Test Runner
WARNING
Это расширенный API. Если вы просто запускаете тесты, вам, вероятно, это не понадобится. В основном он используется авторами библиотек.
Вы можете указать путь к вашему тестовому раннеру с помощью опции runner
в файле конфигурации. Этот файл должен содержать экспорт по умолчанию с классом, реализующим следующие методы:
export interface VitestRunner {
/**
* Вызывается первым, до начала сбора и запуска тестов.
*/
onBeforeCollect?: (paths: string[]) => unknown;
/**
* Вызывается после сбора тестов и перед "onBeforeRun".
*/
onCollected?: (files: File[]) => unknown;
/**
* Вызывается, когда тестовый раннер должен отменить следующие запуски тестов.
* Раннер должен отслеживать этот метод и помечать тесты и наборы как пропущенные в
* "onBeforeRunSuite" и "onBeforeRunTask" при вызове.
*/
onCancel?: (reason: CancelReason) => unknown;
/**
* Вызывается перед запуском отдельного теста. "result" еще отсутствует.
*/
onBeforeRunTask?: (test: TaskPopulated) => unknown;
/**
* Вызывается непосредственно перед выполнением функции теста. Уже содержит "result" с "state" и "startTime".
*/
onBeforeTryTask?: (
test: TaskPopulated,
options: { retry: number; repeats: number }
) => unknown;
/**
* Вызывается после установки result и state.
*/
onAfterRunTask?: (test: TaskPopulated) => unknown;
/**
* Вызывается сразу после выполнения функции теста. Новое состояние еще отсутствует. Не будет вызван, если функция теста выбросит исключение.
*/
onAfterTryTask?: (
test: TaskPopulated,
options: { retry: number; repeats: number }
) => unknown;
/**
* Вызывается перед запуском отдельного набора тестов. "result" еще отсутствует.
*/
onBeforeRunSuite?: (suite: Suite) => unknown;
/**
* Вызывается после запуска отдельного набора тестов. Содержит state и result.
*/
onAfterRunSuite?: (suite: Suite) => unknown;
/**
* Если определен, будет вызван вместо стандартного разделения и обработки набора тестов Vitest.
* Хуки "before" и "after" не будут игнорироваться.
*/
runSuite?: (suite: Suite) => Promise<void>;
/**
* Если определен, будет вызван вместо стандартной обработки Vitest. Полезно, если у вас есть собственная функция теста.
* Хуки "before" и "after" не будут игнорироваться.
*/
runTask?: (test: TaskPopulated) => Promise<void>;
/**
* Вызывается при обновлении задачи. Аналогично "onTaskUpdate" в репортере, но выполняется в том же потоке, что и тесты.
*/
onTaskUpdate?: (task: [string, TaskResult | undefined][]) => Promise<void>;
/**
* Вызывается перед запуском всех тестов в собранных путях.
*/
onBeforeRunFiles?: (files: File[]) => unknown;
/**
* Вызывается сразу после запуска всех тестов в собранных путях.
*/
onAfterRunFiles?: (files: File[]) => unknown;
/**
* Вызывается при определении нового контекста для теста. Полезно, если вы хотите добавить пользовательские свойства в контекст.
* Если вы хотите определить пользовательский контекст только с помощью раннера, рассмотрите возможность использования "beforeAll" в "setupFiles" вместо этого.
*
* Этот метод вызывается как для обработчиков "test", так и для обработчиков "custom".
*
* @see https://www.getbook.com/ru/book/vitest-1/advanced/runner#your-task-function
*/
extendTaskContext?: <T extends Test | Custom>(
context: TaskContext<T>
) => TaskContext<T>;
/**
* Вызывается при импорте определенных файлов. Может быть вызван в двух ситуациях: при сборе тестов и при импорте файлов настройки.
*/
importFile: (filepath: string, source: VitestRunnerImportSource) => unknown;
/**
* Общедоступная конфигурация.
*/
config: VitestRunnerConfig;
}
При инициализации этого класса Vitest передает свою конфигурацию, которую вы должны предоставить как свойство config
.
WARNING
Vitest также внедряет экземпляр ViteNodeRunner
как свойство __vitest_executor
. Вы можете использовать его для обработки файлов в методе importFile
(это поведение по умолчанию для TestRunner
и BenchmarkRunner
).
ViteNodeRunner
предоставляет метод executeId
, который используется для импорта тестовых файлов в среде, совместимой с Vite. Это означает, что он будет разрешать импорты и преобразовывать содержимое файла во время выполнения, чтобы Node мог его понять.
TIP
Поддержка моментальных снимков (Snapshot) и некоторые другие функции зависят от раннера. Чтобы сохранить эту функциональность, вы можете расширить свой раннер, унаследовав его от VitestTestRunner
, импортированного из vitest/runners
. Он также предоставляет BenchmarkNodeRunner
для расширения функциональности тестирования производительности.
Ваши задачи
Вы можете расширить систему задач Vitest своими задачами. Задача - это объект, который является частью набора тестов (suite). Он автоматически добавляется в текущий набор с помощью метода suite.task
:
// ./utils/custom.js
import { createTaskCollector, getCurrentSuite, setFn } from 'vitest/suite';
export { describe, beforeAll, afterAll } from 'vitest';
// эта функция будет вызвана на этапе сбора:
// не вызывайте здесь обработчик функции, добавьте его в задачи набора
// с помощью метода "getCurrentSuite().task()"
// примечание: createTaskCollector обеспечивает поддержку "todo"/"each"/...
export const myCustomTask = createTaskCollector(function (name, fn, timeout) {
getCurrentSuite().task(name, {
...this, // so "todo"/"skip"/... is tracked correctly
meta: {
customPropertyToDifferentiateTask: true,
},
handler: fn,
timeout,
});
});
// ./garden/tasks.test.js
import { afterAll, beforeAll, describe, myCustomTask } from '../custom.js';
import { gardener } from './gardener.js';
describe('take care of the garden', () => {
beforeAll(() => {
gardener.putWorkingClothes();
});
myCustomTask('weed the grass', () => {
gardener.weedTheGrass();
});
myCustomTask.todo('mow the lawn', () => {
gardener.mowerTheLawn();
});
myCustomTask('water flowers', () => {
gardener.waterFlowers();
});
afterAll(() => {
gardener.goHome();
});
});
vitest ./garden/tasks.test.js
WARNING
Если у вас нет пользовательского раннера или вы не определили метод runTest
, Vitest попытается получить задачу автоматически. Если вы не добавили функцию с помощью setFn
, произойдет ошибка.
TIP
Пользовательская система задач поддерживает хуки и контексты. Если вы хотите поддерживать цепочку методов (например, only
, skip
и ваши кастомные), вы можете импортировать createChainable
из vitest/suite
и обернуть свою функцию с его помощью. Вам нужно будет вызвать custom
как custom.call(this)
, если вы решите это сделать.