Funcionalidades
- Configuração, transformadores, resolvedores e plugins do Vite
- Utilize a mesma configuração do seu aplicativo para rodar os testes!
- Modo de observação inteligente e instantâneo, como HMR para testes!
- Testes de componentes para Vue, React, Svelte, Lit, Marko e muito mais
- Suporte nativo a TypeScript / JSX
- ESM por padrão, com suporte a
top level await - Multi-threading de workers via Tinypool
- Suporte a benchmarking através de Tinybench
- Filtragem, timeouts, execução paralela para suítes e testes
- Suporte para Workspace
- Snapshot compatível com Jest
- Chai integrado para asserções + APIs compatíveis com Jest expect
- Tinyspy integrado para mocking
- happy-dom ou jsdom para mocking de DOM
- Modo Navegador para executar testes de componentes no navegador
- Cobertura de código via v8 ou istanbul
- Testes in-source estilo Rust
- Teste de Tipos via expect-type
- Suporte a Sharding
Configuração Compartilhada entre Teste, Desenvolvimento e Build
O Vitest utiliza a configuração, transformadores, resolvedores e plugins do Vite. Isso permite que você use a mesma configuração do seu aplicativo para executar os testes.
Saiba mais em Configurando Vitest.
Modo de Observação
$ vitestQuando você modifica seu código-fonte ou os arquivos de teste, o Vitest busca inteligentemente no grafo de módulos e executa novamente apenas os testes relacionados, assim como o HMR funciona no Vite!
O vitest inicia em watch mode por padrão no ambiente de desenvolvimento e em run mode no ambiente de CI (quando process.env.CI está presente) de forma inteligente. Você pode usar vitest watch ou vitest run para especificar explicitamente o modo desejado.
Inicie o Vitest com a flag --standalone para mantê-lo em execução em segundo plano. Ele não executará nenhum teste até que eles mudem. O Vitest não executará testes se o código-fonte for alterado até que o teste que importa esse código tenha sido executado.
Padrões Web Comuns Nativos
Suporte nativo a Módulos ES, TypeScript, JSX e PostCSS
Threads
Por padrão, o Vitest executa arquivos de teste em múltiplos processos, utilizando node:child_process via Tinypool (um fork leve de Piscina). Isso permite que os testes sejam executados simultaneamente. Se você quiser acelerar ainda mais sua suíte de testes, considere habilitar --pool=threads para executar testes usando node:worker_threads (cuidado que alguns pacotes podem não funcionar com esta configuração).
Para executar testes em um único thread ou processo, consulte poolOptions.
O Vitest também isola o ambiente de cada arquivo para que as alterações de ambiente em um arquivo não afetem outros. O isolamento pode ser desabilitado passando --no-isolate via CLI (sacrificando a correção em prol do desempenho de execução).
Filtragem de Testes
O Vitest oferece muitas maneiras de filtrar os testes a serem executados, acelerando o processo e permitindo que você se concentre no desenvolvimento.
Saiba mais sobre Filtragem de Testes.
Executando Testes em Paralelo
Use .concurrent em testes para iniciá-los em paralelo.
import { describe, it } from 'vitest';
// Os dois testes marcados com concurrent serão iniciados em paralelo
describe('suite', () => {
it('serial test', async () => {
/* ... */
});
it.concurrent('concurrent test 1', async ({ expect }) => {
/* ... */
});
it.concurrent('concurrent test 2', async ({ expect }) => {
/* ... */
});
});Se você usar .concurrent em uma suíte, todos os testes nela serão iniciados em paralelo.
import { describe, it } from 'vitest';
// Todos os testes dentro desta suíte serão iniciados em paralelo
describe.concurrent('suite', () => {
it('concurrent test 1', async ({ expect }) => {
/* ... */
});
it('concurrent test 2', async ({ expect }) => {
/* ... */
});
it.concurrent('concurrent test 3', async ({ expect }) => {
/* ... */
});
});Você pode usar .skip, .only e .todo em suítes e testes concorrentes. Leia mais na Referência da API.
WARNING
Ao executar testes concorrentes, Snapshots e Asserções devem usar expect do Contexto de Teste local para garantir que o teste correto seja detectado.
Snapshot
Suporte a snapshot compatível com Jest.
import { expect, it } from 'vitest';
it('renders correctly', () => {
const result = render();
expect(result).toMatchSnapshot();
});Saiba mais em Snapshot.
Compatibilidade com Chai e Jest expect
Chai é integrado para asserções com APIs compatíveis com Jest expect.
Observe que, se você estiver usando bibliotecas de terceiros que adicionam matchers, definir test.globals como true fornecerá melhor compatibilidade.
Mocking
Tinyspy é integrado para mocking com APIs compatíveis com jest no objeto vi.
import { expect, vi } from 'vitest';
const fn = vi.fn();
fn('hello', 1);
expect(vi.isMockFunction(fn)).toBe(true);
expect(fn.mock.calls[0]).toEqual(['hello', 1]);
fn.mockImplementation((arg: string) => arg);
fn('world', 2);
expect(fn.mock.results[1].value).toBe('world');O Vitest suporta tanto happy-dom quanto jsdom para mocking de DOM e APIs de navegador. Eles não estão incluídos no Vitest, sendo necessário instalá-los separadamente:
$ npm i -D happy-dom
# ou
$ npm i -D jsdomDepois disso, altere a opção environment no seu arquivo de configuração:
// vitest.config.ts
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
environment: 'happy-dom', // ou 'jsdom', 'node'
},
});Saiba mais em Mocking.
Cobertura
O Vitest oferece suporte a cobertura de código nativa via v8 e cobertura de código instrumentada via istanbul.
{
"scripts": {
"test": "vitest",
"coverage": "vitest run --coverage"
}
}Saiba mais sobre Cobertura.
Testes In-Source
O Vitest também oferece uma maneira de executar testes dentro do seu código-fonte junto com a implementação, semelhante aos testes de módulo do Rust.
Isso permite que os testes compartilhem o mesmo escopo das implementações e testem estados privados sem a necessidade de exportá-los. Enquanto isso, também aproxima o ciclo de feedback para o desenvolvimento.
// src/index.ts
// a implementação
export function add(...args: number[]): number {
return args.reduce((a, b) => a + b, 0);
}
// suítes de teste in-source
if (import.meta.vitest) {
const { it, expect } = import.meta.vitest;
it('add', () => {
expect(add()).toBe(0);
expect(add(1)).toBe(1);
expect(add(1, 2, 3)).toBe(6);
});
}Saiba mais sobre Testes in-source.
Benchmarking Experimental
Você pode executar testes de benchmark usando a função bench do Tinybench para comparar resultados de desempenho.
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;
});
});
});Teste de Tipos Experimental
Você pode escrever testes para detectar regressões de tipo. O Vitest vem com o pacote expect-type para fornecer uma API semelhante e fácil de entender.
import { assertType, expectTypeOf, test } from 'vitest';
import { mount } from './mount.js';
test('my types work properly', () => {
expectTypeOf(mount).toBeFunction();
expectTypeOf(mount).parameter(0).toMatchTypeOf<{ name: string }>();
// @ts-expect-error name is a string
assertType(mount({ name: 42 }));
});Sharding
Execute testes em máquinas diferentes utilizando as flags --shard e --reporter=blob. Todos os resultados de teste e cobertura podem ser mesclados no final do seu pipeline de CI usando o comando --merge-reports:
vitest --shard=1/2 --reporter=blob
vitest --shard=2/2 --reporter=blob
vitest --merge-reports --reporter=junit --coverage.reporter=textConsulte Melhorando o Desempenho | Sharding para mais informações.
Variáveis de Ambiente
O Vitest carrega exclusivamente variáveis de ambiente prefixadas com VITE_ de arquivos .env para manter a compatibilidade com testes relacionados ao frontend, aderindo à convenção estabelecida do Vite. No entanto, para carregar todas as variáveis de ambiente de arquivos .env, você pode usar o método loadEnv importado do vite:
import { loadEnv } from 'vite';
import { defineConfig } from 'vitest/config';
export default defineConfig(({ mode }) => ({
test: {
// mode define qual arquivo ".env.{mode}" escolher, se existir
env: loadEnv(mode, process.cwd(), ''),
},
}));