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"

Отображает предупреждающие сообщения о пропущенных тестах или сбоях 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 не начинает новый блок, и эта строка обрабатывается как комментарий.

END_OF_DOCUMENT_MARKER

Блоки ошибок и предупреждений похожи на блоки тестов, но они проходят только если код генерирует ошибку. Вы можете проверить корректность текста ошибки, используя необязательное регулярное выражение <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, 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

Если вызывается с двумя аргументами, возвращаемое значение будет истинным только если 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/v9.2.0/Test-Functions.html

Spec-Zone.ru

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