Testament
Исходный код РедактироватьTestament — это расширенный автоматический инструмент для запуска юнит-тестов в Nim, используется для разработки самого Nim, предлагает изоляцию процессов для ваших тестов, может генерировать статистику по тестовым случаям, поддерживает несколько целей (C, C++, ObjectiveC, JavaScript и т.д.), имитирует сухие запуски, имеет логирование, может генерировать HTML-отчёты, пропускать тесты из файла и многое другое, поэтому может быть полезно для запуска даже самых сложных тестов.
Расположение файлов тестов
По умолчанию Testament ищет файлы тестов по "./tests/category/*.nim". Вы можете переопределить этот шаблон glob с помощью pattern <glob>. Путь к текущей рабочей директории можно изменить, используя --directory:"folder/subfolder/".
Testament использует компилятор nim на PATH. Вы можете изменить это с помощью --nim:"folder/subfolder/nim". Запуск тестов JavaScript с помощью --targets:"js" требует работающей NodeJS на PATH.
Команды
p|pat|pattern <glob> запустить все тесты, соответствующие заданному шаблону all запустить все тесты внутри категорийных папок c|cat|category <category> запустить все тесты определенной категории r|run <test> запустить отдельный файл теста html сгенерировать testresults.html из базы данных
Параметры
--print--verbose--simulate--failing--targets:"c cpp js objc" run tests for specified targets (default: c)--nim:path--directory:dir--colors:on|off--backendLogging:on|off--megatest:on|off--valgrind:on|off--skipFrom:filefile — по одному тесту в строке, комментарии # игнорируютсяЗапуск одного теста
Это минимальный пример для понимания основ, не очень полезный для производства, но легко понять:
$ mkdir -p tests/category $ echo "assert 42 == 42" > tests/category/test0.nim $ testament run tests/category/test0.nim PASS: tests/category/test0.nim c ( 0.2 sec) $ testament r tests/category/test0 PASS: tests/category/test0.nim C ( 0.2 sec)
Запуск всех тестов из директории
Это запустит все тесты в корневой директории tests/. ПРИМЕЧАНИЕ: эти тесты пропущены testament all.
$ testament pattern "tests/*.nim"
Чтобы искать тесты глубже в директории, используйте
$ testament pattern "tests/**/*.nim" # one level deeper $ testament pattern "tests/**/**/*.nim" # two levels deeper
HTML-отчёты
Генерировать HTML-отчёты testresults.html из юнит-тестов, необходимо запустить хотя бы 1 тест перед генерацией отчёта:
$ testament html
Написание юнит-тестов
Пример "шаблона" для редактирования и написания юнит-теста Testament:
discard """
# What actions to expect completion on.
# Options:
# "compile": expect successful compilation
# "run": expect successful compilation and execution
# "reject": expect failed compilation. The "reject" action can catch
# {.error.} pragmas but not {.fatal.} pragmas because
# {.error.} calls are expected to originate from the test-file,
# and can explicitly be specified using the "file", "line" and
# "column" options.
# {.fatal.} pragmas guarantee that compilation will be aborted.
action: "run"
# For testing failed compilations you can specify the expected origin of the
# compilation error.
# With the "file", "line" and "column" options you can define the file,
# line and column that a compilation-error should have originated from.
# Use only with action: "reject" as it expects a failed compilation.
# Requires errormsg or msg to be defined.
# file: ""
# line: ""
# column: ""
# The exit code that the test is expected to return. Typically, the default
# value of 0 is fine. Note that if the test will be run by valgrind, then
# the test will exit with either a code of 0 on success or 1 on failure.
exitcode: 0
# Provide an `output` string to assert that the test prints to standard out
# exactly the expected string. Provide an `outputsub` string to assert that
# the string given here is a substring of the standard out output of the
# test (the output includes both the compiler and test execution output).
output: ""
outputsub: ""
# Whether to sort the compiler output lines before comparing them to the
# expected output.
sortoutput: true
# Provide a `nimout` string to assert that the compiler during compilation
# prints the defined lines to the standard out.
# The lines must match in order, but there may be more lines that appear
# before, after, or in between them.
nimout: '''
a very long,
multi-line
string'''
# This is the Standard Input the test should take, if any.
input: ""
# Error message the test should print, if any.
errormsg: ""
# Can be run in batch mode, or not.
batchable: true
# Can be run Joined with other tests to run all together, or not.
joinable: true
# On Linux 64-bit machines, whether to use Valgrind to check for bad memory
# accesses or memory leaks. On other architectures, the test will be run
# as-is, without Valgrind.
# Options:
# true: run the test with Valgrind
# false: run the without Valgrind
# "leaks": run the test with Valgrind, but do not check for memory leaks
valgrind: false # Can use Valgrind to check for memory leaks, or not (Linux 64Bit only).
# Checks that the specified piece of C-code is within the generated C-code.
ccodecheck: "'Assert error message'"
# Command the test should use to run. If left out or an empty string is
# provided, the command is taken to be:
# "nim $target --hints:on -d:testing --nimblePath:build/deps/pkgs $options $file"
# Subject to variable interpolation.
cmd: "nim c -r $file"
# Maximum generated temporary intermediate code file size for the test.
maxcodesize: 666
# Timeout seconds to run the test. Fractional values are supported.
timeout: 1.5
# Targets to run the test into (c, cpp, objc, js). Defaults to c.
targets: "c js"
# flags with which to run the test, delimited by `;`
matrix: "; -d:release; -d:caseFoo -d:release"
# Conditions that will skip this test. Use of multiple "disabled" clauses
# is permitted.
disabled: "bsd" # Can disable OSes...
disabled: "win"
disabled: "32bit" # ...or architectures
disabled: "i386"
disabled: "azure" # ...or pipeline runners
disabled: true # ...or can disable the test entirely
"""
assert true
assert 42 == 42, "Assert error message" - Как видите, "Spec" — это просто
discard """ """. - Spec имеет разумные значения по умолчанию, поэтому вам не нужно их все указывать, любая простая проверка (assert) сработает.
- Это не весь спектр возможностей Testament, см. спецификацию Testament на GitHub, см. parseSpec().
- Сам Nim использует Testament, поэтому есть много примеров тестов.
- Имеет некоторую встроенную совместимость с CI, например, Azure Pipelines и т.д.
Встроенные подсказки, предупреждения и ошибки (примечания)
Проверка строки, столбца, типа и сообщения подсказок, предупреждений и ошибок может быть выполнена встроенно, как показано ниже:
{.warning: "warning!!"} #[tt.Warning
^ warning!! [User] ]# Открывающая #[tt. отмечает строку сообщения. ^ отмечает столбец сообщения.
Встроенные сообщения можно комбинировать с nimout при nimoutFull равно false (по умолчанию). Это позволяет проверять ожидаемые сообщения из других модулей:
discard """
nimout: "config.nims(1, 1) Hint: some hint message [User]"
"""
{.warning: "warning!!"} #[tt.Warning
^ warning!! [User] ]# Несколько сообщений для одной строки можно проверить, разделив сообщения точкой с запятой:
discard """
matrix: "--errorMax:0 --styleCheck:error"
"""
proc generic_proc*[T](a_a: int) = #[tt.Error
^ 'generic_proc' should be: 'genericProc'; tt.Error
^ 'a_a' should be: 'aA' ]#
discard Используйте --errorMax:0 в matrix, или cmd: "nim check $file" при проверке нескольких сообщений типа 'Ошибка'.
Интерполяция переменных в сообщениях вывода
errormsg, nimout, и встроенные сообщения поддерживают следующие интерполяции переменных:
-
${/}- разделитель директорий платформы -
$file- имя файла (без директории) теста
Все остальные $ символы необходимо экранировать как $$.
Интерполяция переменных в команде
Параметр cmd поддерживает следующие интерполяции переменных:
-
$target- целевая платформа компиляции, напримерc. -
$options- параметры компилятора. -
$file- путь к файлу теста. -
$filedir- директория файла теста.
discard """ cmd: "nim $target --nimblePath:./nimbleDir/simplePkgs $options $file" """
Все остальные $ символы необходимо экранировать как $$.
Примеры юнит-тестов
Ожидается ошибка:
discard """ errormsg: "undeclared identifier: 'not_defined'" """ assert not_defined == "not_defined", "not_defined is not defined"
Ожидается ошибка, сброшенная из другого файла:
# test.nim
discard """
action: "reject"
errorMsg: "I break"
file: "breakPragma.nim"
"""
import ./breakPragma
proc x() {.justDo.} = discard
# breakPragma.nim
import std/macros
macro justDo*(procDef: typed): untyped =
error("I break")
return procDef Ожидается сгенерированный C-код, содержащий заданный фрагмент кода:
discard """ # Checks that the string "Assert error message" is in the generated # C code. ccodecheck: "'Assert error message'" """ assert 42 == 42, "Assert error message"
Код с ненулевым кодом выхода:
discard """ exitcode: 1 """ quit "Non-Zero exit code", 1
Проверка стандартного вывода:
discard """ output: ''' 0 1 2 3 4 5 ''' """ for i in 0..5: echo i
Тесты JavaScript:
discard """
targets: "js"
"""
when defined(js):
import std/jsconsole
console.log("My Frontend Project") Тесты времени компиляции:
discard """ action: "compile" """ static: assert 9 == 9, "Compile time assert"
Тесты без Spec:
assert 1 == 1
См. также:
© 2006–2024 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/testament.html