Referência da API de Teste
Os seguintes tipos são usados nas assinaturas de tipo abaixo
type Awaitable<T> = T | PromiseLike<T>;
type TestFunction = () => Awaitable<void>;
interface TestOptions {
/**
* Falhará o teste se demorar muito para executar
*/
timeout?: number;
/**
* Tentará executar o teste um número específico de vezes se falhar
*
* @default 0
*/
retry?: number;
/**
* Repetirá o mesmo teste várias vezes, mesmo que falhe a cada vez
* Se você tiver a opção "retry" e ela falhar, usará cada tentativa em cada ciclo
* Útil para depurar falhas aleatórias
*
* @default 0
*/
repeats?: number;
}Quando uma função de teste retorna uma promise, o executor aguardará até que ela seja resolvida para coletar as expectativas assíncronas. Se a promise for rejeitada, o teste falhará.
TIP
No Jest, TestFunction também pode ser do tipo (done: DoneCallback) => void. Se esta forma for usada, o teste não será concluído até que done seja chamado. Você pode conseguir o mesmo usando uma função async, veja a seção Guia de Migração Done Callback.
test
Tipo:
(name: string | Function, fn: TestFunction, timeout?: number | TestOptions) => voidAlias:
ittestdefine um conjunto de expectativas relacionadas. Ele recebe o nome do teste e uma função que contém as expectativas a serem testadas.Opcionalmente, você pode fornecer um timeout (em milissegundos) para especificar quanto tempo esperar antes de terminar. O padrão é 5 segundos e pode ser configurado globalmente com testTimeout
tsimport { expect, test } from 'vitest'; test('should work as expected', () => { expect(Math.sqrt(4)).toBe(2); });
test.extend
Tipo:
<T extends Record<string, any>>(fixtures: Fixtures<T>): TestAPI<ExtraContext & T>Alias:
it.extendVersion: Vitest 0.32.3
Use
test.extendpara estender o contexto de teste com fixtures personalizadas (dados/ambiente de teste). Isso retornará um novotestque também é extensível, permitindo que você componha mais fixtures ou substitua as existentes, estendendo-o conforme necessário. Veja Estender Contexto de Teste para mais informações.tsimport { 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
Tipo:
(name: string | Function, fn: TestFunction, timeout?: number | TestOptions) => voidAlias:
it.skipSe você deseja ignorar a execução de certos testes, mas não quer remover o código por algum motivo, use
test.skippara evitar sua execução.tsimport { assert, test } from 'vitest'; test.skip('skipped test', () => { // Teste ignorado, sem erro assert.equal(Math.sqrt(4), 3); });Você também pode ignorar o teste chamando
skipem seu contexto dinamicamente:tsimport { assert, test } from 'vitest'; test('skipped test', context => { context.skip(); // Teste ignorado, sem erro assert.equal(Math.sqrt(4), 3); });
test.skipIf
Tipo:
(condition: any) => TestAlias:
it.skipIfEm alguns cenários, você pode executar testes repetidamente em ambientes diferentes, e alguns testes podem ser específicos para um ambiente. Em vez de usar
ifpara condicionar o código do teste, usetest.skipIfpara ignorar o teste quando a condição for verdadeira.tsimport { assert, test } from 'vitest'; const isDev = process.env.NODE_ENV === 'development'; test.skipIf(isDev)('prod only test', () => { // este teste só é executado em produção });
WARNING
Você não pode usar esta sintaxe ao usar o Vitest como verificador de tipo.
test.runIf
Tipo:
(condition: any) => TestAlias:
it.runIfInverso de test.skipIf.
tsimport { assert, test } from 'vitest'; const isDev = process.env.NODE_ENV === 'development'; test.runIf(isDev)('dev only test', () => { // este teste só é executado em desenvolvimento });
WARNING
Você não pode usar esta sintaxe ao usar o Vitest como verificador de tipo.
test.only
Tipo:
(name: string | Function, fn: TestFunction, timeout?: number) => voidAlias:
it.onlyUse
test.onlypara executar apenas testes específicos em um conjunto. Isso é útil para depuração.Opcionalmente, você pode fornecer um timeout (em milissegundos) para especificar quanto tempo esperar antes de terminar. O padrão é 5 segundos e pode ser configurado globalmente com testTimeout.
tsimport { assert, test } from 'vitest'; test.only('test', () => { // Apenas este teste (e outros marcados com only) são executados assert.equal(Math.sqrt(4), 2); });Às vezes, é muito útil executar testes
onlyem um determinado arquivo, ignorando todos os outros testes de todo o conjunto de testes, que poluem a saída.Para fazer isso, execute
vitestcom o arquivo específico contendo os testes em questão.# vitest interesting.test.ts
test.concurrent
Tipo:
(name: string | Function, fn: TestFunction, timeout?: number) => voidAlias:
it.concurrenttest.concurrentmarca testes consecutivos para serem executados em paralelo. Ele recebe o nome do teste, uma função assíncrona com os testes a serem executados e um timeout opcional (em milissegundos).tsimport { describe, test } from 'vitest'; // Os dois testes marcados com concurrent serão executados em paralelo describe('suite', () => { test('serial test', async () => { /* ... */ }); test.concurrent('concurrent test 1', async () => { /* ... */ }); test.concurrent('concurrent test 2', async () => { /* ... */ }); });test.skip,test.onlyetest.todofuncionam com testes concorrentes. Todas as seguintes combinações são válidas:tstest.concurrent(/* ... */); test.skip.concurrent(/* ... */); // ou test.concurrent.skip(/* ... */) test.only.concurrent(/* ... */); // ou test.concurrent.only(/* ... */) test.todo.concurrent(/* ... */); // ou test.concurrent.todo(/* ... */)Ao executar testes paralelos, Snapshots e asserções devem usar o
expectdo Contexto de Teste local para garantir que o teste correto seja detectado.tstest.concurrent('test 1', async ({ expect }) => { expect(foo).toMatchSnapshot(); }); test.concurrent('test 2', async ({ expect }) => { expect(foo).toMatchSnapshot(); });
WARNING
Você não pode usar esta sintaxe ao usar o Vitest como verificador de tipo.
test.todo
Tipo:
(name: string | Function) => voidAlias:
it.todoUse
test.todopara criar stubs (testes pendentes) para testes que serão implementados posteriormente. Uma entrada será mostrada no relatório para os testes, para que você saiba quantos testes ainda precisa implementar.ts// Uma entrada será mostrada no relatório para este teste test.todo('unimplemented test');
test.fails
Tipo:
(name: string | Function, fn: TestFunction, timeout?: number) => voidAlias:
it.failsUse
test.failspara indicar que uma asserção falhará explicitamente.tsimport { expect, test } from 'vitest'; function myAsyncFunc() { return new Promise(resolve => resolve(1)); } test.fails('fail test', async () => { await expect(myAsyncFunc()).rejects.toBe(1); });
WARNING
Você não pode usar esta sintaxe ao usar o Vitest como verificador de tipo.
test.each
Tipo:
(cases: ReadonlyArray<T>, ...args: any[]) => voidAlias:
it.eachUse
test.eachquando você precisa executar o mesmo teste com diferentes conjuntos de dados. Você pode injetar parâmetros com formatação printf no nome do teste, na ordem dos parâmetros da função de teste.%s: string%d: number%i: integer%f: floating point value (número de ponto flutuante)%j: json%o: object%#: index of the test case (índice do caso de teste)%%: single percent sign ('%') (sinal de porcentagem)
tstest.each([ [1, 1, 2], [1, 2, 3], [2, 1, 3], ])('add(%i, %i) -> %i', (a, b, expected) => { expect(a + b).toBe(expected); }); // isso resultará em // ✓ add(1, 1) -> 2 // ✓ add(1, 2) -> 3 // ✓ add(2, 1) -> 3Você também pode acessar propriedades de objeto com o prefixo
$, se estiver usando objetos como argumentos:tstest.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); }); // isso resultará em // ✓ add(1, 1) -> 2 // ✓ add(1, 2) -> 3 // ✓ add(2, 1) -> 3Você também pode acessar atributos de objeto com
., se estiver usando objetos como argumentos:tstest.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); }); // isso resultará em // ✓ add(1, b) -> 1b // ✓ add(2, b) -> 2b // ✓ add(3, b) -> 3bA partir do Vitest 0.25.3, você também pode usar tabelas de template strings.
- A primeira linha deve ser os nomes das colunas, separados por
|; - Uma ou mais linhas subsequentes de dados fornecidas como expressões literais de template usando a sintaxe
${value}.
tstest.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); });Se você quiser ter acesso ao
TestContext, usedescribe.eachcom um único teste.
TIP
O Vitest processa $values com o método format do chai. Se o valor estiver muito truncado, você pode aumentar chaiConfig.truncateThreshold no seu arquivo de configuração.
WARNING
Você não pode usar esta sintaxe ao usar o Vitest como verificador de tipo.
bench
- Tipo:
(name: string | Function, fn: BenchFunction, options?: BenchOptions) => void
bench define um benchmark (teste de desempenho). No Vitest, um benchmark é uma função que define uma série de operações. O Vitest executa essa função várias vezes para exibir diferentes resultados de desempenho.
O Vitest usa a biblioteca tinybench internamente, herdando todas as suas opções, que podem ser usadas como um terceiro argumento.
import { bench } from 'vitest';
bench(
'normal sorting',
() => {
const x = [1, 5, 4, 2, 3];
x.sort((a, b) => {
return a - b;
});
},
{ time: 1000 }
);export interface Options {
/**
* tempo necessário para executar uma tarefa de benchmark (milissegundos)
* @default 500
*/
time?: number;
/**
* número de vezes que uma tarefa deve ser executada, mesmo que a opção de tempo tenha terminado
* @default 10
*/
iterations?: number;
/**
* função para obter o timestamp atual em milissegundos
*/
now?: () => number;
/**
* Um AbortSignal para abortar o benchmark
*/
signal?: AbortSignal;
/**
* tempo de warmup (milissegundos)
* @default 100ms
*/
warmupTime?: number;
/**
* iterações de warmup
* @default 5
*/
warmupIterations?: number;
/**
* função de setup para executar antes de cada tarefa de benchmark (ciclo)
*/
setup?: Hook;
/**
* função de teardown para executar após cada tarefa de benchmark (ciclo)
*/
teardown?: Hook;
}bench.skip
- Tipo:
(name: string | Function, fn: BenchFunction, options?: BenchOptions) => void
Você pode usar a sintaxe bench.skip para evitar a execução de certos benchmarks.
import { bench } from 'vitest';
bench.skip('normal sorting', () => {
const x = [1, 5, 4, 2, 3];
x.sort((a, b) => {
return a - b;
});
});bench.only
- Tipo:
(name: string | Function, fn: BenchFunction, options?: BenchOptions) => void
Use bench.only para executar apenas certos benchmarks em um determinado conjunto. Isso é útil ao depurar.
import { bench } from 'vitest';
bench.only('normal sorting', () => {
const x = [1, 5, 4, 2, 3];
x.sort((a, b) => {
return a - b;
});
});bench.todo
- Tipo:
(name: string | Function) => void
Use bench.todo para criar stubs (testes pendentes) para benchmarks que serão implementados posteriormente.
import { bench } from 'vitest';
bench.todo('unimplemented test');describe
Quando você usa test ou bench no nível superior do arquivo, eles são coletados como parte do suite implícito. Ao usar describe, você pode definir um novo suite no contexto atual, como um agrupamento de testes ou benchmarks relacionados, e outros suites aninhados. Um suite permite organizar seus testes e benchmarks, tornando os relatórios mais claros e fáceis de entender.
// 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;
});
});
});Você também pode aninhar blocos describe caso precise de uma hierarquia mais complexa para seus testes ou benchmarks.
import { describe, expect, test } from 'vitest';
function numberToCurrency(value) {
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
Tipo:
(name: string | Function, fn: TestFunction, options?: number | TestOptions) => voidUse
describe.skipem um suite para impedir a execução de um blocodescribeespecífico.tsimport { assert, describe, test } from 'vitest'; describe.skip('skipped suite', () => { test('sqrt', () => { // Suite ignorado, sem erro assert.equal(Math.sqrt(4), 3); }); });
describe.skipIf
Tipo:
(condition: any) => voidEm alguns casos, você pode executar suites em diferentes ambientes, e alguns deles podem ser específicos para um determinado ambiente. Em vez de envolver o suite com uma declaração
if, você pode usardescribe.skipIfpara ignorar o suite sempre que a condição for avaliada como verdadeira (truthy).tsimport { describe, test } from 'vitest'; const isDev = process.env.NODE_ENV === 'development'; describe.skipIf(isDev)('prod only test', () => { // este teste só é executado em produção });
WARNING
Você não pode usar esta sintaxe ao usar o Vitest como verificador de tipo.
describe.only
Tipo:
(name: string | Function, fn: TestFunction, options?: number | TestOptions) => voidUse
describe.onlypara executar apenas suites específicos.ts// Apenas este suite (e outros marcados com only) são executados describe.only('suite', () => { test('sqrt', () => { assert.equal(Math.sqrt(4), 3); }); }); describe('other suite', () => { // ... será ignorado });Às vezes, é útil executar testes marcados com
onlyem um arquivo específico, ignorando todos os outros testes do suite de testes, que podem poluir a saída.Para fazer isso, execute
vitestcom o arquivo específico contendo os testes desejados.# vitest interesting.test.ts
describe.concurrent
Tipo:
(name: string | Function, fn: TestFunction, options?: number | TestOptions) => voiddescribe.concurrentem um suite marca todos os testes dentro dele para serem executados concorrentemente (em paralelo).ts// Todos os testes dentro deste suite serão executados em paralelo describe.concurrent('suite', () => { test('concurrent test 1', async () => { /* ... */ }); test('concurrent test 2', async () => { /* ... */ }); test.concurrent('concurrent test 3', async () => { /* ... */ }); });.skip,.onlye.todofuncionam com suites concorrentes. Todas as combinações a seguir são válidas:tsdescribe.concurrent(/* ... */); describe.skip.concurrent(/* ... */); // or describe.concurrent.skip(/* ... */) describe.only.concurrent(/* ... */); // or describe.concurrent.only(/* ... */) describe.todo.concurrent(/* ... */); // or describe.concurrent.todo(/* ... */)
Ao executar testes concorrentes, snapshots e assertions devem usar expect do Contexto de Teste local para garantir que o teste correto seja detectado.
describe.concurrent('suite', () => {
test('concurrent test 1', async ({ expect }) => {
expect(foo).toMatchSnapshot();
});
test('concurrent test 2', async ({ expect }) => {
expect(foo).toMatchSnapshot();
});
});WARNING
Você não pode usar esta sintaxe ao usar o Vitest como verificador de tipo.
describe.sequential
Tipo:
(name: string | Function, fn: TestFunction, options?: number | TestOptions) => voiddescribe.sequentialem um suite marca todos os testes como sequenciais. Isso é útil se você deseja executar testes sequencialmente dentro de um blocodescribe.concurrentou ao usar a opção de linha de comando--sequence.concurrent.tsdescribe.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
Tipo:
(name: string | Function, fn: TestFunction, options?: number | TestOptions) => voidO Vitest oferece uma maneira de executar todos os testes em ordem aleatória por meio da flag da CLI
--sequence.shuffleou da opção de configuraçãosequence.shuffle. No entanto, se você quiser que apenas uma parte do seu suite de testes execute os testes em ordem aleatória, você pode marcá-lo com este método.tsdescribe.shuffle('suite', () => { test('random test 1', async () => { /* ... */ }); test('random test 2', async () => { /* ... */ }); test('random test 3', async () => { /* ... */ }); }); // a ordem depende da opção sequence.seed na configuração (Date.now() por padrão)
.skip, .only e .todo funcionam com suites aleatórios.
WARNING
Você não pode usar esta sintaxe ao usar o Vitest como verificador de tipo.
describe.todo
Tipo:
(name: string | Function) => voidUse
describe.todopara criar stubs de suites que serão implementados posteriormente. Uma entrada será mostrada no relatório para esses testes, permitindo que você saiba quantos testes ainda precisam ser implementados.ts// Uma entrada será mostrada no relatório para este suite describe.todo('unimplemented suite');
describe.each
Tipo:
(cases: ReadonlyArray<T>, ...args: any[]): (name: string | Function, fn: (...args: T[]) => void, options?: number | TestOptions) => voidUse
describe.eachse você tiver vários testes que dependem dos mesmos dados.tsdescribe.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); }); });A partir do Vitest 0.25.3, você também pode usar a tabela de template literal.
- A primeira linha deve conter os nomes das colunas, separados por
|; - Uma ou mais linhas subsequentes de dados fornecidas como expressões literais de modelo usando a sintaxe
${value}.
tsdescribe.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); }); });- A primeira linha deve conter os nomes das colunas, separados por
WARNING
Você não pode usar esta sintaxe ao usar o Vitest como verificador de tipo.
Setup and Teardown
Essas funções permitem que você se conecte ao ciclo de vida dos testes, evitando a repetição de código para configuração e limpeza. Elas se aplicam ao contexto atual: o arquivo, se forem usadas no nível superior, ou o suite atual, se estiverem dentro de um bloco describe. Esses hooks não são chamados quando você está executando o Vitest como um verificador de tipo.
beforeEach
Tipo:
beforeEach(fn: () => Awaitable<void>, timeout?: number)Registre um callback a ser chamado antes da execução de cada teste no contexto atual. Se a função retornar uma Promise, o Vitest aguardará até que a Promise seja resolvida antes de executar o teste.
Opcionalmente, você pode passar um timeout (em milissegundos) definindo o tempo máximo de espera antes de terminar. O padrão é de 5 segundos.
tsimport { beforeEach } from 'vitest'; beforeEach(async () => { // Limpar mocks e adicionar alguns dados de teste após antes de cada execução de teste await stopMocking(); await addUser({ name: 'John' }); });Neste exemplo,
beforeEachgarante que o usuário seja adicionado antes de cada teste.A partir do Vitest v0.10.0,
beforeEachtambém aceita uma função de limpeza opcional (equivalente aafterEach).tsimport { beforeEach } from 'vitest'; beforeEach(async () => { // chamado uma vez antes de cada execução de teste await prepareSomething(); // função de limpeza, chamada uma vez após cada execução de teste return async () => { await resetSomething(); }; });
afterEach
Tipo:
afterEach(fn: () => Awaitable<void>, timeout?: number)Registre um callback a ser chamado após a conclusão de cada teste no contexto atual. Se a função retornar uma Promise, o Vitest aguardará até que a Promise seja resolvida antes de continuar.
Opcionalmente, você pode fornecer um timeout (em milissegundos) para especificar o tempo máximo de espera antes de terminar. O padrão é de 5 segundos.
tsimport { afterEach } from 'vitest'; afterEach(async () => { await clearTestingData(); // limpar dados de teste após cada execução de teste });Neste exemplo,
afterEachgarante que os dados de teste sejam limpos após cada execução de teste.
beforeAll
Tipo:
beforeAll(fn: () => Awaitable<void>, timeout?: number)Registre um callback a ser chamado uma vez antes de começar a executar todos os testes no contexto atual. Se a função retornar uma Promise, o Vitest aguardará até que a Promise seja resolvida antes de executar os testes.
Opcionalmente, você pode fornecer um timeout (em milissegundos) para especificar o tempo máximo de espera antes de terminar. O padrão é de 5 segundos.
tsimport { beforeAll } from 'vitest'; beforeAll(async () => { await startMocking(); // chamado uma vez antes de todos os testes serem executados });Neste exemplo,
beforeAllgarante que os dados de mock sejam configurados antes da execução dos testes.A partir do Vitest v0.10.0,
beforeAlltambém aceita uma função de limpeza opcional (equivalente aafterAll).tsimport { beforeAll } from 'vitest'; beforeAll(async () => { // chamado uma vez antes de todos os testes serem executados await startMocking(); // função de limpeza, chamada uma vez após todos os testes serem executados return async () => { await stopMocking(); }; });
afterAll
Tipo:
afterAll(fn: () => Awaitable<void>, timeout?: number)Registre um callback a ser chamado uma vez após a execução de todos os testes no contexto atual. Se a função retornar uma Promise, o Vitest aguardará até que a Promise seja resolvida antes de continuar.
Opcionalmente, você pode fornecer um timeout (em milissegundos) para especificar o tempo máximo de espera antes de terminar. O padrão é de 5 segundos.
tsimport { afterAll } from 'vitest'; afterAll(async () => { await stopMocking(); // este método é chamado após a execução de todos os testes });Neste exemplo,
afterAllgarante que o métodostopMockingseja chamado após a execução de todos os testes.