B.1 Функции тестирования
-
: test
name -
: test
name quiet|normal|verbose -
: test
("name", "quiet|normal|verbose", fid) -
: test
("name", "quiet|normal|verbose", fname) -
:
success =test(…) -
:
[n, nmax, nxfail, nbug, nskip, nrtskip, nregression] =test(…) -
:
[code, idx] =test("name", "grabdemo") -
: test
([], "explain", fid) -
: test
([], "explain", fname) -
Выполняет встроенные самотесты из первого файла с именем name, найденного в пути загрузки.
testможно вызывать как в командной, так и в функциональной форме. Точное поведение test определяется сочетанием режима (интерактивного или пакетного), уровня отчётности ("quiet","normal","verbose") и наличия файла журнала или выходной переменной для сводки.По умолчанию при вызове
testиз командной строки используется интерактивный режим. В этом режиме тесты выполняются до первой ошибки или до успешного завершения всех тестов. В пакетном режиме выполняются все тесты независимо от сбоев, а результаты собираются для формирования отчёта. Тесты, требующие взаимодействия с пользователем, то есть демонстрационные блоки, в пакетном режиме не выполняются.Пакетный режим включается одним из двух способов: 1) указанием файла журнала с помощью третьего аргумента fname или fid; либо 2) запросом выходного аргумента, например success, n и т. д.
Необязательный второй аргумент задаёт объём выводимых данных и типы выполняемых тестов. Значение по умолчанию —
"normal". Запрос выходного аргумента подавляет вывод итоговой сводки и всех промежуточных предупреждений, если не включён подробный режим отчётности."quiet"-
Выводит сводку, если все тесты пройдены, или сообщение об ошибке с результатами первого неудачного теста при сбое. Не выполняет тесты, требующие взаимодействия с пользователем.
"normal"-
Во время выполнения тестов выводит предупреждения о пропущенных тестах или неудачных xtest. Выводит сводку, если все тесты пройдены, или сообщение об ошибке с результатами первого неудачного теста при сбое. Не выполняет тесты, требующие взаимодействия с пользователем.
"verbose"Отображает тесты перед выполнением. Выводит все предупреждения. В интерактивном режиме выполняет все тесты, включая требующие взаимодействия с пользователем.
Необязательный третий входной аргумент указывает файл журнала, в который следует записать результаты тестов. Файлом журнала может быть символьная строка (fname) или идентификатор открытого файлового дескриптора (fid). Чтобы включить пакетную обработку и при этом выводить результаты на экран, используйте
stdoutдля fid.При вызове только с одним выходным аргументом success
testвозвращает true, если все тесты пройдены успешно. Если функция вызвана с несколькими выходными аргументами, возвращаются число успешно пройденных тестов (n), общее число тестов в файле (nmax), число неудачных xtest (nxfail), число тестов, завершившихся неудачей из-за известных ошибок (nbug), число тестов, пропущенных из-за отсутствующих функций (nskip), число тестов, пропущенных из-за условий времени выполнения (nrtskip), и число регрессий (nregression).Пример
test sind ⇒ PASSES 5 out of 5 tests [n, nmax] = test ("sind") ⇒ n = 5 nmax = 5Дополнительные синтаксисы вызова
Если второй аргумент — строка
"grabdemo", содержимое всех встроенных демонстрационных блоков извлекается, но не выполняется. Текст всех блоков кода объединяется и возвращается как code, а idx представляет собой вектор позиций концов каждого демонстрационного блока. Для более удобного извлечения демонстрационных блоков из файлов см.example.Если второй аргумент —
"explain", аргумент name игнорируется, а объяснение маркеров строк, используемых в отчётахtest, записывается в файл, указанный аргументом fname или fid.
test просматривает указанный файл скрипта в поисках строк, начинающихся с идентификатора «%!». Префикс удаляется, а оставшаяся часть строки обрабатывается интерпретатором Octave. Если при выполнении кода возникает ошибка, тест считается не пройденным.
Поскольку eval() останавливается при первой обнаруженной ошибке, тесты необходимо разделять на блоки; содержимое каждого отдельного блока проверяется независимо. Блоки начинаются с допустимых ключевых слов, например test, function или assert, которые непосредственно следуют за «%!». Блок определяется отступами, как в Python. Строки, начинающиеся с «%!<whitespace>», относятся к предыдущему блоку.
Например:
%!test error ("this test fails!")
%!test "test doesn't fail. it doesn't generate an error" При сбое теста вы увидите что-то подобное:
***** test error ("this test fails!")
!!!!! test failed
this test fails! Как правило, чтобы проверить, работает ли что-либо, нужно утверждать, что результат имеет правильное значение. Реальный тест может выглядеть так:
%!test
%! a = [1, 2, 3; 4, 5, 6]; B = [1; 2];
%! expect = [ a ; 2*a ];
%! get = kron (b, a);
%! if (any (size (expect) != size (get)))
%! error ("wrong size: expected %d,%d but got %d,%d",
%! size (expect), size (get));
%! elseif (any (any (expect != get)))
%! error ("didn't get what was expected.");
%! endif Чтобы упростить этот процесс, используйте функцию assert. Например, с помощью assert предыдущий тест можно свести к следующему:
%!test %! a = [1, 2, 3; 4, 5, 6]; b = [1; 2]; %! assert (kron (b, a), [ a; 2*a ]);
assert принимает допуск, позволяющий сравнивать результаты по абсолютному или относительному значению. Например, все приведённые ниже варианты завершаются успешно:
%!test assert (1+eps, 1, 2*eps) # absolute error %!test assert (100+100*eps, 100, -2*eps) # relative error
Можно также выполнить сравнение самостоятельно, но поручить assert генерировать ошибку:
%!test assert (isempty ([])) %!test assert ([1, 2; 3, 4] > 0)
Поскольку assert так часто используется отдельно в блоке теста, для него предусмотрена сокращённая форма:
%!assert (...)
которая эквивалентна следующей:
%!test assert (...)
Иногда блок тестов зависит от наличия в Octave необязательной функциональности. Перед выполнением таких блоков необходимо проверить, доступна ли требуемая функциональность. Блок %!testif HAVE_XXX выполняется только в том случае, если Octave был собран с функциональностью «HAVE_XXX». Например, разложение разреженного значения на сингулярные компоненты, svds(), требует библиотеки ARPACK. Все тесты для svds начинаются с
%!testif HAVE_ARPACK
В файле config.h или __octave_config_info__ ("build_features") можно посмотреть некоторые возможные значения для проверки.
Иногда во время разработки тест должен работать, но известно, что он завершается неудачей. Тест всё равно следует оставить, поскольку после завершения работы над кодом он должен пройти, однако исправить проблему немедленно может быть невозможно. Чтобы избежать ненужных сообщений об ошибках для таких известных сбоев, пометьте блок с помощью xtest вместо test:
%!xtest assert (1==0)
%!xtest fail ("success=1", "error") В этом случае тест будет выполнен, а любой сбой будет зарегистрирован. Однако тестирование не прерывается, и последующие блоки обрабатываются обычным образом. Ещё одно применение xtest — статистические тесты, которые обычно проходят, но, как известно, иногда завершаются неудачей.
Каждый блок выполняется в собственной функциональной области видимости, поэтому переменные, определённые в одном блоке, автоматически не доступны другим блокам. Если переменные нужно использовать совместно, их необходимо объявить как shared до использования. Например, следующий код объявляет переменную a, задаёт её начальное значение (по умолчанию оно пустое), а затем использует её в нескольких последующих тестах.
%!shared a %! a = [1, 2, 3; 4, 5, 6]; %!assert (kron ([1; 2], a), [ a; 2*a ]) %!assert (kron ([1, 2], a), [ a, 2*a ]) %!assert (kron ([1,2; 3,4], a), [ a,2*a; 3*a,4*a ])
Можно совместно использовать несколько переменных одновременно:
%!shared a, b
Изменения общих переменных сохраняются от одного теста к другому только в случае успешного прохождения теста. Поэтому, если один тест изменяет общую переменную, последующие тесты не могут знать, какое значение этой переменной ожидать, поскольку результат предыдущих тестов неизвестен. По этой причине не рекомендуется изменять общие переменные в тестах.
Также можно совместно использовать тестовые функции:
%!function a = fn (b) %! a = 2*b; %!endfunction %!assert (fn(2), 4)
Обратите внимание, что при объявлении нового общего блока все предыдущие переменные и значения теряются.
Помните, что %!function начинает новый блок, а %!endfunction завершает его. Обратите внимание: пока не начат новый блок, строки, начинающиеся с «%!<space>», отбрасываются как комментарии. Следующий пример почти идентичен предыдущему, но ничего не делает.
%!function a = fn (b) %! a = 2*b; %!endfunction %! assert (fn(2), 4)
Поскольку после «%!» стоит пробел, инструкция assert не начинает новый блок, и эта строка считается комментарием.
Блоки error и warning похожи на блоки тестов, но считаются пройденными только в том случае, если код генерирует ошибку. Правильность текста ошибки можно проверить с помощью необязательного регулярного выражения <pattern>. Например:
%!error <passes!> error ("this test passes!") Если код не генерирует ошибку, тест считается не пройденным. Например:
%!error "this is an error because it succeeds."
выводит
***** error "this is an error because it succeeds." !!!!! test failed: no error
Важно по возможности автоматизировать тесты, однако для некоторых из них требуется взаимодействие с пользователем. Их можно выделить в демонстрационные блоки, которые в пакетном режиме выполняются только при вызове с demo или параметром verbose функции test. Перед выполнением код отображается. Например:
%!demo %! t = [0:0.01:2*pi]; x = sin (t); %! plot (t, x); %! # you should now see a sine wave in your figure window
выводит
funcname example 1: t = [0:0.01:2*pi]; x = sin (t); plot (t, x); # you should now see a sine wave in your figure window Press <enter> to continue:
Обратите внимание, что демонстрационные блоки не могут использовать общие переменные. Это позволяет выполнять их отдельно, игнорируя все остальные тесты.
Чтобы временно отключить блок теста, укажите # вместо типа блока. Это создаёт блок комментария, который выводится в файл журнала, но не выполняется. Например:
%!#demo %! t = [0:0.01:2*pi]; x = sin (t); %! plot (t, x); %! # you should now see a sine wave in your figure window
Следующий простой фрагмент кода показывает, как использовать fail, assert, error и xtest:
function output = must_be_zero (input)
if (input != 0)
error ("Nonzero input!")
endif
output = input;
endfunction
%!fail ("must_be_zero (1)")
%!assert (must_be_zero (0), 0)
%!error <Nonzero> must_be_zero (1)
%!xtest error ("This code generates an error") Если поместить этот код в файл must_be_zero.m и запустить тест, результат будет таким:
test must_be_zero verbose
⇒
>>>>> /path/to/must_be_zero.m
***** fail ("must_be_zero (1)")
***** assert (must_be_zero (0), 0)
***** error <Nonzero> must_be_zero (1)
***** xtest error ("This code generates an error")
!!!!! known failure
This code generates an error
PASSES 3 out of 4 tests (1 expected failure) Сводка по типам блоков:
%!test%!test <MESSAGE>-
Проверяет правильность всего блока. Если присутствует
<MESSAGE>, блок теста обрабатывается так же, какxtest. %!testif HAVE_XXX%!testif HAVE_XXX, HAVE_YYY, …%!testif HAVE_XXX, HAVE_YYY …; RUNTIME_COND%!testif … <MESSAGE>-
Проверяет блок, только если Octave был собран с функциональностью
HAVE_XXX.RUNTIME_COND— необязательное выражение, которое вычисляется при выполнении теста для проверки выполнения некоторого условия. ЕслиRUNTIME_CONDимеет значение false, тест пропускается. Если присутствует<MESSAGE>, блок теста обрабатывается так же, какxtest. %!xtest%!xtest <MESSAGE>-
Проверяет блок, сообщает о сбое теста, но не прерывает тестирование. Если присутствует
<MESSAGE>, при сбое теста выводится текст сообщения, например:!!!!! known bug: MESSAGE
Если сообщение является целым числом, оно интерпретируется как идентификатор ошибки в системе отслеживания ошибок Octave и выводится в следующем виде:
!!!!! known bug: https://octave.org/testfailure/?BUG-ID
где BUG-ID — целочисленный номер ошибки. Это позволяет яснее документировать известные проблемы.
Если
MESSAGE— целое число, перед которым стоит звёздочка (например,*12345), оно интерпретируется как идентификатор закрытого сообщения об ошибке. Обычно это означает, что проблема, проверяемая данным тестом, была устранена. Если такие тесты завершаются неудачей, функцияtestсообщает о них как о регрессиях:!!!!! regression: https://octave.org/testfailure/?BUG-ID
%!error%!error <MESSAGE>%!warning%!warning <MESSAGE>-
Проверяет правильность сообщения об ошибке или предупреждения. Если задано
<MESSAGE>, оно интерпретируется как шаблон регулярного выражения, которому должно соответствовать сообщение об ошибке или предупреждение. %!demo-
Демонстрация выполняется только в интерактивном режиме.
%!#-
Комментарий. Игнорирует всё содержимое блока.
%!shared x,y,z-
Объявляет переменные для использования в нескольких тестах.
%!function-
Определяет функцию для использования в нескольких тестах.
%!endfunction-
Завершает определение функции.
%!assert (x, y, tol)%!assert <MESSAGE> (x, y, tol)%!fail (CODE, PATTERN)%!fail <MESSAGE> (CODE, PATTERN)-
Сокращённая форма для
%!test assert (x, y, tol)или%!test fail (CODE, PATTERN). Если присутствует<MESSAGE>, блок теста обрабатывается так же, какxtest.
При написании тестов в Octave принято не ставить точку с запятой в конце строк, начинающихся с типа блока. Однако любой код внутри блока является обычным кодом Octave и обычно завершается точкой с запятой. Например:
## bare block instantiation %!assert (sin (0), 0)
но
## test block with normal Octave code %!test %! assert (sin (0), 0);
Также можно создавать тестовые скрипты для встроенных функций и собственных функций на C++. Для этого поместите файл с именем функции (без расширения .m) в каталог из пути загрузки — тогда функция test обнаружит его. Кроме того, тесты можно встроить непосредственно в код C++:
/*
%!test disp ("this is a test")
*/ или
#if 0
%!test disp ("this is a test")
#endif Однако в этом случае исходный код должен находиться в пути загрузки, а пользователь должен не забыть ввести test ("funcname.cc").
-
: assert
(cond) -
: assert
(cond, errmsg) -
: assert
(cond, errmsg, …) -
: assert
(cond, msg_id, errmsg, …) -
: assert
(observed, expected) -
: assert
(observed, expected, tol) -
Выдаёт ошибку, если указанное условие не выполнено.
assertможно вызывать тремя различными способами.assert (cond)assert (cond, errmsg)assert (cond, errmsg, …)assert (cond, msg_id, errmsg, …)-
При вызове с одним аргументом cond функция
assertвыдаёт ошибку, если cond имеет значение false (числовой ноль).Все дополнительные аргументы передаются функции
errorдля обработки. assert (observed, expected)-
Выдаёт ошибку, если наблюдаемое значение не совпадает с ожидаемым.
Обратите внимание, что observed и expected могут быть скалярами, векторами, матрицами, строками, массивами ячеек или структурами.
assert (observed, expected, tol)-
Выдаёт ошибку, если наблюдаемое значение не совпадает с ожидаемым; при этом для числовых данных сравнение на равенство выполняется с допуском tol.
Если tol положителен, он задаёт абсолютный допуск, при превышении которого будет выдана ошибка:
abs (observed - expected) > abs (tol).Если tol отрицателен, он задаёт относительный допуск, при превышении которого будет выдана ошибка:
abs (observed - expected) > abs (tol * expected).Если expected равен нулю, tol всегда интерпретируется как абсолютный допуск.
Если tol не является скаляром, его размерности должны совпадать с размерностями observed и expected; проверки выполняются поэлементно.
-
:
status =fail(code) -
:
status =fail(code, pattern) -
:
status =fail(code, "warning") -
:
status =fail(code, "warning", pattern) -
Возвращает true, если code завершается ошибкой, сообщение которой соответствует шаблону pattern; в противном случае выдаёт ошибку.
code должен быть строкой, передаваемой интерпретатору Octave через функцию
evalin, то есть (заключённой в кавычки) строковой константой или строковой переменной.Обратите внимание: если code выполняется успешно, а не завершается ошибкой, выводится следующее сообщение:
expected error <.> but got none
При вызове с двумя аргументами функция возвращает true, только если code завершается ошибкой, сообщение которой содержит pattern (с учётом регистра). Если код завершается другой ошибкой, отличной от указанной в pattern, выводится сообщение:
expected <pattern> but got <text of actual error>Угловые скобки не входят в вывод.
При вызове с параметром
"warning"функцияfailвыдаёт ошибку, если выполнение кода не приводит к появлению предупреждения.
© 1996–2026 The Octave Project Developers
Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.
Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions.
https://docs.octave.org/v9.4.0/Test-Functions.html