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
$ vitest
Quando 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 jsdom
Depois 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=text
Consulte 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(), ''),
},
}));