Справочник по Test API
В приведенных ниже сигнатурах типов используются следующие типы:
type Awaitable<T> = T | PromiseLike<T>;
type TestFunction = () => Awaitable<void>;
interface TestOptions {
/**
* Тест завершится с ошибкой, если время его выполнения превысит указанное значение.
*/
timeout?: number;
/**
* В случае неудачи тест будет повторен указанное количество раз.
*
* @default 0
*/
retry?: number;
/**
* Повторяет один и тот же тест несколько раз, даже если он каждый раз завершается с ошибкой.
* Если у вас есть опция "retry", и тест проваливается, каждая попытка повтора будет использована в каждом цикле.
* Полезно для отладки случайных сбоев.
*
* @default 0
*/
repeats?: number;
}Vitest 1.3.0 устаревшим использование опций в качестве последнего параметра. Вы увидите сообщение об устаревании до версии 2.0.0, когда этот синтаксис будет удален. Если вам нужно передать параметры, используйте второй аргумент функции test.
import { test } from 'vitest';
test('flaky test', () => {}, { retry: 3 });
test('flaky test', { retry: 3 }, () => {}); Когда тестовая функция возвращает promise, исполнитель будет ожидать его разрешения для сбора асинхронных ожиданий. Если promise отклонен, тест завершится с ошибкой.
TIP
В Jest TestFunction также может иметь тип (done: DoneCallback) => void. Если используется эта форма, тест не будет завершен до тех пор, пока не будет вызван done. Вы можете добиться того же, используя async функцию, см. раздел Руководства по миграции Callback Done.
Начиная с Vitest 1.3.0, большинство опций поддерживают как точечную нотацию, так и объектный синтаксис, что позволяет вам использовать любой стиль, который вы предпочитаете.
import { test } from 'vitest';
test.skip('skipped test', () => {
// some logic that fails right now
});import { test } from 'vitest';
test('skipped test', { skip: true }, () => {
// some logic that fails right now
});test
- Псевдоним:
it
test определяет набор связанных утверждений. Он принимает имя теста и функцию, содержащую утверждения для проверки.
При необходимости вы можете указать тайм-аут (в миллисекундах), чтобы ограничить время ожидания завершения теста. Значение по умолчанию — 5 секунд, и его можно настроить глобально с помощью testTimeout.
import { expect, test } from 'vitest';
test('должен работать как ожидается', () => {
expect(Math.sqrt(4)).toBe(2);
});test.extend 0.32.3+
- Псевдоним:
it.extend
Используйте test.extend, чтобы расширить контекст теста пользовательскими фикстурами. Это вернет новый test, который также можно расширить. Это позволяет добавлять новые фикстуры или переопределять существующие. См. Расширение контекста теста для получения дополнительной информации.
import { expect, test } from 'vitest';
const todos = [];
const archive = [];
const myTest = test.extend({
todos: async ({ task }, use) => {
todos.push(1, 2, 3);
await use(todos);
todos.length = 0;
},
archive,
});
myTest('add item', ({ todos }) => {
expect(todos.length).toBe(3);
todos.push(4);
expect(todos.length).toBe(4);
});test.skip
- Псевдоним:
it.skip
Если вы хотите пропустить выполнение определенных тестов, но не хотите удалять код, вы можете использовать test.skip, чтобы исключить их из выполнения.
import { assert, test } from 'vitest';
test.skip('пропущенный тест', () => {
// Test skipped, no error
assert.equal(Math.sqrt(4), 3);
});Вы также можете пропустить тест динамически, вызвав skip в его контексте:
import { assert, test } from 'vitest';
test('пропущенный тест', context => {
context.skip();
// Test skipped, no error
assert.equal(Math.sqrt(4), 3);
});test.skipIf
- Псевдоним:
it.skipIf
В некоторых случаях вам может потребоваться запускать тесты в разных окружениях, и некоторые тесты могут быть специфичными для определенной среды. Вместо того, чтобы оборачивать тестовый код в if, вы можете использовать test.skipIf, чтобы пропустить тест, если условие истинно.
import { assert, test } from 'vitest';
const isDev = process.env.NODE_ENV === 'development';
test.skipIf(isDev)('тест только для prod', () => {
// this test only runs in production
});WARNING
Вы не можете использовать этот синтаксис, если Vitest используется для проверки типов.
test.runIf
- Псевдоним:
it.runIf
Противоположность test.skipIf.
import { assert, test } from 'vitest';
const isDev = process.env.NODE_ENV === 'development';
test.runIf(isDev)('тест только для dev', () => {
// this test only runs in development
});WARNING
Вы не можете использовать этот синтаксис, если Vitest используется для проверки типов.
test.only
- Псевдоним:
it.only
Используйте test.only, чтобы запускать только определенные тесты в данном наборе. Это полезно для отладки.
При необходимости вы можете указать тайм-аут (в миллисекундах), чтобы ограничить время ожидания завершения теста. Значение по умолчанию — 5 секунд, и его можно настроить глобально с помощью testTimeout.
import { assert, test } from 'vitest';
test.only('test', () => {
// Only this test (and others marked with only) are run
assert.equal(Math.sqrt(4), 2);
});Иногда бывает полезно запускать тесты only в определенном файле, игнорируя все остальные тесты из всего набора, которые могут "загрязнять" вывод.
Чтобы сделать это, запустите vitest с указанием конкретного файла, содержащего интересующие тесты.
# vitest interesting.test.tstest.concurrent
- Псевдоним:
it.concurrent
test.concurrent помечает тесты для параллельного выполнения. Он принимает имя теста, асинхронную функцию, содержащую тесты, и необязательный тайм-аут (в миллисекундах).
import { describe, test } from 'vitest';
// The two tests marked with concurrent will be run in parallel
describe('suite', () => {
test('serial test', async () => {
/* ... */
});
test.concurrent('concurrent test 1', async () => {
/* ... */
});
test.concurrent('concurrent test 2', async () => {
/* ... */
});
});test.skip, test.only и test.todo работают с параллельными тестами. Допустимы следующие комбинации:
test.concurrent(/* ... */);
test.skip.concurrent(/* ... */); // или test.concurrent.skip(/* ... */)
test.only.concurrent(/* ... */); // или test.concurrent.only(/* ... */)
test.todo.concurrent(/* ... */); // или test.concurrent.todo(/* ... */)При выполнении параллельных тестов, для работы со снимками (Snapshots) и утверждениями (Assertions) необходимо использовать expect из локального Контекста теста. Это необходимо для того, чтобы убедиться, что обнаружен правильный тест.
test.concurrent('test 1', async ({ expect }) => {
expect(foo).toMatchSnapshot();
});
test.concurrent('test 2', async ({ expect }) => {
expect(foo).toMatchSnapshot();
});WARNING
Вы не можете использовать этот синтаксис, если Vitest используется для проверки типов.
test.sequential
- Псевдоним:
it.sequential
test.sequential помечает тест как последовательный. Это полезно, если вы хотите запускать тесты последовательно в describe.concurrent или с помощью опции командной строки --sequence.concurrent.
import { describe, test } from 'vitest';
// ---cut---
// с опцией конфигурации { sequence: { concurrent: true } }
test('concurrent test 1', async () => {
/* ... */
});
test('concurrent test 2', async () => {
/* ... */
});
test.sequential('sequential test 1', async () => {
/* ... */
});
test.sequential('sequential test 2', async () => {
/* ... */
});
// внутри параллельного набора тестов
describe.concurrent('suite', () => {
test('concurrent test 1', async () => {
/* ... */
});
test('concurrent test 2', async () => {
/* ... */
});
test.sequential('sequential test 1', async () => {
/* ... */
});
test.sequential('sequential test 2', async () => {
/* ... */
});
});test.todo
- Псевдоним:
it.todo
Используйте test.todo, чтобы пометить тесты, которые будут реализованы позже. В отчете будет отображена запись для этих тестов, чтобы вы знали, сколько тестов вам еще предстоит реализовать.
// An entry will be shown in the report for this test
test.todo('нереализованный тест');test.fails
- Псевдоним:
it.fails
Используйте test.fails, чтобы указать, что тест должен завершиться с ошибкой.
import { expect, test } from 'vitest';
function myAsyncFunc() {
return new Promise(resolve => resolve(1));
}
test.fails('тест с ошибкой', async () => {
await expect(myAsyncFunc()).rejects.toBe(1);
});WARNING
Вы не можете использовать этот синтаксис, если Vitest используется для проверки типов.
test.each
- Псевдоним:
it.each
Используйте test.each, когда вам нужно запустить один и тот же тест с разными наборами входных данных. Вы можете использовать параметры форматирования printf в имени теста, в порядке следования параметров тестовой функции.
%s: string (строка)%d: number (число)%i: integer (целое число)%f: floating point value (значение с плавающей запятой)%j: json%o: object (объект)%#: index of the test case (индекс тестового случая)%%: single percent sign ('%') (одиночный знак процента ('%'))
import { expect, test } from 'vitest';
// ---cut---
test.each([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
])('add(%i, %i) -> %i', (a, b, expected) => {
expect(a + b).toBe(expected);
});
// это вернет
// ✓ add(1, 1) -> 2
// ✓ add(1, 2) -> 3
// ✓ add(2, 1) -> 3Вы также можете получить доступ к свойствам объекта с префиксом $, если вы используете объекты в качестве аргументов:
test.each([
{ a: 1, b: 1, expected: 2 },
{ a: 1, b: 2, expected: 3 },
{ a: 2, b: 1, expected: 3 },
])('add($a, $b) -> $expected', ({ a, b, expected }) => {
expect(a + b).toBe(expected);
});
// это вернет
// ✓ add(1, 1) -> 2
// ✓ add(1, 2) -> 3
// ✓ add(2, 1) -> 3Вы также можете получить доступ к атрибутам объекта с помощью ., если вы используете объекты в качестве аргументов:
test.each`
a | b | expected
${{ val: 1 }} | ${'b'} | ${'1b'}
${{ val: 2 }} | ${'b'} | ${'2b'}
${{ val: 3 }} | ${'b'} | ${'3b'}
`('add($a.val, $b) -> $expected', ({ a, b, expected }) => {
expect(a.val + b).toBe(expected);
});
// это вернет
// ✓ add(1, b) -> 1b
// ✓ add(2, b) -> 2b
// ✓ add(3, b) -> 3bНачиная с Vitest 0.25.3, вы также можете использовать табличный шаблон строки.
- Первая строка должна содержать имена столбцов, разделенные
|; - Одна или несколько последующих строк данных, предоставленных в виде выражений шаблонных литералов с использованием синтаксиса
${value}.
import { expect, test } from 'vitest';
// ---cut---
test.each`
a | b | expected
${1} | ${1} | ${2}
${'a'} | ${'b'} | ${'ab'}
${[]} | ${'b'} | ${'b'}
${{}} | ${'b'} | ${'[object Object]b'}
${{ asd: 1 }} | ${'b'} | ${'[object Object]b'}
`('returns $expected when $a is added $b', ({ a, b, expected }) => {
expect(a + b).toBe(expected);
});Если вам нужен доступ к TestContext, используйте describe.each с одним тестом.
TIP
Vitest обрабатывает $values с помощью метода format chai. Если значение усекается, вы можете увеличить chaiConfig.truncateThreshold в файле конфигурации.
WARNING
Вы не можете использовать этот синтаксис, если Vitest используется для проверки типов.
bench
- Тип:
(name: string | Function, fn: BenchFunction, options?: BenchOptions) => void
bench определяет бенчмарк (тест производительности). В Vitest бенчмарк — это функция, определяющая последовательность операций. Vitest запускает эту функцию несколько раз для получения различных показателей производительности.
Vitest использует библиотеку tinybench под капотом, наследуя все ее параметры, которые можно использовать в качестве третьего аргумента.
import { bench } from 'vitest';
bench(
'обычная сортировка',
() => {
const x = [1, 5, 4, 2, 3];
x.sort((a, b) => {
return a - b;
});
},
{ time: 1000 }
);export interface Options {
/**
* Время, необходимое для выполнения задачи бенчмарка (в миллисекундах).
* @default 500
*/
time?: number;
/**
* Количество раз, которое задача должна выполняться, даже если опция времени завершена.
* @default 10
*/
iterations?: number;
/**
* Функция для получения текущей временной метки в миллисекундах.
*/
now?: () => number;
/**
* AbortSignal для прерывания бенчмарка.
*/
signal?: AbortSignal;
/**
* Время на разогрев (в миллисекундах).
* @default 100ms
*/
warmupTime?: number;
/**
* Итерации прогрева.
* @default 5
*/
warmupIterations?: number;
/**
* Функция настройки для запуска перед каждой задачей бенчмарка (циклом).
*/
setup?: Hook;
/**
* Функция завершения для запуска после каждой задачи бенчмарка (цикла).
*/
teardown?: Hook;
}bench.skip
- Тип:
(name: string | Function, fn: BenchFunction, options?: BenchOptions) => void
Вы можете использовать синтаксис bench.skip, чтобы пропустить выполнение определенных бенчмарков.
import { bench } from 'vitest';
bench.skip('обычная сортировка', () => {
const x = [1, 5, 4, 2, 3];
x.sort((a, b) => {
return a - b;
});
});bench.only
- Тип:
(name: string | Function, fn: BenchFunction, options?: BenchOptions) => void
Используйте bench.only, чтобы запускать только определенные бенчмарки в данном наборе. Это полезно для отладки.
import { bench } from 'vitest';
bench.only('обычная сортировка', () => {
const x = [1, 5, 4, 2, 3];
x.sort((a, b) => {
return a - b;
});
});bench.todo
- Тип:
(name: string | Function) => void
Используйте bench.todo, чтобы пометить бенчмарки, которые будут реализованы позже.
import { bench } from 'vitest';
bench.todo('нереализованный тест');describe
Когда вы используете test или bench на верхнем уровне файла, они автоматически объединяются в неявный набор тестов (suite). Используя describe, вы можете определить новый набор в текущем контексте, представляющий собой группу связанных тестов, бенчмарков или других вложенных наборов. Набор позволяет организовать тесты и бенчмарки, делая отчеты более наглядными.
// basic.spec.ts
// organizing tests
import { describe, expect, test } from 'vitest';
const person = {
isActive: true,
age: 32,
};
describe('person', () => {
test('person is defined', () => {
expect(person).toBeDefined();
});
test('is active', () => {
expect(person.isActive).toBeTruthy();
});
test('age limit', () => {
expect(person.age).toBeLessThanOrEqual(32);
});
});// basic.bench.ts
// organizing benchmarks
import { bench, describe } from 'vitest';
describe('sort', () => {
bench('normal', () => {
const x = [1, 5, 4, 2, 3];
x.sort((a, b) => {
return a - b;
});
});
bench('reverse', () => {
const x = [1, 5, 4, 2, 3];
x.reverse().sort((a, b) => {
return a - b;
});
});
});Вы также можете вкладывать блоки describe, если у вас есть иерархическая структура тестов или бенчмарков:
import { describe, expect, test } from 'vitest';
function numberToCurrency(value: number | string) {
if (typeof value !== 'number') throw new Error('Value must be a number');
return value
.toFixed(2)
.toString()
.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
describe('numberToCurrency', () => {
describe('given an invalid number', () => {
test('composed of non-numbers to throw error', () => {
expect(() => numberToCurrency('abc')).toThrowError();
});
});
describe('given a valid number', () => {
test('returns the correct currency format', () => {
expect(numberToCurrency(10000)).toBe('10,000.00');
});
});
});describe.skip
- Alias:
suite.skip
Используйте describe.skip в тест-сьюте, чтобы пропустить выполнение определенного блока describe.
import { assert, describe, test } from 'vitest';
describe.skip('skipped suite', () => {
test('sqrt', () => {
// Suite skipped, no error
assert.equal(Math.sqrt(4), 3);
});
});describe.skipIf
- Alias:
suite.skipIf
В некоторых случаях вам может потребоваться запускать тест-сьюты несколько раз в разных окружениях, и некоторые из них могут быть специфичными для определенного окружения. Вместо того чтобы оборачивать тест-сьют в if, вы можете использовать describe.skipIf, чтобы пропустить набор, если условие истинно.
import { describe, test } from 'vitest';
const isDev = process.env.NODE_ENV === 'development';
describe.skipIf(isDev)('prod only test', () => {
// this test only runs in production
});WARNING
Вы не можете использовать этот синтаксис при использовании Vitest в качестве проверки типов.
describe.runIf
- Псевдоним:
suite.runIf
Противоположность describe.skipIf.
import { assert, describe, test } from 'vitest';
const isDev = process.env.NODE_ENV === 'development';
describe.runIf(isDev)('dev only test suite', () => {
// this test suite only runs in development
});WARNING
Вы не можете использовать этот синтаксис, когда используете Vitest как проверку типов.
describe.only
- Тип:
(name: string | Function, fn: TestFunction, options?: number | TestOptions) => void
Используйте describe.only, чтобы запускать только определенные тест-сьюты.
import { assert, describe, test } from 'vitest';
// ---cut---
// Only this suite (and others marked with only) are run
describe.only('suite', () => {
test('sqrt', () => {
assert.equal(Math.sqrt(4), 3);
});
});
describe('other suite', () => {
// ... will be skipped
});Иногда полезно запускать тесты only в конкретном файле, игнорируя все остальные тесты из всего набора, которые загромождают вывод.
Чтобы сделать это, запустите vitest с указанием конкретного файла, содержащего интересующие тесты.
# vitest interesting.test.tsdescribe.concurrent
- Alias:
suite.concurrent
describe.concurrent в тест-сьюте помечает все тесты внутри него как параллельные.
import { describe, test } from 'vitest';
// ---cut---
// All tests within this suite will be run in parallel
describe.concurrent('suite', () => {
test('concurrent test 1', async () => {
/* ... */
});
test('concurrent test 2', async () => {
/* ... */
});
test.concurrent('concurrent test 3', async () => {
/* ... */
});
});.skip, .only и .todo работают с параллельными тест-сьютами. Все следующие комбинации являются допустимыми:
describe.concurrent(/* ... */);
describe.skip.concurrent(/* ... */); // or describe.concurrent.skip(/* ... */)
describe.only.concurrent(/* ... */); // or describe.concurrent.only(/* ... */)
describe.todo.concurrent(/* ... */); // or describe.concurrent.todo(/* ... */)При запуске параллельных тестов, Снимки (Snapshots) и Утверждения (Assertions) должны использовать expect из локального Контекста Теста, чтобы убедиться, что обнаружен правильный тест.
describe.concurrent('suite', () => {
test('concurrent test 1', async ({ expect }) => {
expect(foo).toMatchSnapshot();
});
test('concurrent test 2', async ({ expect }) => {
expect(foo).toMatchSnapshot();
});
});WARNING
Вы не можете использовать этот синтаксис при использовании Vitest в качестве проверки типов.
describe.sequential
- Alias:
suite.sequential
describe.sequential в тест-сьюте помечает каждый тест как последовательный. Это полезно, если требуется запускать тесты последовательно внутри describe.concurrent или при использовании опции командной строки --sequence.concurrent.
import { describe, test } from 'vitest';
// ---cut---
describe.concurrent('suite', () => {
test('concurrent test 1', async () => {
/* ... */
});
test('concurrent test 2', async () => {
/* ... */
});
describe.sequential('', () => {
test('sequential test 1', async () => {
/* ... */
});
test('sequential test 2', async () => {
/* ... */
});
});
});describe.shuffle
- Alias:
suite.shuffle
Vitest предоставляет способ запускать все тесты в случайном порядке с помощью флага CLI --sequence.shuffle или опции конфигурации sequence.shuffle, но если вы хотите, чтобы только часть тестов в вашем наборе запускалась в случайном порядке, вы можете отметить этот набор с помощью этого флага.
import { describe, test } from 'vitest';
// ---cut---
describe.shuffle('suite', () => {
test('random test 1', async () => {
/* ... */
});
test('random test 2', async () => {
/* ... */
});
test('random test 3', async () => {
/* ... */
});
});
// order depends on sequence.seed option in config (Date.now() by default).skip, .only и .todo работают со случайными тест-сьютами.
WARNING
Вы не можете использовать этот синтаксис при использовании Vitest в качестве проверки типов.
describe.todo
- Alias:
suite.todo
Используйте describe.todo, чтобы создать заготовки для тест-сьютов, которые будут реализованы позже. В отчете будет отображаться запись для этих тестов, чтобы вы знали, сколько тестов вам еще нужно реализовать.
// An entry will be shown in the report for this suite
describe.todo('unimplemented suite');describe.each
- Alias:
suite.each
Используйте describe.each, если у вас есть несколько тестов, которые зависят от одних и тех же данных.
import { describe, expect, test } from 'vitest';
// ---cut---
describe.each([
{ a: 1, b: 1, expected: 2 },
{ a: 1, b: 2, expected: 3 },
{ a: 2, b: 1, expected: 3 },
])('describe object add($a, $b)', ({ a, b, expected }) => {
test(`returns ${expected}`, () => {
expect(a + b).toBe(expected);
});
test(`returned value not be greater than ${expected}`, () => {
expect(a + b).not.toBeGreaterThan(expected);
});
test(`returned value not be less than ${expected}`, () => {
expect(a + b).not.toBeLessThan(expected);
});
});Начиная с Vitest 0.25.3, вы также можете использовать шаблонные строки в виде таблицы.
- Первая строка должна содержать имена столбцов, разделенные символом
|; - Одна или несколько последующих строк данных, предоставленных в виде выражений строковых литералов с использованием синтаксиса
${value}.
import { describe, expect, test } from 'vitest';
// ---cut---
describe.each`
a | b | expected
${1} | ${1} | ${2}
${'a'} | ${'b'} | ${'ab'}
${[]} | ${'b'} | ${'b'}
${{}} | ${'b'} | ${'[object Object]b'}
${{ asd: 1 }} | ${'b'} | ${'[object Object]b'}
`('describe template string add($a, $b)', ({ a, b, expected }) => {
test(`returns ${expected}`, () => {
expect(a + b).toBe(expected);
});
});WARNING
Вы не можете использовать этот синтаксис при использовании Vitest в качестве проверки типов.
Setup and Teardown
Эти функции позволяют взаимодействовать с жизненным циклом тестов, чтобы избежать повторения кода инициализации и завершения. Они применяются к текущему контексту: к файлу, если они используются на верхнем уровне файла, или к текущему тест-сьюту, если они находятся внутри блока describe. Эти хуки не вызываются, когда вы запускаете Vitest в качестве проверки типов.
beforeEach
- Тип:
beforeEach(fn: () => Awaitable<void>, timeout?: number)
Регистрирует функцию обратного вызова (callback), которая будет вызвана перед каждым тестом в текущем контексте. Если функция возвращает промис, Vitest ждет, пока промис не будет разрешен, прежде чем запускать тест.
При необходимости вы можете передать тайм-аут (в миллисекундах), определяющий, как долго ждать перед завершением. Значение по умолчанию - 5 секунд.
import { beforeEach } from 'vitest';
beforeEach(async () => {
// Clear mocks and add some testing data after before each test run
await stopMocking();
await addUser({ name: 'John' });
});Здесь beforeEach гарантирует, что пользователь будет добавлен перед каждым тестом.
Начиная с Vitest v0.10.0, beforeEach также принимает необязательную функцию очистки (cleanup function) (эквивалентную afterEach).
import { beforeEach } from 'vitest';
beforeEach(async () => {
// called once before each test run
await prepareSomething();
// clean up function, called once after each test run
return async () => {
await resetSomething();
};
});afterEach
- Тип:
afterEach(fn: () => Awaitable<void>, timeout?: number)
Регистрирует обратный вызов, который будет вызван после завершения каждого теста в текущем контексте. Если функция возвращает промис, Vitest ждет, пока промис не будет разрешен, прежде чем продолжить.
При необходимости вы можете указать тайм-аут (в миллисекундах) для указания, как долго ждать перед завершением. Значение по умолчанию - 5 секунд.
import { afterEach } from 'vitest';
afterEach(async () => {
await clearTestingData(); // clear testing data after each test run
});Здесь afterEach гарантирует, что тестовые данные будут очищены после каждого запуска теста.
TIP
В Vitest 1.3.0 добавлен хук onTestFinished. Вы можете вызвать его во время выполнения теста, чтобы очистить любое состояние после завершения теста.
beforeAll
- Тип:
beforeAll(fn: () => Awaitable<void>, timeout?: number)
Регистрирует обратный вызов, который будет вызван один раз перед началом запуска всех тестов в текущем контексте. Если функция возвращает промис, Vitest ждет, пока промис не будет разрешен, прежде чем запускать тесты.
При необходимости вы можете указать тайм-аут (в миллисекундах) для указания, как долго ждать перед завершением. Значение по умолчанию - 5 секунд.
import { beforeAll } from 'vitest';
beforeAll(async () => {
await startMocking(); // called once before all tests run
});Здесь beforeAll гарантирует, что mock-данные будут настроены перед запуском тестов.
Начиная с Vitest v0.10.0, beforeAll также принимает необязательную функцию очистки (cleanup function) (эквивалентную afterAll).
import { beforeAll } from 'vitest';
beforeAll(async () => {
// called once before all tests run
await startMocking();
// clean up function, called once after all tests run
return async () => {
await stopMocking();
};
});afterAll
- Тип:
afterAll(fn: () => Awaitable<void>, timeout?: number)
Регистрирует обратный вызов, который будет вызван один раз после того, как все тесты будут запущены в текущем контексте. Если функция возвращает промис, Vitest ждет, пока промис не будет разрешен, прежде чем продолжить.
При необходимости вы можете указать тайм-аут (в миллисекундах) для указания, как долго ждать перед завершением. Значение по умолчанию - 5 секунд.
import { afterAll } from 'vitest';
afterAll(async () => {
await stopMocking(); // this method is called after all tests run
});Здесь afterAll гарантирует, что метод stopMocking будет вызван после запуска всех тестов.
Хуки Теста
Vitest предоставляет несколько хуков, которые можно вызывать во время выполнения теста для очистки состояния после завершения теста.
WARNING
Эти хуки вызовут ошибку, если они вызываются вне тела теста.
onTestFinished 1.3.0+
Этот хук всегда вызывается после завершения выполнения теста. Он вызывается после хуков afterEach, так как они могут повлиять на результат теста. Он получает объект TaskResult с текущим результатом теста.
import { onTestFinished, test } from 'vitest';
test('performs a query', () => {
const db = connectDb();
onTestFinished(() => db.close());
db.query('SELECT * FROM users');
});WARNING
Если вы запускаете тесты параллельно, вам всегда следует использовать хук onTestFinished из контекста теста, поскольку Vitest не отслеживает параллельные тесты в глобальных хуках:
import { test } from 'vitest';
test.concurrent('performs a query', ({ onTestFinished }) => {
const db = connectDb();
onTestFinished(() => db.close());
db.query('SELECT * FROM users');
});Этот хук особенно полезен при создании повторно используемой логики:
// Это может быть в отдельном файле
function getTestDb() {
const db = connectMockedDb();
onTestFinished(() => db.close());
return db;
}
test('performs a user query', async () => {
const db = getTestDb();
expect(await db.query('SELECT * from users').perform()).toEqual([]);
});
test('performs an organization query', async () => {
const db = getTestDb();
expect(await db.query('SELECT * from organizations').perform()).toEqual([]);
});TIP
Этот хук всегда вызывается в обратном порядке и не зависит от параметра sequence.hooks.
onTestFailed
Этот хук вызывается только после того, как тест завершился неудачей. Он вызывается после хуков afterEach, так как они могут повлиять на результат теста. Он получает объект TaskResult с текущим результатом теста. Этот хук полезен для отладки.
import { onTestFailed, test } from 'vitest';
test('performs a query', () => {
const db = connectDb();
onTestFailed(e => {
console.log(e.result.errors);
});
db.query('SELECT * FROM users');
});WARNING
Если вы запускаете тесты параллельно, вам всегда следует использовать хук onTestFailed из контекста теста, поскольку Vitest не отслеживает параллельные тесты в глобальных хуках:
import { test } from 'vitest';
test.concurrent('performs a query', ({ onTestFailed }) => {
const db = connectDb();
onTestFailed(result => {
console.log(result.errors);
});
db.query('SELECT * FROM users');
});