Запуск тестов¶
Стабильность: 2 – Стабильная
АПИ является удовлетворительным. Совместимость с NPM имеет высший приоритет и не будет нарушена кроме случаев явной необходимости.
Модуль node:test предназначен для написания и запуска JavaScript-тестов. Подключение:
1 | |
1 | |
Модуль доступен только в схеме node:.
Тест из модуля test — это одна функция, которая обрабатывается одним из трёх способов:
- Синхронная функция: провал при выброшенном исключении, успех иначе.
- Функция, возвращающая
Promise: провал при отклонении промиса, успех при выполнении. - Функция с колбэком: провал, если первый аргумент колбэка истинный; успех, если первый аргумент ложный. Если функция и принимает колбэк, и возвращает
Promise, тест считается проваленным.
Ниже пример использования модуля test.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | |
Если какой-либо тест провален, код выхода процесса устанавливается в 1.
Подтесты¶
Метод test() контекста теста позволяет создавать подтесты и выстраивать иерархию вложенных тестов внутри более крупного. Поведение совпадает с функцией test() верхнего уровня. Ниже — пример верхнего теста с двумя подтестами.
1 2 3 4 5 6 7 8 9 | |
Примечание: хуки
beforeEachиafterEachвызываются между запусками подтестов.
Здесь await гарантирует завершение обоих подтестов: родительский тест сам по себе не ждёт подтесты (в отличие от тестов внутри suite). Незавершённые подтесты при завершении родителя отменяются и считаются провалом; провал подтеста ведёт к провалу родителя.
Повторный запуск проваленных тестов¶
Раннер может сохранять состояние прогона в файл и затем перезапускать только проваленные тесты без полного прогона. Укажите путь к файлу состояния ключом --test-rerun-failures; если файла нет, он будет создан.
Файл состояния — JSON с массивом попыток запуска. Каждая попытка — объект, сопоставляющий успешно прошедшие тесты с номером попытки, на которой они впервые прошли. Ключ — путь к файлу теста с номером строки и столбца определения теста. Если один и тот же тест в одной позиции запускается несколько раз (например в цикле), к ключу добавляется счётчик. Изменение порядка выполнения или места теста может сбить соответствие; --test-rerun-failures имеет смысл при детерминированном порядке тестов.
Пример файла состояния:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
В примере две попытки и два теста в test.js: первый прошёл с первой попытки, второй — со второй.
С опцией --test-rerun-failures выполняются только тесты, которые ещё ни разу не прошли успешно.
1 | |
Псевдонимы describe() и it()¶
Наборы и тесты можно оформлять через describe() и it(): describe() это псевдоним suite(), it() — псевдоним test().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
describe и it импортируются из модуля node:test.
1 | |
1 | |
Пропуск тестов¶
Отдельные тесты можно пропустить, передав опцию skip в вызов test, либо вызвав метод контекста skip(), как в примере ниже.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | |
Тесты TODO¶
Отдельные тесты можно пометить как нестабильные или незавершённые, передав опцию todo в вызов test или вызвав метод контекста todo(), как в примере ниже. Такие тесты означают отложенную реализацию или известную ошибку, которую нужно исправить. Тесты TODO выполняются, но не считаются провалом и не влияют на код выхода процесса. Если тест помечен и как TODO, и как пропущенный, опция TODO игнорируется.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | |
Ожидание падения тестов¶
Инвертирует отчёт об успехе/провале для отдельного теста или набора: помеченный тест считается пройденным только если выбрасывает исключение; если исключения нет — провал.
В примерах ниже doTheThing() не возвращает true, но тесты помечены expectFailure, поэтому проходят.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
Если expectFailure имеет тип RegExp | Function | Object | Error, тест проходит только при выбросе совпадающего значения. См. assert.throws про обработку типов.
Следующие тесты падают несмотря на expectFailure, потому что ошибка не совпадает с ожидаемой.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
Чтобы задать и причину, и шаблон ошибки для expectFailure, используйте { label, match }.
1 2 3 4 5 6 7 8 9 10 11 12 | |
skip и/или todo несовместимы с expectFailure; при совместном указании приоритет у skip и todo (skip сильнее остальных, todo сильнее expectFailure).
Эти тесты будут пропущены (не выполнятся):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
Эти тесты будут помечены как «todo» (ошибки подавляются):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
Тесты only¶
Если Node.js запущен с --test-only или отключена изоляция тестов, можно выполнить только выбранные тесты, передав им опцию only. У теста с only выполняются и все подтесты. Если only задан у набора, выполняются все тесты набора, кроме случая, когда у потомков тоже есть only — тогда только они.
При подтестах внутри test()/it() нужно пометить only всех предков, чтобы запустить только часть подтестов.
Метод контекста runOnly() даёт то же на уровне подтестов. Невыполненные тесты не попадают в вывод раннера.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | |
Фильтрация тестов по имени¶
Опция командной строки --test-name-pattern позволяет запускать только те тесты, имя которых соответствует заданному шаблону; опция --test-skip-pattern — пропускать тесты, имя которых соответствует шаблону. Шаблоны имён интерпретируются как регулярные выражения JavaScript. Опции --test-name-pattern и --test-skip-pattern можно указывать несколько раз, в том числе для вложенных тестов. Для каждого выполняемого теста также выполняются соответствующие хуки, например beforeEach(). Тесты, которые не выполняются, не попадают в вывод раннера.
Для приведённого ниже файла тестов запуск Node.js с --test-name-pattern="test [1-3]" приведёт к выполнению test 1, test 2 и test 3. Если test 1 не совпал с шаблоном имени, его подтесты не выполнятся, даже если сами подходят под шаблон. Тот же набор тестов можно выполнить, передав --test-name-pattern несколько раз (например --test-name-pattern="test 1", --test-name-pattern="test 2" и т. д.).
1 2 3 4 5 6 7 8 9 | |
Шаблоны имён можно задавать в виде литералов регулярных выражений — тогда доступны флаги RegExp. В предыдущем примере запуск Node.js с --test-name-pattern="/test [4-5]/i" (или --test-skip-pattern="/test [4-5]/i") даст совпадение с Test 4 и Test 5, так как шаблон без учёта регистра.
Чтобы однозначно сопоставить один тест с шаблоном, префиксуйте имя всеми именами предков через пробел. Например, для файла:
1 2 3 4 5 6 7 | |
Запуск Node.js с --test-name-pattern="test 1 some test" сопоставит только some test внутри test 1.
Шаблоны имён не меняют набор файлов, которые выполняет раннер.
Если заданы и --test-name-pattern, и --test-skip-pattern, тест должен удовлетворять обоим условиям, чтобы быть выполненным.
Посторонняя асинхронная активность¶
Как только функция теста завершает работу, результаты сообщаются как можно скорее, сохраняя порядок тестов. При этом тест может породить асинхронную активность, которая переживает сам тест. Раннер обрабатывает такую активность, но не откладывает отчёт о результатах ради неё.
В примере ниже тест завершается, когда два вызова setImmediate() ещё не выполнены. Первый setImmediate() пытается создать новый подтест. Поскольку родительский тест уже завершился и вывел результаты, новый подтест сразу помечается как проваленный и позже попадает в TestsStream.
Второй setImmediate() создаёт событие uncaughtException. События uncaughtException и unhandledRejection, исходящие от уже завершённого теста, модуль test помечает как провал и передаёт в TestsStream как диагностические предупреждения верхнего уровня.
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
Режим наблюдения (watch)¶
Стабильность: 1 — экспериментально
Раннер тестов Node.js поддерживает режим наблюдения при передаче флага --watch:
1 | |
В режиме watch раннер отслеживает изменения в тестовых файлах и зависимостях. При обнаружении изменений перезапускаются затронутые тесты. Работа продолжается, пока процесс не будет завершён.
Глобальная подготовка и завершение¶
Стабильность: 1.0 — ранняя разработка
Можно указать модуль, который выполняется до всех тестов и задаёт глобальное состояние или фикстуры. Удобно для подготовки ресурсов или общего состояния, нужного нескольким тестам.
Модуль может экспортировать:
- функцию
globalSetup— выполняется один раз перед стартом всех тестов; - функцию
globalTeardown— выполняется один раз после завершения всех тестов.
Путь к модулю задаётся флагом --test-global-setup при запуске тестов из командной строки.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
1 2 3 4 5 6 7 8 9 10 11 12 | |
Если функция глобальной подготовки выбрасывает ошибку, тесты не запускаются, процесс завершается с ненулевым кодом выхода. В этом случае globalTeardown не вызывается.
Запуск тестов из командной строки¶
Раннер тестов Node.js вызывается из командной строки с флагом --test:
1 | |
По умолчанию Node.js выполняет все файлы, подходящие под шаблоны:
**/*.test.{cjs,mjs,js}**/*-test.{cjs,mjs,js}**/*_test.{cjs,mjs,js}**/test-*.{cjs,mjs,js}**/test.{cjs,mjs,js}**/test/**/*.{cjs,mjs,js}
Если не указан --no-strip-types, дополнительно учитываются:
**/*.test.{cts,mts,ts}**/*-test.{cts,mts,ts}**/*_test.{cts,mts,ts}**/test-*.{cts,mts,ts}**/test.{cts,mts,ts}**/test/**/*.{cts,mts,ts}
Вместо этого в конце команды Node.js можно передать один или несколько шаблонов glob, как показано ниже. Поведение glob соответствует glob(7). Шаблоны glob в командной строке лучше заключать в двойные кавычки, чтобы оболочка не раскрывала их — так выше переносимость между системами.
1 | |
Случайный порядок выполнения тестов¶
Стабильность: 1.0 — ранняя разработка
Раннер может перемешивать порядок выполнения, чтобы выявлять тесты, зависящие от порядка. В этом режиме перемешиваются и найденные файлы тестов, и очередь тестов внутри файла. Включение: --test-randomize.
1 | |
При включённой рандомизации раннер выводит диагностическое сообщение с seed прогона:
1 | |
--test-random-seed=<число> воспроизводит тот же порядок. Указание --test-random-seed также включает рандомизацию, поэтому при заданном seed флаг --test-randomize необязателен:
1 | |
В большинстве файлов рандомизация работает автоматически. Важное исключение — последовательное await подтестов: каждый следующий стартует после завершения предыдущего, и раннер сохраняет порядок объявления вместо перемешивания.
Пример: выполняется строго по очереди и не рандомизируется.
1 2 3 4 5 6 7 8 | |
1 2 3 4 5 6 7 8 | |
API в стиле suite (describe()/it() или suite()/test()) по-прежнему допускают рандомизацию: соседние тесты ставятся в очередь вместе.
Пример: этот вариант остаётся подходящим для рандомизации.
1 2 3 4 5 6 7 | |
1 2 3 4 5 6 7 | |
--test-randomize и --test-random-seed несовместимы с режимом --watch.
Подходящие файлы выполняются как тестовые. Подробнее — в разделе модель выполнения раннера тестов.
Модель выполнения раннера тестов¶
При включённой изоляции тестов на уровне процесса каждый подходящий файл теста выполняется в отдельном дочернем процессе. Максимальное число одновременных дочерних процессов задаёт --test-concurrency. Если дочерний процесс завершился с кодом 0, тест считается пройденным; иначе — провалом. Файлы должны быть исполняемы Node.js, но не обязаны использовать внутри модуль node:test.
Каждый файл выполняется как обычный скрипт: если в нём через node:test объявлены тесты, они выполняются в одном потоке приложения, независимо от опции concurrency у test().
При отключённой изоляции каждый файл импортируется в процесс раннера. После загрузки всех файлов тесты верхнего уровня выполняются с параллелизмом 1. Общий контекст позволяет тестам взаимодействовать так, как при изоляции нельзя: например глобальное состояние может меняться тестом из другого файла.
Наследование опций дочерним процессом¶
В режиме изоляции процессов (по умолчанию) дочерние процессы наследуют опции Node.js от родителя, в том числе из файлов конфигурации. Часть флагов отфильтрована для корректной работы раннера:
--test— запрещён, чтобы избежать рекурсивного запуска тестов--experimental-test-coverage— управляет раннер--watch— режим watch на уровне родителя--experimental-default-config-file— загрузка конфигурации на уровне родителя--test-reporter— отчётность на уровне родителя--test-reporter-destination— назначения вывода задаёт родитель--experimental-config-file— пути к конфигу на уровне родителя--test-randomize— рандомизацию задаёт родитель и передаёт дочерним процессам--test-random-seed— seed рандомизации задаёт родитель и передаёт дочерним процессам
Остальные опции Node.js из аргументов командной строки, переменных окружения и конфигурационных файлов дочерние процессы наследуют.
Сбор покрытия кода¶
Стабильность: 1 — экспериментально
При запуске Node.js с флагом --experimental-test-coverage собирается покрытие кода; после завершения всех тестов выводится статистика. Если переменная окружения NODE_V8_COVERAGE задаёт каталог покрытия, файлы V8 записываются туда. Модули ядра Node.js и файлы в node_modules/ по умолчанию не входят в отчёт; их можно явно включить флагом --test-coverage-include. По умолчанию все подходящие тестовые файлы исключаются из отчёта о покрытии; исключения можно переопределить --test-coverage-exclude. При включённом покрытии отчёт передаётся репортёрам тестов через событие 'test:coverage'.
Покрытие для набора строк можно отключить такими комментариями:
1 2 3 4 5 6 7 | |
Покрытие можно отключить на заданное число строк; затем оно снова включается автоматически. Если число строк не указано, игнорируется одна строка.
1 2 3 4 5 6 7 8 9 | |
Репортёры покрытия¶
Репортёры tap и spec выводят сводку по покрытию. Также есть репортёр lcov, создающий файл lcov для детального отчёта.
1 | |
- Этот репортёр не выводит результаты самих тестов.
- Его лучше использовать вместе с другим репортёром.
Подмены (mocking)¶
Модуль node:test поддерживает подмены через объект верхнего уровня mock. В примере создаётся шпион для функции сложения двух чисел; затем проверяется, что функция вызывалась ожидаемо.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
Та же функциональность доступна на объекте TestContext каждого теста. В примере ниже шпион создаётся для метода объекта через API контекста. Плюс подмен через контекст: раннер сам восстанавливает подменённое поведение после завершения теста.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
Таймеры¶
Подмена таймеров — распространённый приём: имитация и управление setInterval и setTimeout без реального ожидания интервалов.
Полный список методов и возможностей — в классе MockTimers.
Так проще писать устойчивые и предсказуемые тесты для логики, зависящей от времени.
Ниже показана подмена setTimeout. Вызов .enable({ apis: ['setTimeout'] }); подменяет setTimeout в модулях node:timers и node:timers/promises, а также глобальный setTimeout в Node.js.
Примечание: деструктуризация вроде import [setTimeout](timers.md#settimeoutcallback-delay-args) from 'node:timers' в этой API пока не поддерживается.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
Та же функциональность доступна в свойстве mock у TestContext. При подмене через контекст раннер после теста автоматически восстанавливает подменённые таймеры.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
Дата¶
API подмены таймеров позволяет подменять и объект Date — удобно для тестов, зависящих от времени, и для симуляции Date.now() и т. п.
Реализация даты тоже входит в MockTimers — см. там полный список методов.
Примечание: при совместной подмене Date и таймеров они связаны: сдвиг времени двигает и подменённую дату — имитируется один общий внутренний таймер.
Ниже — подмена Date и текущее значение Date.now().
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
Если начальная эпоха не задана, дата берётся от 0 в Unix-эпохе (1 января 1970, 00:00:00 UTC). Начальное время можно задать свойством now в вызове .enable() — оно станет стартовым для подменённого Date (положительное целое или другой объект Date).
1 2 3 4 5 6 7 8 9 10 11 12 | |
1 2 3 4 5 6 7 8 9 10 11 12 | |
Метод .setTime() вручную переносит подменённую дату; принимается только неотрицательное целое.
Примечание: метод не выполняет подменённые таймеры, которые оказались «в прошлом» относительно нового времени.
В примере ниже задаётся новое время для подменённой даты.
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
Таймеры, запланированные «в прошлом», при вызове setTime() не срабатывают. Чтобы выполнить их, дальше двигайте время через .tick().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
.runAll() выполняет все таймеры в очереди и сдвигает подменённую дату до времени последнего выполненного таймера, как если бы время прошло.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
Снимки (snapshot testing)¶
Добавлено в: v22.3.0
Тесты-снимки сериализуют произвольные значения в строки и сравнивают их с эталоном. Эталонные значения называются снимками и хранятся в файле снимков; раннер им управляет, но формат остаётся читаемым для отладки. Файлы снимков обычно коммитят вместе с тестами.
Файлы снимков создаются при запуске Node.js с флагом --test-update-snapshots. На каждый тестовый файл — отдельный файл снимка. По умолчанию имя совпадает с тестом и расширением .snapshot; поведение настраивается через snapshot.setResolveSnapshotPath(). Каждое утверждение снимка соответствует экспорту в файле.
Пример ниже при первом запуске провалится: файла снимка ещё нет.
1 2 3 4 5 6 7 | |
Сгенерируйте файл снимка, запустив тест с --test-update-snapshots. Тест должен пройти, рядом появится test.js.snapshot. Ниже — пример содержимого: каждый снимок помечен полным именем теста и счётчиком, если в одном тесте несколько снимков.
1 2 3 4 5 6 7 8 9 10 | |
После создания файла снимка запустите тесты без --test-update-snapshots — они должны проходить.
Репортёры тестов¶
В модуле node:test можно передать флаги --test-reporter, чтобы раннер использовал нужный репортёр.
Встроенные репортёры:
-
specВыводит результаты в удобочитаемом виде. Репортёр по умолчанию. -
tapФормат TAP. -
dotКомпактный вывод: успешный тест —., провал —X. -
junitjUnit XML. -
lcovПокрытие кода; используется с--experimental-test-coverage.
Точный формат вывода может меняться между версиями Node.js и не гарантирован для программного разбора. Для программного доступа к результатам подписывайтесь на события TestsStream.
Репортёры импортируются из node:test/reporters:
1 | |
1 | |
Пользовательские репортёры¶
--test-reporter может указывать путь к своему репортёру. Это модуль, экспортирующий значение, допустимое для stream.compose. Репортёр преобразует события TestsStream.
Пример репортёра на базе stream.Transform:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | |
Пример репортёра на генераторе:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | |
Значение для --test-reporter — строка в том же виде, что аргумент динамического import(), или значение, как у --import.
Несколько репортёров¶
Флаг --test-reporter можно указать несколько раз, чтобы получить вывод в нескольких форматах. Тогда для каждого репортёра нужно задать назначение через --test-reporter-destination: stdout, stderr или путь к файлу. Пары «репортёр — назначение» сопоставляются по порядку следования.
В примере spec пишет в stdout, а dot — в file.txt:
1 | |
Если указан один репортёр, назначение по умолчанию — stdout, пока не задано явно.
run([options])¶
options<Object>Параметры конфигурации запуска тестов. Поддерживаются следующие свойства:concurrency<number>|<boolean>Если указано число, параллельно выполняется столько процессов с тестами; каждый процесс соответствует одному тестовому файлу. Еслиtrue, параллельно запускаетсяos.availableParallelism() - 1тестовых файлов. Еслиfalse, за раз выполняется только один тестовый файл. По умолчанию:false.cwd<string>Текущий рабочий каталог для раннера тестов. Используется как база для разрешения путей к файлам, как при запуске тестов из командной строки из этого каталога. По умолчанию:process.cwd().files<Array>Массив путей к запускаемым файлам. По умолчанию: как при запуске тестов из командной строки.forceExit<boolean>Завершать процесс после того, как все известные тесты выполнены, даже если цикл событий иначе оставался бы активным. По умолчанию:false.globPatterns<Array>Массив glob-шаблонов для подбора тестовых файлов. Нельзя использовать вместе сfiles. По умолчанию: как при запуске тестов из командной строки.inspectPort<number>|<Function>Порт инспектора для дочернего процесса с тестами. Может быть числом или функцией без аргументов, возвращающей число. Если передано пустое значение, у каждого процесса свой порт, увеличивающийся отprocess.debugPortродителя. Опция игнорируется, еслиisolationравно'none'— дочерние процессы не создаются. По умолчанию:undefined.isolation<string>Тип изоляции тестов. При значении'process'каждый тестовый файл выполняется в отдельном дочернем процессе. При'none'все тестовые файлы выполняются в текущем процессе. По умолчанию:'process'.only<boolean>Если истинно, контекст выполняет только тесты с установленной опциейonly.setup<Function>Функция, принимающая экземплярTestsStreamи позволяющая зарегистрировать обработчики до запуска тестов. По умолчанию:undefined.execArgv<Array>Массив флагов CLI для передачи исполняемому файлуnodeпри порождении дочерних процессов. Не действует приisolationравном'none'. По умолчанию:[]argv<Array>Массив флагов CLI для передачи каждому тестовому файлу при порождении дочерних процессов. Не действует приisolationравном'none'. По умолчанию:[].signal<AbortSignal>Позволяет прервать выполняющийся прогон тестов.testNamePatterns<string>|<RegExp>|<Array>Строка, RegExp или массив RegExp — выполнять только тесты, имя которых совпадает с шаблоном. Шаблоны имён интерпретируются как регулярные выражения JavaScript. Для каждого выполняемого теста вызываются и соответствующие хуки, напримерbeforeEach(). По умолчанию:undefined.testSkipPatterns<string>|<RegExp>|<Array>Строка, RegExp или массив RegExp — исключать тесты, имя которых совпадает с шаблоном. Шаблоны имён интерпретируются как регулярные выражения JavaScript. Для каждого выполняемого теста вызываются и соответствующие хуки, напримерbeforeEach(). По умолчанию:undefined.timeout<number>Через столько миллисекунд выполнение тестов считается проваленным. Если не задано, подтесты наследуют значение от родителя. По умолчанию:Infinity.watch<boolean>Включить режим watch или нет. По умолчанию:false.shard<Object>Запуск части тестов (шард). По умолчанию:undefined.randomize<boolean>Перемешивать порядок тестовых файлов и очередь тестов. Несовместимо сwatch: true. По умолчанию:false.randomSeed<number>Зерно для перемешивания порядка. Если задано, прогоны можно повторять с тем же порядком, а указание опции также включает рандомизацию. Значение — целое от0до4294967295. По умолчанию:undefined.rerunFailuresFilePath<string>Путь к файлу, в котором раннер сохраняет состояние тестов, чтобы при следующем запуске выполнить только проваленные тесты; подробнее см. Повторный запуск проваленных тестов. По умолчанию:undefined.coverage<boolean>Включить сбор покрытия кода. По умолчанию:false.coverageExcludeGlobs<string>|<Array>Исключить файлы из покрытия по glob-шаблону (абсолютные и относительные пути). Учитывается только приcoverage: true. Если заданы иcoverageExcludeGlobs, иcoverageIncludeGlobs, в отчёт попадают файлы, удовлетворяющие обоим условиям. По умолчанию:undefined.coverageIncludeGlobs<string>|<Array>Явно включить файлы в покрытие по glob-шаблону (абсолютные и относительные пути). Учитывается только приcoverage: true. Если заданы иcoverageExcludeGlobs, иcoverageIncludeGlobs, в отчёт попадают файлы, удовлетворяющие обоим условиям. По умолчанию:undefined.lineCoverage<number>Минимальный процент покрытых строк. Если покрытие ниже порога, процесс завершится с кодом1. По умолчанию:0.branchCoverage<number>Минимальный процент покрытых ветвлений. Если покрытие ниже порога, процесс завершится с кодом1. По умолчанию:0.functionCoverage<number>Минимальный процент покрытых функций. Если покрытие ниже порога, процесс завершится с кодом1. По умолчанию:0.env<Object>Переменные окружения для процесса с тестами. Несовместимо сisolation='none'. Переменные заменяют значения основного процесса и не сливаются сprocess.env. По умолчанию:process.env.
- Возвращает:
<TestsStream>
Примечание: shard используется для горизонтального распараллеливания прогона между машинами или процессами, в том числе на больших наборах в разных средах. Несовместим с режимом watch, который рассчитан на быстрые итерации с автоматическим перезапуском тестов при изменении файлов.
1 2 3 4 5 6 7 8 9 10 11 | |
1 2 3 4 5 6 7 8 9 10 | |
suite([name][, options][, fn])¶
name<string>Имя набора, отображаемое в отчёте о тестах. По умолчанию: свойствоnameуfnили'<anonymous>', если уfnнет имени.options<Object>Необязательные параметры набора. Поддерживаются те же опции, что уtest([name][, options][, fn]).fn<Function>|<AsyncFunction>Функция набора с вложенными тестами и наборами. Первый аргумент — объектSuiteContext. По умолчанию: пустая функция.- Возвращает:
<Promise>Немедленно выполняется сundefined.
Функция suite() импортируется из модуля node:test.
suite.skip([name][, options][, fn])¶
Сокращение для пропуска набора. То же, что suite([name], { skip: true }[, fn]).
suite.todo([name][, options][, fn])¶
Сокращение для пометки набора как TODO. То же, что suite([name], { todo: true }[, fn]).
suite.only([name][, options][, fn])¶
Сокращение для пометки набора как only. То же, что suite([name], { only: true }[, fn]).
test([name][, options][, fn])¶
name<string>Имя теста, отображаемое в отчёте. По умолчанию: свойствоnameуfnили'<anonymous>', если уfnнет имени.options<Object>Параметры теста. Поддерживаются следующие свойства:concurrency<number>|<boolean>Если указано число, столько тестов выполняется асинхронно (по-прежнему в одном потоке цикла событий). Еслиtrue, все запланированные асинхронные тесты идут параллельно в рамках потока. Еслиfalse— по одному тесту за раз. Если не задано, подтесты наследуют значение от родителя. По умолчанию:false.expectFailure<boolean>|<string>|<RegExp>|<Function>|<Object>|<Error>Если истинно, от теста ожидается провал. Непустая строка показывается в отчёте как причина ожидаемого провала. Если переданы напрямую RegExp | Function | Object | Error (без обёртки{ match: … }), тест считается пройденным только при совпадении выброшенной ошибки по правиламassert.throws. Чтобы задать и причину, и проверку, передайте объект с полямиlabel(строка) иmatch(RegExp, Function, Object или Error). По умолчанию:false.only<boolean>Если истинно и контекст настроен на выполнение только тестов сonly, этот тест выполняется; иначе пропускается. По умолчанию:false.signal<AbortSignal>Позволяет прервать выполняющийся тест.skip<boolean>|<string>Если истинно, тест пропускается. Строка показывается в отчёте как причина пропуска. По умолчанию:false.todo<boolean>|<string>Если истинно, тест помечается какTODO. Строка показывается в отчёте как причина статусаTODO. По умолчанию:false.timeout<number>Через столько миллисекунд тест считается проваленным. Если не задано, подтесты наследуют значение от родителя. По умолчанию:Infinity.plan<number>Ожидаемое число утверждений и подтестов в тесте. Если фактическое число не совпадает с планом, тест проваливается. По умолчанию:undefined.
fn<Function>|<AsyncFunction>Тестируемая функция. Первый аргумент — объектTestContext. При колбэк-стиле второй аргумент — колбэк. По умолчанию: пустая функция.- Возвращает:
<Promise>Выполняется сundefinedпосле завершения теста или сразу, если тест выполняется внутри набора.
test() — это значение, импортируемое из модуля test. Каждый вызов регистрирует тест в TestsStream.
Объект TestContext, передаваемый в fn, используется для действий в контексте текущего теста: пропуск, диагностика, подтесты и т. д.
test() возвращает Promise, который выполняется по завершении теста; внутри набора он может выполниться сразу. Для тестов верхнего уровня возвращаемое значение часто можно игнорировать. Для подтестов await нужен, чтобы родитель не завершился раньше и не отменил подтест (см. пример).
1 2 3 4 5 6 7 8 9 | |
Опция timeout завершает тест с провалом по истечении timeout мс, но не является надёжным способом отмены: выполняющийся тест может блокировать поток и помешать срабатыванию отмены.
test.skip([name][, options][, fn])¶
Сокращение для пропуска теста — то же, что test([name], { skip: true }[, fn]).
test.todo([name][, options][, fn])¶
Сокращение для пометки теста как TODO — то же, что test([name], { todo: true }[, fn]).
test.only([name][, options][, fn])¶
Сокращение для пометки теста как only — то же, что test([name], { only: true }[, fn]).
describe([name][, options][, fn])¶
Псевдоним suite().
Функция describe() импортируется из модуля node:test.
describe.skip([name][, options][, fn])¶
Сокращение для пропуска набора — то же, что describe([name], { skip: true }[, fn]).
describe.todo([name][, options][, fn])¶
Сокращение для пометки набора как TODO — то же, что describe([name], { todo: true }[, fn]).
describe.only([name][, options][, fn])¶
Сокращение для пометки набора как only — то же, что describe([name], { only: true }[, fn]).
it([name][, options][, fn])¶
Псевдоним test().
Функция it() импортируется из модуля node:test.
it.skip([name][, options][, fn])¶
Сокращение для пропуска теста — то же, что it([name], { skip: true }[, fn]).
it.todo([name][, options][, fn])¶
Сокращение для пометки теста как TODO — то же, что it([name], { todo: true }[, fn]).
it.only([name][, options][, fn])¶
Сокращение для пометки теста как only — то же, что it([name], { only: true }[, fn]).
before([fn][, options])¶
fn<Function>|<AsyncFunction>Функция хука. При колбэк-стиле второй аргумент — колбэк. По умолчанию: пустая функция.options<Object>Параметры хука. Поддерживаются следующие свойства:signal<AbortSignal>Позволяет прервать выполняющийся хук.timeout<number>Через столько миллисекунд хук считается проваленным. Если не задано, подтесты наследуют значение от родителя. По умолчанию:Infinity.
Создаёт хук, выполняемый перед набором тестов.
1 2 3 4 5 6 | |
after([fn][, options])¶
fn<Function>|<AsyncFunction>Функция хука. При колбэк-стиле второй аргумент — колбэк. По умолчанию: пустая функция.options<Object>Параметры хука. Поддерживаются следующие свойства:signal<AbortSignal>Позволяет прервать выполняющийся хук.timeout<number>Через столько миллисекунд хук считается проваленным. Если не задано, подтесты наследуют значение от родителя. По умолчанию:Infinity.
Создаёт хук, выполняемый после набора тестов.
1 2 3 4 5 6 | |
Примечание: хук after выполняется гарантированно, даже если тесты в наборе провалились.
beforeEach([fn][, options])¶
fn<Function>|<AsyncFunction>Функция хука. При колбэк-стиле второй аргумент — колбэк. По умолчанию: пустая функция.options<Object>Параметры хука. Поддерживаются следующие свойства:signal<AbortSignal>Позволяет прервать выполняющийся хук.timeout<number>Через столько миллисекунд хук считается проваленным. Если не задано, подтесты наследуют значение от родителя. По умолчанию:Infinity.
Создаёт хук, выполняемый перед каждым тестом в текущем наборе.
1 2 3 4 5 6 | |
afterEach([fn][, options])¶
fn<Function>|<AsyncFunction>Функция хука. При колбэк-стиле второй аргумент — колбэк. По умолчанию: пустая функция.options<Object>Параметры хука. Поддерживаются следующие свойства:signal<AbortSignal>Позволяет прервать выполняющийся хук.timeout<number>Через столько миллисекунд хук считается проваленным. Если не задано, подтесты наследуют значение от родителя. По умолчанию:Infinity.
Создаёт хук, выполняемый после каждого теста в текущем наборе. Хук afterEach() выполняется даже при провале теста.
1 2 3 4 5 6 | |
assert¶
Объект, методы которого настраивают доступные утверждения для объектов TestContext в текущем процессе. По умолчанию доступны методы из node:assert и функции снимков.
Ту же конфигурацию можно задать всем файлам через общий модуль, подключаемый --require или --import.
assert.register(name, fn)¶
Определяет новую функцию утверждения с заданным именем. Если утверждение с таким именем уже есть, оно перезаписывается.
snapshot¶
Объект для настройки параметров снимков по умолчанию в текущем процессе. Общая конфигурация для всех файлов — через модуль с --require или --import.
snapshot.setDefaultSnapshotSerializers(serializers)¶
serializers<Array>Массив синхронных функций — сериализаторы по умолчанию для тестов со снимками.
Задаёт механизм сериализации по умолчанию для раннера. По умолчанию раннер вызывает JSON.stringify(value, null, 2) для переданного значения. У JSON.stringify() есть ограничения на циклические структуры и типы данных. Для более надёжной сериализации используйте эту функцию.
snapshot.setResolveSnapshotPath(fn)¶
fn<Function>Функция вычисления пути к файлу снимка. Единственный аргумент — путь к тестовому файлу. Если тест не привязан к файлу (например в REPL), аргументundefined.fn()должна вернуть строку с путём к файлу снимка.
Задаёт расположение файла снимка. По умолчанию имя файла снимка совпадает с точкой входа с расширением .snapshot.
Class: MockFunctionContext¶
Класс MockFunctionContext позволяет просматривать и менять поведение подмен, созданных через API MockTracker.
ctx.calls¶
- Тип:
<Array>
Геттер возвращает копию внутреннего массива вызовов подмены. Каждый элемент — объект со свойствами:
arguments<Array>Аргументы вызова подменённой функции.error<any>Если подменённая функция выбросила исключение, здесь значение исключения. По умолчанию:undefined.result<any>Возвращённое подменённой функцией значение.stack<Error>ОбъектError, по стеку можно определить место вызова подмены.target<Function>| undefined Если подмена — конструктор, здесь класс создаваемого экземпляра; иначеundefined.this<any>Значениеthisпри вызове подмены.
ctx.callCount()¶
- Возвращает:
<integer>Число вызовов этой подмены.
Эффективнее, чем ctx.calls.length: ctx.calls — геттер, создающий копию внутреннего массива.
ctx.mockImplementation(implementation)¶
implementation<Function>|<AsyncFunction>Новая реализация подмены.
Меняет поведение существующей подмены.
Пример: создаётся подмена через t.mock.fn(), вызывается функция, затем подменяется реализация.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
ctx.mockImplementationOnce(implementation[, onCall])¶
implementation<Function>|<AsyncFunction>Реализация для вызова с номеромonCall.onCall<integer>Номер вызова, на котором применитьimplementation. Если такой вызов уже произошёл, выбрасывается исключение. По умолчанию: номер следующего вызова.
Меняет поведение подмены только для одного вызова. После вызова с номером onCall подмена возвращается к поведению, которое было бы без mockImplementationOnce().
Пример: подмена через t.mock.fn(), смена реализации на один следующий вызов, затем прежнее поведение.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
ctx.resetCalls()¶
Сбрасывает историю вызовов подменённой функции.
ctx.restore()¶
Восстанавливает исходную реализацию подменённой функции. Подмену по-прежнему можно вызывать.
Class: MockModuleContext¶
Стабильность: 1.0 — ранняя разработка
Класс MockModuleContext управляет поведением подмен модулей, созданных через API MockTracker.
ctx.restore()¶
Восстанавливает исходную реализацию подменённого модуля.
Class: MockPropertyContext¶
Класс MockPropertyContext позволяет просматривать и менять поведение подмен свойств, созданных через API MockTracker.
ctx.accesses¶
- Тип:
<Array>
Геттер возвращает копию внутреннего массива обращений (чтение/запись) к подменённому свойству. Каждый элемент — объект со свойствами:
type<string>'get'или'set'— тип обращения.value<any>Прочитанное ('get') или записанное ('set') значение.stack<Error>ОбъектErrorдля определения места обращения к подмене.
ctx.accessCount()¶
- Возвращает:
<integer>Число обращений к свойству (чтение и запись).
Эффективнее, чем ctx.accesses.length: ctx.accesses — геттер с копией внутреннего массива.
ctx.mockImplementation(value)¶
value<any>Новое значение подменённого свойства.
Меняет значение, возвращаемое геттером подменённого свойства.
ctx.mockImplementationOnce(value[, onAccess])¶
value<any>Значение для обращения с номеромonAccess.onAccess<integer>Номер обращения, на котором применитьvalue. Если такое обращение уже было, выбрасывается исключение. По умолчанию: номер следующего обращения.
Меняет поведение подмены только для одного обращения. После обращения с номером onAccess подмена возвращается к поведению без mockImplementationOnce().
Пример: подмена через t.mock.property(), смена значения на одно следующее обращение, затем прежнее поведение.
1 2 3 4 5 6 7 8 9 10 | |
Ограничение¶
Для согласованности с остальным API подмен эта функция считает и чтение, и запись свойства обращениями. Если запись происходит на том же индексе обращения, значение «на один раз» расходуется на операцию set, и подменённое свойство принимает это значение. Это может давать неожиданный результат, если «на один раз» предполагалось только для чтения.
ctx.resetAccesses()¶
Сбрасывает историю обращений к подменённому свойству.
ctx.restore()¶
Восстанавливает исходное поведение подменённого свойства. Подмену по-прежнему можно использовать.
Class: MockTracker¶
Класс MockTracker управляет подменами. Модуль раннера экспортирует mock верхнего уровня — экземпляр MockTracker. У каждого теста свой экземпляр в свойстве контекста mock.
mock.fn([original[, implementation]][, options])¶
original<Function>|<AsyncFunction>Необязательная исходная функция для подмены. По умолчанию: пустая функция.implementation<Function>|<AsyncFunction>Необязательная реализация дляoriginal. Удобно для подмен с заданным числом вызовов с одним поведением и последующим восстановлениемoriginal. По умолчанию: функция изoriginal.options<Object>Необязательные параметры подмены функции. Поддерживаются свойства:times<integer>Сколько раз подмена использует поведениеimplementation. Послеtimesвызовов автоматически восстанавливается поведениеoriginal. Должно быть целым больше нуля. По умолчанию:Infinity.
- Возвращает:
<Proxy>Подменённая функция с особым свойствомmock— экземпляромMockFunctionContextдля проверки и смены поведения.
Создаёт подмену функции.
Пример: счётчик увеличивается на 1 за вызов; опция times задаёт два первых вызова с прибавлением 2.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
mock.getter(object, methodName[, implementation][, options])¶
Синтаксический сахар для MockTracker.method с options.getter равным true.
mock.method(object, methodName[, implementation][, options])¶
object<Object>Объект, метод которого подменяется.methodName<string>|<symbol>Имя метода наobject. Еслиobject[methodName]не функция, выбрасывается ошибка.implementation<Function>|<AsyncFunction>Необязательная реализация дляobject[methodName]. По умолчанию: исходный методobject[methodName].options<Object>Необязательные параметры подмены метода. Поддерживаются свойства:getter<boolean>Еслиtrue,object[methodName]трактуется как геттер. Несовместимо с опциейsetter. По умолчанию: false.setter<boolean>Еслиtrue,object[methodName]трактуется как сеттер. Несовместимо с опциейgetter. По умолчанию: false.times<integer>Сколько раз подмена использует поведениеimplementation. Послеtimesвызовов восстанавливается исходное поведение. Должно быть целым больше нуля. По умолчанию:Infinity.
- Возвращает:
<Proxy>Подменённый метод с особым свойствомmock— экземпляромMockFunctionContext.
Создаёт подмену существующего метода объекта. Ниже — пример подмены метода.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
mock.module(specifier[, options])¶
Стабильность: 1.0 — ранняя разработка
specifier<string>|<URL>Идентификатор подменяемого модуля.options<Object>Необязательные параметры подмены модуля. Поддерживаются свойства:cache<boolean>Еслиfalse, каждый вызовrequire()илиimport()создаёт новую подмену. Еслиtrue, последующие вызовы возвращают ту же подмену, модуль попадает в кэш CommonJS. По умолчанию: false.exports<Object>Необязательные экспорты подмены. Свойствоdefault, если задано, — экспорт по умолчанию; остальные собственные перечислимые свойства — именованные экспорты. Нельзя использовать вместе сdefaultExportилиnamedExports.- Для CommonJS или встроенного модуля
exports.defaultзадаёт значениеmodule.exports. - Если для CommonJS или встроенной подмены нет
exports.default,module.exports— пустой объект. - Если есть именованные экспорты и экспорт по умолчанию не объект, при использовании как CommonJS или встроенного модуля подмена выбросит исключение.
- Для CommonJS или встроенного модуля
defaultExport<any>Необязательный экспорт по умолчанию. Если не задан, у ESM-подмены нет default-экспорта. Для CommonJS или встроенного модуля значение идёт вmodule.exports. Если не задано, для CJS и встроенных подменmodule.exports— пустой объект. Нельзя использовать вместе сoptions.exports. Устарело, будет удалено; предпочтительноoptions.exports.default.namedExports<Object>Необязательный объект ключей и значений для именованных экспортов. Для CommonJS или встроенного модуля значения копируются вmodule.exports. Если есть именованные экспорты и экспорт по умолчанию не объект, при использовании как CJS или встроенного модуля подмена выбросит исключение. Нельзя использовать вместе сoptions.exports. Устарело; предпочтительноoptions.exports.
- Возвращает:
<MockModuleContext>Объект для управления подменой.
Подменяет экспорты модулей ECMAScript, CommonJS, JSON и встроенных модулей Node.js. Ссылки на оригинальный модуль, созданные до подмены, не меняются. Для подмены модулей Node.js нужно запускать с флагом --experimental-test-module-mocks.
Примечание: хуки настройки модулей, зарегистрированные через синхронный API, влияют на разрешение specifier в mock.module. Хуки асинхронного API сейчас игнорируются (загрузчик раннера синхронный, многократные цепочки загрузки в Node не поддерживаются).
Ниже — пример подмены модуля.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | |
mock.property(object, propertyName[, value])¶
object<Object>Объект, свойство которого подменяется.propertyName<string>|<symbol>Имя свойства наobject.value<any>Необязательное значение подмены дляobject[propertyName]. По умолчанию: исходное значение свойства.- Возвращает:
<Proxy>Прокси к объекту с подменённым свойством; у него есть свойствоmock— экземплярMockPropertyContextдля проверки и смены поведения.
Создаёт подмену значения свойства: можно отслеживать и управлять чтением и записью и восстановить исходное значение.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
mock.reset()¶
Восстанавливает исходное поведение всех подмен, созданных этим MockTracker, и отвязывает их от экземпляра MockTracker. Отвязанные подмены по-прежнему вызываемы, но этот MockTracker больше не может их сбрасывать или иначе управлять ими.
После каждого теста эта функция вызывается для MockTracker контекста. При активном использовании глобального MockTracker рекомендуется вызывать её вручную.
mock.restoreAll()¶
Восстанавливает исходное поведение всех подмен этого MockTracker. В отличие от mock.reset(), mock.restoreAll() не отвязывает подмены от MockTracker.
mock.setter(object, methodName[, implementation][, options])¶
Синтаксический сахар для MockTracker.method с options.setter равным true.
Class: MockTimers¶
Подмена таймеров — распространённый приём тестирования: имитировать и управлять setInterval и setTimeout без реального ожидания.
MockTimers также может подменять объект Date.
У MockTracker есть экспорт верхнего уровня timers — экземпляр MockTimers.
timers.enable([enableOptions])¶
Включает подмену указанных таймеров.
enableOptions<Object>Необязательные параметры включения подмены таймеров. Поддерживаются свойства:apis<Array>Необязательный массив подменяемых API. Допустимые значения:'setInterval','setTimeout','setImmediate'и'Date'. По умолчанию:['setInterval', 'setTimeout', 'setImmediate', 'Date']. Если массив не передан, по умолчанию подменяются все связанные с временем API ('setInterval','clearInterval','setTimeout','clearTimeout','setImmediate','clearImmediate'и'Date').now<number>|<Date>Необязательное начальное время в миллисекундах или объектDateдляDate.now(). По умолчанию:0.
Примечание: при подмене конкретного таймера неявно подменяется и соответствующая функция очистки.
Примечание: подмена Date влияет на подменённые таймеры — общие внутренние часы.
Пример без задания начального времени:
1 2 | |
1 2 | |
В примере подменяется setInterval и неявно clearInterval. Подменяются только setInterval и clearInterval из node:timers, node:timers/promises и globalThis.
Пример с заданным начальным временем
1 2 | |
1 2 | |
Пример с объектом Date как начальным временем
1 2 | |
1 2 | |
Если вызвать mock.timers.enable() без параметров:
Подменяются все таймеры ('setInterval', 'clearInterval', 'setTimeout', 'clearTimeout', 'setImmediate' и 'clearImmediate'). Функции setInterval, clearInterval, setTimeout, clearTimeout, setImmediate и clearImmediate из node:timers, node:timers/promises и globalThis, а также глобальный объект Date.
timers.reset()¶
Восстанавливает исходное поведение всех подмен, созданных этим экземпляром MockTimers, и отвязывает их от MockTracker.
Примечание: после каждого теста эта функция вызывается для MockTracker контекста.
1 2 | |
1 2 | |
timers[Symbol.dispose]()¶
Вызывает timers.reset().
timers.tick([milliseconds])¶
Сдвигает время для всех подменённых таймеров.
milliseconds<number>На сколько миллисекунд сдвинуть таймеры. По умолчанию:1.
Примечание: в отличие от setTimeout в Node.js здесь допустимы только положительные числа. Отрицательные задержки в Node поддерживаются лишь для совместимости с вебом.
Ниже подменяется setTimeout, затем .tick сдвигает время и срабатывают ожидающие таймеры.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
Функцию .tick можно вызывать несколько раз подряд.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
Сдвиг времени через .tick также двигает любой объект Date, созданный после включения подмены (если подменялся и Date).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
Функции очистки¶
Как уже сказано, все функции очистки таймеров (clearTimeout, clearInterval и clearImmediate) подменяются неявно. Пример с setTimeout:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
Модули таймеров Node.js¶
После включения подмены таймеров затрагиваются node:timers, node:timers/promises и глобальные таймеры Node.js:
Примечание: деструктуризация вроде import [setTimeout](timers.md#settimeoutcallback-delay-args) from 'node:timers' пока не поддерживается этой API.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
В Node.js setInterval из node:timers/promises — это AsyncGenerator; он тоже поддерживается этой API:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | |
timers.runAll()¶
Немедленно выполняет все ожидающие подменённые таймеры. Если подменён и объект Date, время Date сдвигается до момента самого позднего таймера.
Ниже все ожидающие таймеры срабатывают сразу, без задержки.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
Примечание: runAll() предназначена для срабатывания таймеров в режиме подмены. На реальные системные часы и таймеры вне подмены не влияет.
timers.setTime(milliseconds)¶
Задаёт текущую метку Unix как опорную для всех подменённых объектов Date.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
Дата и таймеры вместе¶
Объекты даты и таймеров связаны. Если вызвать setTime() для подменённого Date, уже запланированные setTimeout и setInterval не срабатывают от этого.
Метод tick при этом сдвигает подменённый объект Date.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
Class: TestsStream¶
- Наследует
<Readable>
Успешный вызов run() возвращает новый TestsStream — поток событий о ходе выполнения тестов. TestsStream генерирует события в порядке, связанном с объявлением тестов.
Часть событий гарантированно следует порядку объявления тестов, другие — порядку фактического выполнения.
Event: 'test:coverage'¶
data<Object>summary<Object>Объект с отчётом о покрытии.files<Array>Массив отчётов по файлам. Каждый отчёт — объект со схемой:path<string>Абсолютный путь к файлу.totalLineCount<number>Всего строк.totalBranchCount<number>Всего ветвлений.totalFunctionCount<number>Всего функций.coveredLineCount<number>Покрыто строк.coveredBranchCount<number>Покрыто ветвлений.coveredFunctionCount<number>Покрыто функций.coveredLinePercent<number>Процент покрытых строк.coveredBranchPercent<number>Процент покрытых ветвлений.coveredFunctionPercent<number>Процент покрытых функций.functions<Array>Массив записей о покрытии функций.branches<Array>Массив записей о ветвлениях.lines<Array>Массив строк: номер строки и число покрытий.
thresholds<Object>Пороги по типам покрытия.totals<Object>Сводка по всем файлам.totalLineCount<number>Всего строк.totalBranchCount<number>Всего ветвлений.totalFunctionCount<number>Всего функций.coveredLineCount<number>Покрыто строк.coveredBranchCount<number>Покрыто ветвлений.coveredFunctionCount<number>Покрыто функций.coveredLinePercent<number>Процент покрытых строк.coveredBranchPercent<number>Процент покрытых ветвлений.coveredFunctionPercent<number>Процент покрытых функций.
workingDirectory<string>Рабочий каталог на начало сбора покрытия. Удобно для относительных путей, если тесты менялиcwdпроцесса Node.js.
nesting<number>Уровень вложенности теста.
Генерируется при включённом покрытии после завершения всех тестов.
Event: 'test:complete'¶
data<Object>column<number>| undefined Номер столбца объявления теста илиundefined, если тест запущен из REPL.details<Object>Дополнительные метаданные выполнения.file<string>| undefined Путь к тестовому файлу;undefined, если тест запущен из REPL.line<number>| undefined Номер строки объявления теста илиundefined, если тест запущен из REPL.name<string>Имя теста.nesting<number>Уровень вложенности теста.testNumber<number>Порядковый номер теста.todo<string>|<boolean>| undefined Присутствует, если вызванcontext.todoskip<string>|<boolean>| undefined Присутствует, если вызванcontext.skip
Генерируется по завершении выполнения теста. Порядок событий не совпадает с порядком объявления тестов. Соответствующие события в порядке объявления — 'test:pass' и 'test:fail'.
Event: 'test:dequeue'¶
data<Object>column<number>| undefined Номер столбца объявления теста илиundefined, если тест запущен из REPL.file<string>| undefined Путь к тестовому файлу;undefined, если тест запущен из REPL.line<number>| undefined Номер строки объявления теста илиundefined, если тест запущен из REPL.name<string>Имя теста.nesting<number>Уровень вложенности теста.type<string>Тип теста:'suite'или'test'.
Генерируется при снятии теста с очереди, непосредственно перед выполнением. Порядок в общем случае не совпадает с порядком объявления тестов. Соответствующее событие в порядке объявления — 'test:start'.
Event: 'test:diagnostic'¶
data<Object>column<number>| undefined Номер столбца объявления теста илиundefined, если тест запущен из REPL.file<string>| undefined Путь к тестовому файлу;undefined, если тест запущен из REPL.line<number>| undefined Номер строки объявления теста илиundefined, если тест запущен из REPL.message<string>Текст диагностики.nesting<number>Уровень вложенности теста.level<string>Уровень важности сообщения. Допустимые значения:'info': информационные сообщения.'warn': предупреждения.'error': ошибки.
Генерируется при вызове context.diagnostic. Порядок событий совпадает с порядком объявления тестов.
Event: 'test:enqueue'¶
data<Object>column<number>| undefined Номер столбца объявления теста илиundefined, если тест запущен из REPL.file<string>| undefined Путь к тестовому файлу;undefined, если тест запущен из REPL.line<number>| undefined Номер строки объявления теста илиundefined, если тест запущен из REPL.name<string>Имя теста.nesting<number>Уровень вложенности теста.type<string>Тип теста:'suite'или'test'.
Генерируется при постановке теста в очередь на выполнение.
Event: 'test:fail'¶
data<Object>column<number>| undefined Номер столбца объявления теста илиundefined, если тест запущен из REPL.details<Object>Дополнительные метаданные выполнения.file<string>| undefined Путь к тестовому файлу;undefined, если тест запущен из REPL.line<number>| undefined Номер строки объявления теста илиundefined, если тест запущен из REPL.name<string>Имя теста.nesting<number>Уровень вложенности теста.testNumber<number>Порядковый номер теста.todo<string>|<boolean>| undefined При вызовеcontext.todoskip<string>|<boolean>| undefined При вызовеcontext.skip
Генерируется при провале теста. Порядок совпадает с порядком объявления тестов. Соответствующее событие в порядке выполнения — 'test:complete'.
Event: 'test:interrupted'¶
data<Object>tests<Array>Массив объектов с данными о прерванных тестах.column<number>| undefined Номер столбца объявления теста илиundefined, если тест из REPL.file<string>| undefined Путь к тестовому файлу;undefined, если тест из REPL.line<number>| undefined Номер строки объявления теста илиundefined, если тест из REPL.name<string>Имя теста.nesting<number>Уровень вложенности теста.
Генерируется при прерывании раннера сигналом SIGINT (например Ctrl+C). В событии — сведения о тестах, которые выполнялись в момент прерывания.
При изоляции процессов (по умолчанию) имя теста — путь к файлу: родительский раннер знает только тесты уровня файла. При --test-isolation=none показывается фактическое имя теста.
Event: 'test:pass'¶
data<Object>column<number>| undefined Номер столбца объявления теста илиundefined, если тест запущен из REPL.details<Object>Дополнительные метаданные выполнения.duration_ms<number>Длительность теста в миллисекундах.type<string>| undefined Тип теста: признак набора.attempt<number>| undefined Номер попытки прогона, только при--test-rerun-failures.passed_on_attempt<number>| undefined Номер попытки, на которой тест прошёл, только при--test-rerun-failures.
file<string>| undefined Путь к тестовому файлу;undefined, если тест запущен из REPL.line<number>| undefined Номер строки объявления теста илиundefined, если тест запущен из REPL.name<string>Имя теста.nesting<number>Уровень вложенности теста.testNumber<number>Порядковый номер теста.todo<string>|<boolean>| undefined При вызовеcontext.todoskip<string>|<boolean>| undefined При вызовеcontext.skip
Генерируется при успешном прохождении теста. Порядок совпадает с порядком объявления тестов. Соответствующее событие в порядке выполнения — 'test:complete'.
Event: 'test:plan'¶
data<Object>column<number>| undefined Номер столбца объявления теста илиundefined, если тест запущен из REPL.file<string>| undefined Путь к тестовому файлу;undefined, если тест запущен из REPL.line<number>| undefined Номер строки объявления теста илиundefined, если тест запущен из REPL.nesting<number>Уровень вложенности теста.count<number>Число выполненных подтестов.
Генерируется после завершения всех подтестов данного теста. Порядок совпадает с порядком объявления тестов.
Event: 'test:start'¶
data<Object>column<number>| undefined Номер столбца объявления теста илиundefined, если тест запущен из REPL.file<string>| undefined Путь к тестовому файлу;undefined, если тест запущен из REPL.line<number>| undefined Номер строки объявления теста илиundefined, если тест запущен из REPL.name<string>Имя теста.nesting<number>Уровень вложенности теста.
Генерируется, когда тест начинает отчитываться о себе и подтестах. Порядок совпадает с порядком объявления тестов. Соответствующее событие в порядке выполнения — 'test:dequeue'.
Event: 'test:stderr'¶
data<Object>
Генерируется при записи выполняющегося теста в stderr. Только если передан флаг --test. Порядок в общем случае не совпадает с порядком объявления тестов.
Event: 'test:stdout'¶
data<Object>
Генерируется при записи выполняющегося теста в stdout. Только если передан флаг --test. Порядок в общем случае не совпадает с порядком объявления тестов.
Event: 'test:summary'¶
data<Object>counts<Object>Счётчики результатов прогона.cancelled<number>Число отменённых тестов.failed<number>Число проваленных тестов.passed<number>Число успешных тестов.skipped<number>Число пропущенных тестов.suites<number>Число выполненных наборов.tests<number>Число выполненных тестов без наборов.todo<number>Число тестов в статусе TODO.topLevel<number>Число тестов и наборов верхнего уровня.
duration_ms<number>Длительность прогона в миллисекундах.file<string>| undefined Путь к тестовому файлу, с которого получена сводка. Если сводка объединяет несколько файлов —undefined.success<boolean>Считается ли прогон успешным. При любой ошибке (провал теста, не выполнен порог покрытия и т. п.) —false.
Генерируется по завершении прогона. Содержит метрики для оценки успеха или провала. При изоляции тестов на уровне процесса событие 'test:summary' приходит для каждого файла и отдельно итоговая сводка.
Event: 'test:watch:drained'¶
Генерируется, когда в режиме watch в очереди больше нет тестов.
Event: 'test:watch:restarted'¶
Генерируется при перезапуске одного или нескольких тестов из‑за изменения файла в режиме watch.
getTestContext()¶
- Возвращает:
<TestContext>|<SuiteContext>| undefined
Возвращает TestContext или SuiteContext для текущего теста или набора, либо undefined вне теста/набора. Позволяет получить контекст из тела теста/набора или из асинхронных операций внутри них.
1 2 3 4 5 6 7 8 9 10 11 | |
Из теста возвращает TestContext. Из набора — SuiteContext.
Вне теста или набора (например на верхнем уровне модуля или в колбэке setTimeout после завершения) — undefined.
Внутри хука (before, beforeEach, after, afterEach) возвращается контекст теста или набора, к которому привязан хук.
Class: TestContext¶
В каждую функцию теста передаётся экземпляр TestContext для работы с раннером. Конструктор TestContext в API не экспортируется.
context.before([fn][, options])¶
fn<Function>|<AsyncFunction>Функция хука. Первый аргумент —TestContext. При колбэк-стиле второй аргумент — колбэк. По умолчанию: пустая функция.options<Object>Параметры хука:signal<AbortSignal>Позволяет прервать выполняющийся хук.timeout<number>Через столько миллисекунд хук считается проваленным. Если не задано, подтесты наследуют значение от родителя. По умолчанию:Infinity.
Создаёт хук, выполняемый перед подтестом текущего теста.
context.beforeEach([fn][, options])¶
fn<Function>|<AsyncFunction>Функция хука. Первый аргумент —TestContext. При колбэк-стиле второй аргумент — колбэк. По умолчанию: пустая функция.options<Object>Параметры хука:signal<AbortSignal>Позволяет прервать выполняющийся хук.timeout<number>Через столько миллисекунд хук считается проваленным. Если не задано, подтесты наследуют значение от родителя. По умолчанию:Infinity.
Создаёт хук перед каждым подтестом текущего теста.
1 2 3 4 5 6 7 8 | |
context.after([fn][, options])¶
fn<Function>|<AsyncFunction>Функция хука. Первый аргумент —TestContext. При колбэк-стиле второй аргумент — колбэк. По умолчанию: пустая функция.options<Object>Параметры хука:signal<AbortSignal>Позволяет прервать выполняющийся хук.timeout<number>Через столько миллисекунд хук считается проваленным. Если не задано, подтесты наследуют значение от родителя. По умолчанию:Infinity.
Создаёт хук после завершения текущего теста.
1 2 3 4 5 6 | |
context.afterEach([fn][, options])¶
fn<Function>|<AsyncFunction>Функция хука. Первый аргумент —TestContext. При колбэк-стиле второй аргумент — колбэк. По умолчанию: пустая функция.options<Object>Параметры хука:signal<AbortSignal>Позволяет прервать выполняющийся хук.timeout<number>Через столько миллисекунд хук считается проваленным. Если не задано, подтесты наследуют значение от родителя. По умолчанию:Infinity.
Создаёт хук после каждого подтеста текущего теста.
1 2 3 4 5 6 7 8 | |
context.assert¶
Объект с методами утверждения, привязанными к context. Здесь доступны функции верхнего уровня модуля node:assert для построения планов тестов.
1 2 3 4 | |
context.assert.fileSnapshot(value, path[, options])¶
value<any>Значение для сериализации в строку. Если Node.js запущен с--test-update-snapshots, сериализованное значение записывается вpath. Иначе оно сравнивается с содержимым существующего файла снимка.path<string>Файл, куда записывается сериализованноеvalue.options<Object>Необязательные параметры. Поддерживаются следующие свойства:serializers<Array>Массив синхронных функций сериализацииvalueв строку. В первую функцию передаётся толькоvalue; результат каждой передаётся следующей. После всех сериализаторов значение приводится к строке. По умолчанию: если сериализаторы не заданы, используются сериализаторы раннера по умолчанию.
Сериализует value и записывает в файл path.
1 2 3 4 5 6 | |
Отличия от context.assert.snapshot():
- Путь к файлу снимка задаётся явно.
- В одном файле снимка — одно значение.
- Раннер не выполняет дополнительного экранирования.
Это упрощает подсветку синтаксиса и подобные сценарии.
context.assert.snapshot(value[, options])¶
value<any>Значение для сериализации. При--test-update-snapshotsсериализованное значение записывается в файл снимка. Иначе сравнивается с соответствующим значением в существующем файле.options<Object>Необязательные параметры. Поддерживаются следующие свойства:serializers<Array>Массив синхронных сериализаторов (как вfileSnapshot). По умолчанию: сериализаторы раннера по умолчанию.
Утверждения для тестов со снимками.
1 2 3 4 5 6 7 8 9 10 11 12 | |
context.diagnostic(message)¶
message<string>Текст диагностики.
Пишет диагностику в вывод; данные появляются в конце результатов теста. Возвращаемого значения нет.
1 2 3 | |
context.filePath¶
Абсолютный путь к тестовому файлу, создавшему текущий тест. Если тесты подключаются из других модулей, возвращается путь корневого тестового файла.
context.fullName¶
Имя теста и всех предков через >.
context.name¶
Имя теста.
context.passed¶
- Тип:
<boolean>До выполнения теста —false, например в хукеbeforeEach.
Указывает, успешен ли тест.
context.error¶
- Тип:
<Error>| null
Причина провала теста/кейса; исходная ошибка в context.error.cause.
context.attempt¶
- Тип:
<number>
Номер попытки теста (с нуля: первая — 0, вторая — 1 и т. д.). Удобно с опцией --test-rerun-failures, чтобы знать текущую попытку.
context.workerId¶
- Тип:
<number>| undefined
Уникальный идентификатор воркера, выполняющего текущий тестовый файл. Берётся из NODE_TEST_WORKER_ID. При --test-isolation=process (по умолчанию) каждый файл в отдельном дочернем процессе с ID от 1 до N (N — число параллельных воркеров). При --test-isolation=none все тесты в одном процессе, идентификатор всегда 1. Вне контекста теста — undefined.
Свойство удобно для распределения ресурсов (соединения с БД, порты и т. д.) между параллельными файлами:
1 2 3 4 5 6 7 8 9 10 11 | |
context.plan(count[,options])¶
count<number>Ожидаемое число утверждений и подтестов.options<Object>Дополнительные параметры плана.wait<boolean>|<number>Поведение ожидания плана:true— ждать неограниченно, пока не выполнятся все утверждения и подтесты.false— проверка сразу после завершения функции теста, без ожидания отложенных утверждений и подтестов. Утверждения и подтесты, завершившиеся позже, в план не входят.- число — максимальное время ожидания в миллисекундах до тайм-аута при ожидании ожидаемых утверждений и подтестов. При тайм-ауте тест проваливается. По умолчанию:
false.
Задаёт ожидаемое число утверждений и подтестов в тесте. При несовпадении с фактом тест проваливается.
Примечание: чтобы утверждения учитывались планом, используйте
t.assert, а не прямой импортassert.
1 2 3 4 5 | |
В асинхронном коде plan помогает убедиться, что выполнено нужное число утверждений:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
С опцией wait можно задать, как долго тест ждёт ожидаемые утверждения. Например, ограничение по времени позволяет дождаться асинхронных утверждений в заданном окне:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
Примечание: отсчёт тайм-аута wait начинается только после завершения функции теста.
context.runOnly(shouldRunOnlyTests)¶
shouldRunOnlyTests<boolean>Выполнять ли только тесты сonly.
Если shouldRunOnlyTests истинно, контекст выполняет только тесты с опцией only; иначе — все. Без флага --test-only в командной строке вызов не действует.
1 2 3 4 5 6 7 8 | |
context.signal¶
- Тип:
<AbortSignal>
Позволяет прервать подзадачи теста при его отмене.
1 2 3 | |
context.skip([message])¶
message<string>Необязательное сообщение о пропуске.
Помечает тест в выводе как пропущенный. Если передана message, она попадает в отчёт. skip() не прерывает выполнение функции теста. Возвращаемого значения нет.
1 2 3 4 | |
context.todo([message])¶
message<string>Необязательное сообщениеTODO.
Добавляет в вывод директиву TODO. При переданной message она включается в отчёт. todo() не прерывает выполнение функции теста. Возвращаемого значения нет.
1 2 3 4 | |
context.test([name][, options][, fn])¶
name<string>Имя подтеста в отчёте. По умолчанию: свойствоnameуfnили'<anonymous>', если уfnнет имени.options<Object>Параметры подтеста. Поддерживаются свойства:concurrency<number>|<boolean>| null Если число — столько подтестов выполняется асинхронно (в одном потоке цикла событий). Еслиtrue— все подтесты параллельно. Еслиfalse— по одному за раз. Если не задано, подтесты наследуют от родителя. По умолчанию:null.only<boolean>Если истинно и контекст настроен наonly, подтест выполняется; иначе пропускается. По умолчанию:false.signal<AbortSignal>Прерывание выполняющегося подтеста.skip<boolean>|<string>Пропуск подтеста; строка — причина в отчёте. По умолчанию:false.todo<boolean>|<string>СтатусTODO; строка — пояснение в отчёте. По умолчанию:false.timeout<number>Тайм-аут подтеста в миллисекундах. Если не задано, подтесты наследуют от родителя. По умолчанию:Infinity.plan<number>Ожидаемое число утверждений и подтестов. При несовпадении с планом подтест проваливается. По умолчанию:undefined.
fn<Function>|<AsyncFunction>Функция подтеста; первый аргумент —TestContext; при колбэках второй — колбэк. По умолчанию: пустая функция.- Возвращает:
<Promise>Выполняется сundefinedпо завершении подтеста.
Создаёт подтесты внутри текущего теста; поведение как у test() верхнего уровня.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
context.waitFor(condition[, options])¶
condition<Function>|<AsyncFunction>Функция-проверка, вызываемая периодически до успешного завершения или истечения тайм-аута опроса. Успех — отсутствие исключения и отклонения промиса. Аргументов не принимает, может вернуть любое значение.options<Object>Необязательные параметры опроса:- Возвращает:
<Promise>Выполняется значением, возвращённымcondition.
Опрашивает condition, пока она не завершится успешно или не истечёт тайм-аут.
Class: SuiteContext¶
В каждую функцию набора передаётся экземпляр SuiteContext для работы с раннером. Конструктор SuiteContext в API не экспортируется.
context.filePath¶
Абсолютный путь к файлу, создавшему текущий набор. Если наборы подключаются из модулей, возвращается путь корневого тестового файла.
context.fullName¶
Имя набора и предков через >.
context.name¶
Имя набора.
context.signal¶
- Тип:
<AbortSignal>
Позволяет прервать подзадачи теста при его отмене.
context.passed¶
- Тип:
<boolean>
Указывает, прошли ли набор и все его подтесты.
context.attempt¶
- Тип:
<number>
Номер попытки набора (с нуля). Удобно с --test-rerun-failures, чтобы знать номер текущей попытки.
context.diagnostic(message)¶
message<string>Текст диагностики.
Выводит диагностическое сообщение, обычно для журналирования о наборе или его тестах.
1 2 3 | |
