Spec-Zone.ru › Octave 5

B.1 Функции тестирования

имя теста
имя теста тихо|нормально|подробно
тест ("имя", "тихо|нормально|подробно", fid)
тест ("имя", "тихо|нормально|подробно", имя_файла)
успех = тест (…)
[n, nmax, nxfail, nbug, nskip, nrtskip, nregression] = тест (…)
[код, idx] = тест ("имя", "grabdemo")
тест ([], "объяснение", fid)
тест ([], "объяснение", имя_файла)

Выполнить встроенные тесты из первого файла в loadpath, соответствующего имя.

test может быть вызван как в командной, так и в функциональной форме. Точное выполнение test определяется комбинацией режима (интерактивный или пакетный), уровня отчетов ("quiet", "normal", "verbose") и наличием файла журнала или переменной для вывода сводки.

По умолчанию, когда test вызывается из командной строки, режим интерактивный. В этом режиме тесты будут выполняться до тех пор, пока не произойдет первая ошибка или не завершатся все тесты успешно. В пакетном режиме все тесты выполняются независимо от любых сбоев, а результаты собираются для отчетности. Тесты, требующие взаимодействия пользователя, например, демонстрационные блоки, никогда не выполняются в пакетном режиме.

Пакетный режим включается либо 1) путем указания файла журнала с помощью третьего аргумента имя_файла или fid, либо 2) путем запроса выходного аргумента, такого как успех, n и т. д.

Необязательный второй аргумент определяет объем генерируемого вывода и какие типы тестов необходимо выполнить. Значение по умолчанию – "normal". Запрос выходного аргумента подавит вывод итогового сообщения и любых промежуточных сообщений об ошибках, если не включен подробный вывод.

"quiet"

Вывести сводку, когда все тесты пройдены, или вывести ошибку с результатами первого не пройденного теста при возникновении сбоя. Не запускать тесты, требующие взаимодействия пользователя.

"normal"

Отображать предупреждения о пропущенных тестах или об ошибках xtests во время выполнения теста. Вывести сводку, когда все тесты пройдены, или вывести ошибку с результатами первого не пройденного теста при возникновении сбоя. Не запускать тесты, требующие взаимодействия пользователя.

"verbose"

Отображать тесты перед выполнением. Выводить все сообщения об ошибках. В интерактивном режиме запускать все тесты, включая те, которые требуют взаимодействия пользователя.

Необязательный третий входной аргумент указывает файл журнала, в который должны быть записаны результаты тестов. Файл журнала может быть строкой символов (имя_файла) или идентификатором открытого дескриптора файла (fid). Чтобы включить пакетную обработку, но все равно выводить результаты на экран, используйте stdout для fid.

При вызове с единственным выходным аргументом успех, test возвращает true, если все тесты были успешны. При вызове с более чем одним выходным аргументом возвращается количество успешных тестов (n), общее количество тестов в файле (nmax), количество сбоев xtests (nxfail), количество тестов, завершившихся неудачей из-за известных ошибок (nbug), количество пропущенных тестов из-за отсутствующих функций (nskip), количество пропущенных тестов из-за условий во время выполнения (nrtskip) и количество регрессий (nregression).

Пример

test sind
⇒
PASSES 5 out of 5 tests

[n, nmax] = test ("sind")
⇒
n =  5
nmax =  5

Дополнительные синтаксические варианты вызова

Если второй аргумент — строка "grabdemo", содержимое любых встроенных демонстрационных блоков извлекается, но не выполняется. Текст всех блоков кода конкатенируется и возвращается как код, а idx — вектор позиций концов каждого демонстрационного блока. Для более простого извлечения демонстрационных блоков из файлов см. пример.

Если второй аргумент — "explain", то имя игнорируется, и объяснение используемых маркеров строк в test отчетах записывается в файл, указанный имя_файла или fid.

См. также: assert, fail, demo, пример, error.

test сканирует указанный файл скрипта, ища строки, начинающиеся с идентификатора ‘%!’. Префикс удаляется, а остальная часть строки обрабатывается интерпретатором Octave. Если код генерирует ошибку, то тест считается проваленным.

Поскольку eval() остановится на первой встреченной ошибке, необходимо разделить тесты на блоки, при этом всё, что находится в отдельном блоке, оценивается отдельно. Блоки вводятся с помощью допустимых ключевых слов, таких как test, function, или assert непосредственно после ‘%!’. Блок определяется отступами, как в Python. Строки, начинающиеся с ‘%!<пробелы>’, являются частью предыдущего блока.

Например:

%!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 заканчивает этот блок. Обратите внимание, что до начала нового блока строки, начинающиеся с ‘%!<пробел>’, будут отбрасываться как комментарии. Следующее почти идентично вышеприведённому примеру, но ничего не делает.

%!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 — целое число номера ошибки. Цель — обеспечить более ясное описание известных проблем.

%!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, test, error, isequal.

fail (code)
fail (code, pattern)
fail (code, "warning")
fail (code, "warning", pattern)

Возвращает true, если code завершается с сообщением об ошибке, соответствующим pattern, в противном случае выводит ошибку.

code должен иметь вид строки, передаваемой интерпретатору Octave через функцию evalin, т.е. (скобочная) строковая константа или строковая переменная.

Обратите внимание, что если code выполняется успешно, а не завершается ошибкой, отображаемая ошибка:

expected error <.> but got none

Если вызывается с двумя аргументами, возвращаемое значение будет истинным только в том случае, если code завершается с сообщением об ошибке, содержащим pattern (регистрозависимый). Если код завершается с другой ошибкой, чем указанная в pattern, то выводится сообщение:

expected <pattern>
          but got <text of actual error>

Фигурные скобки не являются частью вывода.

При вызове с опцией "warning" fail выведет ошибку, если при выполнении кода не возникает предупреждение.

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

© 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/v5.2.0/Test-Functions.html

Spec-Zone.ru

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