Spec-Zone.ru › Octave 8

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.

См. также: assert, fail, demo, example, error.

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.

Обратите внимание, что observed и expected могут быть скалярами, векторами, матрицами, строками, массивами ячеек или структурами.

assert (observed, expected, tol)

Вызывает ошибку, если observed не совпадает с expected, но сравнение для числовых данных использует допуск tol.

Если tol положительный, это абсолютный допуск, который вызовет ошибку, если abs (observed - expected) > abs (tol).

Если tol отрицательный, это относительный допуск, который вызовет ошибку, если abs (observed - expected) > abs (tol * expected).

Если expected равно нулю, tol всегда будет интерпретироваться как абсолютный допуск.

Если tol не является скаляром, его размерности должны совпадать с размерностями observed и expected, и проверки выполняются на основе элементов.

См. также: fail, test, error, isequal.

: 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 вызовет ошибку, если выполнение кода не приводит к предупреждению.

См. также: assert, error.

© 1996–2023 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/v8.1.0/Test-Functions.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API