Test Runner

Vitest

Vitest é o test runner rápido e nativo do Vite. Ele reutiliza sua configuração de build, executa testes em paralelo e oferece APIs compatíveis com Jest com suporte de primeira classe para TypeScript.

intermediate13 min readUpdated 15 de set. de 2026
sum.test.ts
ts
// sum.test.ts
import { describe, it, expect } from "vitest";
import { sum } from "./sum";

describe("sum", () => {
  it("adds two numbers", () => {
    expect(sum(2, 3)).toBe(5);
  });

  it("handles negatives", () => {
    expect(sum(-1, -1)).toBe(-2);
  });
});
Alimentado por
Vite
API
Compatível com Jest
Linguagem
TypeScript nativo
Mocks
vi.fn, vi.mock
Watch mode
Instantâneo, Vite HMR
Browser mode
Testes em browser real

Por que importa

Por que o Vitest está vencendo

Rápido por padrão

Os testes rodam através do pipeline de transformação do Vite em workers paralelos, então o feedback é quase instantâneo, mesmo em suítes grandes.

Reutiliza sua configuração

Aliases, plugins e configurações de TypeScript vêm do mesmo config do Vite que seu app já usa, então não há nada para duplicar.

API compatível com Jest

describe, it, expect e os helpers de mocking espelham o Jest, o que torna a migração e o compartilhamento de conhecimento simples.

O panorama completo

As três ideias por trás do Vitest

Um pipeline nativo do Vite, uma API compatível com Jest e workers paralelos que mantêm o ciclo de feedback rápido.

O runner

Executar

Encontra arquivos de teste, executa-os em workers paralelos e reporta os resultados com uma UI clara e rápida.

A transformação

Build

Usa o Vite para compilar TypeScript, JSX e aliases exatamente como seu app faz.

Asserções e mocks

Verificar

expect, vi.fn e vi.mock cobrem asserções, spies e mocking de módulos.

Vitest em resumo

O núcleo do Vitest

describe e it

Agrupe testes relacionados e nomeie cada um pelo comportamento que ele verifica.

expect

Uma API rica de matchers para valores, objetos, erros e resultados assíncronos.

vi.fn e vi.spyOn

Crie mocks e spies para isolar o código sob teste.

vi.mock

Substitua um módulo inteiro por um mock, com hoisting acima dos imports.

Testes assíncronos

Aguarde promises e use expect.resolves ou expect.rejects.

Cobertura e UI

Relatórios de cobertura integrados e uma UI opcional no browser.

Uma breve historia

Um test runner construído para Vite

  1. 2021

    Vitest anunciado

    Anthony Fu apresenta um test runner nativo do Vite que reutiliza o pipeline existente.

    21
  2. 2022

    Base do Vitest 1.0

    Lançamentos rápidos adicionam cobertura, modo browser e compatibilidade com Jest.

    22
  3. 2024

    Vitest 1 e 2

    Uma API estável, projetos de workspace e modo browser amadurecem.

    24
  4. Hoje

    O padrão para Vite

    O test runner recomendado para Vite, Vue, Svelte, Solid e muitas configurações de React.

    Hoje

O guia completo

Vitest: Tudo que voce precisa saber

O que é o Vitest?

O Vitest é um test runner alimentado pelo Vite. Ele reutiliza a sua configuração existente do Vite — aliases, plugins, transformações de TypeScript e JSX — para que os testes sejam executados através do mesmo pipeline da sua aplicação. Essa base compartilhada é o motivo pelo qual ele inicia rápido e permanece rápido.

A API parecerá familiar se você já utilizou o Jest. describe, it, expect e os helpers de mocking funcionam da mesma maneira. O que muda é o motor por baixo: o Vitest executa testes em workers paralelos, monitora arquivos com o grafo de módulos do Vite e oferece suporte nativo ao TypeScript sem a necessidade de configurações extras.

Escrevendo seu primeiro teste

Um arquivo de teste importa de vitest e descreve o comportamento que ele verifica.

// sum.test.ts
import { describe, it, expect } from "vitest";
import { sum } from "./sum";

describe("sum", () => {
  it("adds two numbers", () => {
    expect(sum(2, 3)).toBe(5);
  });

  it("handles negatives", () => {
    expect(sum(-1, -1)).toBe(-2);
  });
});

Nomeie os testes de acordo com o comportamento, não com a função. Um teste que falha e diz “soma dois números” informa o que quebrou; um que diz “teste de soma 1” não informa. Agrupe casos relacionados com describe e use beforeEach e afterEach para setup e cleanup.

Assertions

O Vitest oferece uma API de matchers robusta, muito similar à do Jest.

// assertions.test.ts
expect(value).toBe(5);              // strict equality
expect(value).toEqual({ a: 1 });    // deep equality
expect(value).toBeTruthy();
expect(list).toHaveLength(3);
expect(list).toContain("a");
expect(fn).toThrow("invalid");
expect(value).toBeGreaterThan(3);

Use toEqual para objetos e arrays e toBe para primitivos e verificações de referência. toMatchObject e toContainEqual são úteis quando você se importa apenas com parte de uma estrutura.

Mocks e spies

O isolamento é fundamental para os testes unitários. O Vitest fornece vi.fn para mocks, vi.spyOn para envolver métodos existentes e vi.mock para substituir módulos inteiros.

// api.test.ts
import { vi, describe, it, expect } from "vitest";
import { fetchUser } from "./api";

vi.mock("./http", () => ({
  get: vi.fn().mockResolvedValue({ id: 1, name: "Ada" }),
}));

describe("fetchUser", () => {
  it("returns the user", async () => {
    await expect(fetchUser(1)).resolves.toEqual({ id: 1, name: "Ada" });
  });
});

vi.mock é içada (hoisted) acima dos imports, portanto, o mock é registrado antes que o módulo sob teste o carregue. Quando a factory precisar de uma variável definida no arquivo de teste, use vi.hoisted para que o valor exista antes da execução do mock.

Testes assíncronos

Aguarde a operação e faça a asserção do resultado. O Vitest fornece os helpers resolves e rejects para promises.

// async.test.ts
it("rejects on failure", async () => {
  await expect(loadUser(-1)).rejects.toThrow("Invalid id");
});

Prefira este estilo em vez do callback done. Esquecer o done causa timeouts difíceis de diagnosticar, e rejections não tratadas podem vazar entre os testes. Para timers falsos, vi.useFakeTimers() e vi.advanceTimersByTime() permitem que você teste debounces e intervalos de forma determinística.

Snapshots

Snapshots capturam um valor e o comparam em execuções posteriores. Eles são úteis para saídas grandes e estáveis, como dados serializados ou marcações renderizadas, mas são fáceis de usar incorretamente.

// snapshot.test.ts
it("matches the shape", () => {
  expect(createConfig({ debug: true })).toMatchSnapshot();
});

Um snapshot que é atualizado sem ser revisado é pior do que a ausência de um teste. Use-os para estruturas de dados onde uma comparação completa seja impraticável, e prefira asserções explícitas quando você souber o que é relevante. toMatchInlineSnapshot mantém o valor esperado no arquivo de teste, o que torna as revisões significativas.

Configuração

O Vitest lê um bloco test do seu config do Vite ou de um vitest.config.ts dedicado.

// vitest.config.ts
import { defineConfig } from "vitest/config";

export default defineConfig({
  test: {
    environment: "jsdom",
    globals: true,
    coverage: {
      provider: "v8",
      reporter: ["text", "html"],
      thresholds: { lines: 80 },
    },
  },
});

A opção environment seleciona node, jsdom, happy-dom ou um browser. Para testes de componentes, jsdom ou happy-dom são típicos; para lógica pura, mantenha o ambiente rápido node. Os coverage thresholds transformam uma meta de cobertura em uma regra obrigatória.

Vitest e a pirâmide de testes

O Vitest é a camada de testes unitários e de integração. Combine-o com uma biblioteca de testes de componentes, como a Testing Library, para o comportamento da UI, e com uma ferramenta de ponta a ponta (end-to-end) como o Playwright para fluxos completos de usuário. Juntos, eles cobrem a pirâmide: muitos testes unitários rápidos, menos testes de integração e alguns poucos testes end-to-end.

Melhores práticas

  • Teste o comportamento, não os detalhes de implementação.
  • Mantenha cada teste focado em apenas um comportamento.
  • Use beforeEach para configurações compartilhadas e limpe mocks com vi.clearAllMocks.
  • Prefira resolves e rejects em vez de callbacks done.
  • Faça mock nas fronteiras (rede, tempo, aleatoriedade), não em cada chamada interna.
  • Use limites de cobertura (coverage thresholds) para evitar regressões silenciosas.
  • Execute em modo watch durante o desenvolvimento e no CI a cada push.

Erros comuns

  • Fazer asserções em estados internos ou métodos privados em vez de comportamentos observáveis.
  • Atualizar snapshots sem revisar o diff.
  • Esquecer de limpar mocks entre os testes, causando vazamento de estado.
  • Usar timers reais, tornando os testes lentos e instáveis (flaky).
  • Exagerar nos mocks a ponto de o teste verificar apenas os próprios mocks.
  • Testar o mesmo comportamento em todos os níveis da pirâmide.

Próximos passos

O Vitest é a maneira mais rápida de começar a testar um projeto Vite. Compare-o com o clássico Jest, adicione Testing Library para componentes e Playwright para fluxos end-to-end, e utilize o Vite para manter a configuração compartilhada. Depois, escreva alguns testes para o código que você já possui e veja como um refactor se torna seguro.

Testando código assíncrono

Aguarde a promise e faça a asserção no resultado. O callback done é fácil de esquecer e produz timeouts confusos.

Preferir
it("loads the user", async () => {
  await expect(getUser(1)).resolves.toEqual({
    id: 1,
    name: "Ada",
  });
});
Evitar
it("loads the user", (done) => {
  getUser(1).then((user) => {
    expect(user.name).toBe("Ada");
    done();
  });
});

Fazendo mock de um módulo

vi.mock sofre hoisting acima dos imports, então o módulo é substituído antes que o código sob teste o carregue.

Preferir
import { vi } from "vitest";

vi.mock("./api", () => ({
  fetchUser: vi.fn().mockResolvedValue({
    id: 1,
  }),
}));
Evitar
import * as api from "./api";
// reassigning after import
// is brittle and often fails
api.fetchUser = async () => ({ id: 1 });

Perguntas frequentes

Perguntas frequentes

Keep learning

Related topics from the roadmap.

$ comecar a aprender

Pronto para aprender Vitest?

Nosso tutorial interativo te guia por Vitest passo a passo — com quizzes e codigo real que voce pode executar no navegador.