Spec-Zone.ru › Octave 9

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.

См. также: 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 не начинает новый блок, и эта строка считается комментарием.

Блоки 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; проверки выполняются поэлементно.

См. также: 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–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

Spec-Zone.ru

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