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"-
Отображает предупреждающие сообщения о пропущенных тестах или не пройденных xtests во время выполнения теста. Выводит сводку, если все тесты пройдены, или сообщение об ошибке с результатами первого не пройденного теста при возникновении ошибки. Не запускайте тесты, требующие взаимодействия пользователя.
"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 оператор не начинает новый блок, и эта строка обрабатывается как комментарий.
Блоки ошибок и предупреждений аналогичны блокам тестов, но они проходят успешно только если код генерирует ошибку. Вы можете проверить корректность текста ошибки, используя необязательный регулярный выражения <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ложно, тест пропускается. Если<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 ложно (числовой ноль).Любые дополнительные аргументы передаются функции
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, и проверки выполняются на элементной основе.
- : fail (code) ¶
- : fail (code, pattern) ¶
- : fail (code, "warning") ¶
- : 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–2022 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/v7.2.0/Test-Functions.html