unittest
Примечание: Вместо unittest.nim, пожалуйста, рассмотрите использование инструмента testament, который предлагает изоляцию процессов для ваших тестов. Также when isMainModule: doAssert conditionHere обычно является гораздо более простым решением для целей тестирования.
Этот модуль реализует шаблон, чтобы упростить создание юнит-тестов.
Статус и имя теста выводятся после любого вывода или отладки.
Тесты могут быть вложенными, однако сбой вложенного теста не пометит родительский тест как не пройденный. Настройка и завершение работы наследуются. Настройка может быть переопределена локально.
Скомпилированные файлы тестов, а также nim c -r <testfile.nim> завершаются со значением 0 для успеха (нет не пройденных тестов) или 1 для сбоя.
Запуск одного теста
Укажите имя теста в качестве аргумента командной строки.
nim c -r test "my test name" "another test"
Можно использовать несколько аргументов.
Запуск одной тестовой группы
Укажите имя группы, ограниченное "::".
nim c -r test "my test name::"
Выбор тестов по шаблону
Один "*" может быть использован для подстановки.
Ограничьте конец имени группы с помощью "::".
Выполняются тесты, соответствующие любому из аргументов.
nim c -r test fast_suite::mytest1 fast_suite::mytest2 nim c -r test "fast_suite::mytest*" nim c -r test "auth*::" "crypto::hashing*" # Run suites starting with 'bug #' and standalone tests starting with '#' nim c -r test 'bug #*::' '::#*'
Примеры
suite "description for this stuff":
echo "suite setup: run once before the tests"
setup:
echo "run before each test"
teardown:
echo "run after each test"
test "essential truths":
# give up and stop if this fails
require(true)
test "slightly less obvious stuff":
# print a nasty message and move on, skipping
# the remainder of this block
check(1 != 1)
check("asd"[2] == 'd')
test "out of bounds error is thrown on bad access":
let v = @[1, 2, 3] # you can do initialization here
expect(IndexDefect):
discard v[4]
echo "suite teardown: run once after the tests" Ограничения/Ошибки
Поскольку check будет переписывать некоторые выражения для поддержки контрольных точек (а именно, присваивать выражения переменным), некоторые преобразования типов не поддерживаются. Например, check 4.0 == 2 + 2 не будет работать. Но doAssert 4.0 == 2 + 2 работает. Убедитесь, что обе стороны оператора (такие как ==, >= и так далее) имеют одинаковый тип.
Импорты
- since, exitprocs, macros, strutils, streams, times, sets, sequtils, os, terminal
Типы
TestStatus = enum OK, FAILED, SKIPPED
- Статус теста при его завершении. Исходный код Редактировать
OutputLevel = enum PRINT_ALL, ## Print as much as possible. PRINT_FAILURES, ## Print only the failed tests. PRINT_NONE ## Print nothing.
- Уровень детализации вывода тестов. Исходный код Редактировать
TestResult = object suiteName*: string ## Name of the test suite that contains this test case. ## Can be ``nil`` if the test case is not in a suite. testName*: string ## Name of the test case status*: TestStatus- Исходный код Редактировать
OutputFormatter = ref object of RootObj
- Исходный код Редактировать
ConsoleOutputFormatter = ref object of OutputFormatter colorOutput: bool ## Have test results printed in color. ## Default is true for the non-js target, ## for which ``stdout`` is a tty. ## Setting the environment variable ## ``NIMTEST_COLOR`` to ``always`` or ## ``never`` changes the default for the ## non-js target to true or false respectively. ## The deprecated environment variable ## ``NIMTEST_NO_COLOR``, when set, ## changes the default to true, if ## ``NIMTEST_COLOR`` is undefined. outputLevel: OutputLevel ## Set the verbosity of test results. ## Default is ``PRINT_ALL``, unless ## the ``NIMTEST_OUTPUT_LVL`` environment ## variable is set for the non-js target. isInSuite: bool isInTest: bool- Исходный код Редактировать
JUnitOutputFormatter = ref object of OutputFormatter stream: Stream testErrors: seq[string] testStartTime: float testStackTrace: string
- Исходный код Редактировать
Переменные
abortOnError: bool
- Устанавливается в значение true, чтобы немедленно завершить работу при ошибке. По умолчанию значение false, если не установлена переменная окружения
NIMTEST_ABORT_ON_ERRORдля целевой платформы, отличной от js. Исходный код Редактировать
Процедуры
proc addOutputFormatter(formatter: OutputFormatter) {...}{.raises: [], tags: [].}- Исходный код Редактировать
proc delOutputFormatter(formatter: OutputFormatter) {...}{.raises: [], tags: [].}- Исходный код Редактировать
proc resetOutputFormatters() {...}{.raises: [], tags: [].}- Исходный код Редактировать
proc newConsoleOutputFormatter(outputLevel: OutputLevel = OutputLevel.PRINT_ALL; colorOutput = true): ConsoleOutputFormatter {...}{. raises: [], tags: [].}- Исходный код Редактировать
proc defaultConsoleFormatter(): ConsoleOutputFormatter {...}{.raises: [], tags: [ReadEnvEffect].}- Исходный код Редактировать
proc newJUnitOutputFormatter(stream: Stream): JUnitOutputFormatter {...}{. raises: [IOError, OSError], tags: [WriteIOEffect].}- Создаёт форматировщик, который записывает отчёт в указанный поток в формате JUnit. Поток
streamНЕ закрывается автоматически после завершения тестов, так как форматировщик не может узнать, когда завершаются все тесты. Вы должны вызвать formatter.close() для завершения отчёта. Исходный код Редактировать proc close(formatter: JUnitOutputFormatter) {...}{. raises: [IOError, OSError, Exception], tags: [WriteIOEffect].}- Завершает отчёт и закрывает базовый поток. Исходный код Редактировать
proc checkpoint(msg: string) {...}{.raises: [], tags: [].}- Устанавливает контрольную точку, идентифицированную как
msg. При ошибке теста выводятся все встреченные до этого контрольные точки. Пример:checkpoint("Checkpoint A") check((42, "the Answer to life and everything") == (1, "a")) checkpoint("Checkpoint B")выводит "Checkpoint A", как только произойдёт сбой.
Исходный код Редактировать proc disableParamFiltering() {...}{.raises: [], tags: [].}- отключает фильтрацию тестов с параметрами командной строки Исходный код Редактировать
Методы
method suiteStarted(formatter: OutputFormatter; suiteName: string) {...}{.base, gcsafe, raises: [], tags: [].}- Исходный код Редактировать
method testStarted(formatter: OutputFormatter; testName: string) {...}{.base, gcsafe, raises: [], tags: [].}- Исходный код Редактировать
method failureOccurred(formatter: OutputFormatter; checkpoints: seq[string]; stackTrace: string) {...}{.base, gcsafe, raises: [], tags: [].}-
stackTraceпредоставляется только в случае, если сбой произошёл из-за исключения.checkpointsникогда неnil. Исходный код Редактировать method testEnded(formatter: OutputFormatter; testResult: TestResult) {...}{.base, gcsafe, raises: [], tags: [].}- Исходный код Редактировать
method suiteEnded(formatter: OutputFormatter) {...}{.base, gcsafe, raises: [], tags: [].}- Исходный код Редактировать
method suiteStarted(formatter: ConsoleOutputFormatter; suiteName: string) {...}{. raises: [IOError, ValueError], tags: [WriteIOEffect].}- Исходный код Редактировать
method testStarted(formatter: ConsoleOutputFormatter; testName: string) {...}{. raises: [], tags: [].}- Исходный код Редактировать
method failureOccurred(formatter: ConsoleOutputFormatter; checkpoints: seq[string]; stackTrace: string) {...}{. raises: [], tags: [].}- Исходный код Редактировать
method testEnded(formatter: ConsoleOutputFormatter; testResult: TestResult) {...}{. raises: [IOError, ValueError], tags: [WriteIOEffect].}- Исходный код Редактировать
method suiteEnded(formatter: ConsoleOutputFormatter) {...}{.raises: [], tags: [].}- Исходный код Редактировать
method suiteStarted(formatter: JUnitOutputFormatter; suiteName: string) {...}{. raises: [IOError, OSError, ValueError], tags: [WriteIOEffect].}- Исходный код Редактировать
method testStarted(formatter: JUnitOutputFormatter; testName: string) {...}{. raises: [], tags: [TimeEffect].}- Исходный код Редактировать
method failureOccurred(formatter: JUnitOutputFormatter; checkpoints: seq[string]; stackTrace: string) {...}{. raises: [], tags: [].}-
stackTraceпредоставляется только в случае, если сбой произошёл из-за исключения.checkpointsникогда неnil. Исходный код Редактировать method testEnded(formatter: JUnitOutputFormatter; testResult: TestResult) {...}{. raises: [IOError, OSError, ValueError], tags: [TimeEffect, WriteIOEffect].}- Исходный код Редактировать
method suiteEnded(formatter: JUnitOutputFormatter) {...}{.raises: [IOError, OSError], tags: [WriteIOEffect].}- Исходный код Редактировать
Макросы
macro check(conditions: untyped): untyped
- Проверить, истинно ли утверждение или список утверждений. При ошибке выводится полезное сообщение об ошибке и контрольные точки (если
outputLevelнеPRINT_NONE). Пример:import strutils check("AKB48".toLowerAscii() == "akb48") let teams = {'A', 'K', 'B', '4', '8'} check: "AKB48".toLowerAscii() == "akb48" 'C' in teamsИсходный код Изменить macro expect(exceptions: varargs[typed]; body: untyped): untyped
- Проверить, вызывает ли
bodyисключение, указанное в переданномexceptions. Тест проходит, если поднятое исключение является частью допустимых исключений. В противном случае тест завершается неудачно. Пример:import math, random proc defectiveRobot() = randomize() case rand(1..4) of 1: raise newException(OSError, "CANNOT COMPUTE!") of 2: discard parseInt("Hello World!") of 3: raise newException(IOError, "I can't do that Dave.") else: assert 2 + 2 == 5 expect IOError, OSError, ValueError, AssertionDefect: defectiveRobot()Исходный код Изменить
Шаблоны
template suite(name, body) {...}{.dirty.}-
Объявить набор тестов, идентифицированный по
nameс необязательной секциейsetupи/илиteardown.Набор тестов — это ряд одного или более связанных тестов, использующих общую фикстуру (
setup,teardown). Фикстура выполняется для КАЖДОГО теста.suite "test suite for addition": setup: let result = 4 test "2 + 2 = 4": check(2+2 == result) test "(2 + -2) != 4": check(2 + -2 != result) # No teardown neededНабор выполнит отдельные тестовые случаи в том порядке, в котором они были перечислены. При стандартных глобальных настройках приведенный выше код выводит:
[Suite] test suite for addition [OK] 2 + 2 = 4 [OK] (2 + -2) != 4
Исходный код Изменить template test(name, body) {...}{.dirty.}- Определить отдельный тестовый случай, идентифицированный по
name.test "roses are red": let roses = "red" check(roses == "red")
Приведенный выше код выводит:
[OK] roses are red
Исходный код Изменить template fail()
- Вывести обнаруженные контрольные точки и выйти, если
abortOnErrorистинно. В противном случае стереть контрольные точки и указать, что тест завершился неудачно (изменить код выхода и статус теста). Этот шаблон полезен для отладки, но в основном используется внутри. Пример:checkpoint("Checkpoint A") complicatedProcInThread() fail()выводит "Контрольная точка A" перед завершением.
Исходный код Изменить template skip()
- Отметить тест как пропущенный. Должен использоваться в случаях, когда выполнение теста невозможно по причинам, зависящим от внешней среды, определённых условий работы приложения или конфигураций. Код теста всё равно выполняется.
if not isGLContextCreated(): skip()
Исходный код Изменить template require(conditions: untyped)
- Аналогично
check, за исключением того, что любой неудачный тест приводит к немедленному завершению программы. Любые завершающие действия не выполняются, и вывод неудачного теста не генерируется. Исходный код Изменить
© 2006–2021 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/unittest.html