Home > Blog > Desenvolvimento Web
Desenvolvimento Web
JavaScript

Vitest no TypeScript: Testes Rápidos

Atualizado em: 23 de julho de 2026

Desenvolvedor executando testes com Vitest no TypeScript

Projetos TypeScript crescem rapidamente. Funções pequenas viram serviços, integrações externas aparecem e uma simples alteração pode quebrar comportamentos que pareciam estáveis. Nesse cenário, testes automatizados ajudam a detectar regressões antes que o código chegue à produção. Neste guia, você vai aprender a usar Vitest no TypeScript para criar testes rápidos, organizar arquivos, trabalhar com mocks, medir cobertura e integrar a suíte ao fluxo de desenvolvimento.

O Vitest foi criado para funcionar de forma muito próxima ao ecossistema do Vite. Ele oferece uma API familiar para quem já conhece Jest, inicialização rápida e suporte natural a TypeScript, módulos ES e recursos modernos do JavaScript. Mesmo em projetos que não usam uma interface web, ele pode ser uma alternativa prática para testar bibliotecas, APIs e funções de negócio.

O que é Vitest?

Vitest é um framework de testes para JavaScript e TypeScript. Ele executa testes unitários, oferece asserções, mocks, spies, hooks de preparação e relatórios de cobertura. A sintaxe usa funções como describe, it, test e expect, o que torna a migração mais simples para equipes que já trabalham com Jest.

O TypeScript verifica tipos durante o desenvolvimento, mas não garante que uma função produz o resultado correto. Um cálculo pode aceitar apenas números e ainda assim retornar um valor errado. Os testes complementam o sistema de tipos ao validar o comportamento real do código.

Se você ainda está conhecendo a linguagem, consulte o artigo sobre o que é TypeScript. Para revisar a base executada no navegador e no Node.js, veja também como o JavaScript funciona.

Instalando o Vitest

Em um projeto TypeScript existente, instale o Vitest como dependência de desenvolvimento:

npm install -D vitest

Depois, adicione scripts ao arquivo package.json:

{
  "scripts": {
    "test": "vitest",
    "test:run": "vitest run",
    "test:coverage": "vitest run --coverage"
  }
}

O comando npm test inicia o modo de observação, que repete os testes relacionados quando os arquivos mudam. O script test:run executa uma vez e encerra, comportamento adequado para integração contínua.

A documentação oficial do Vitest apresenta requisitos, configuração e recursos atualizados. Se o projeto usa Vite, consulte também a documentação oficial do Vite.

Criando o primeiro teste

Crie um arquivo chamado src/math.ts:

export function sum(a: number, b: number): number {
  return a + b;
}

Agora crie src/math.test.ts:

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

describe("sum", () => {
  it("soma dois números", () => {
    expect(sum(2, 3)).toBe(5);
  });

  it("aceita números negativos", () => {
    expect(sum(-4, 1)).toBe(-3);
  });
});

O bloco describe agrupa casos relacionados. Cada chamada de it representa um comportamento verificável. A função expect recebe o resultado real, enquanto toBe compara com o valor esperado.

Asserções mais usadas

O Vitest inclui matchers para valores simples, objetos, arrays, erros e Promises. Veja alguns exemplos:

expect(total).toBe(10);
expect(user).toEqual({ id: 1, name: "Ana" });
expect(tags).toContain("typescript");
expect(value).toBeTruthy();
expect(result).toBeDefined();
expect(() => divide(10, 0)).toThrow("Divisão inválida");

Use toBe para valores primitivos e identidade de referência. Para comparar a estrutura de objetos ou arrays, normalmente prefira toEqual. Escolher a asserção mais específica melhora a mensagem apresentada quando o teste falha.

Testando funções assíncronas

Funções que retornam Promises podem ser testadas com async e await:

async function findUser(id: number) {
  return { id, name: "Marina" };
}

it("busca um usuário", async () => {
  const user = await findUser(7);

  expect(user).toEqual({
    id: 7,
    name: "Marina"
  });
});

Também é possível usar resolves e rejects:

await expect(findUser(7)).resolves.toHaveProperty("id", 7);
await expect(loadMissingFile()).rejects.toThrow();

Não esqueça de retornar ou aguardar a Promise. Caso contrário, o teste pode terminar antes da operação assíncrona e produzir um resultado enganoso.

Preparação com hooks

Hooks organizam tarefas repetidas antes ou depois dos testes. Os mais comuns são beforeEach, afterEach, beforeAll e afterAll.

import { beforeEach, describe, expect, it } from "vitest";

let cart: string[];

beforeEach(() => {
  cart = [];
});

describe("carrinho", () => {
  it("começa vazio", () => {
    expect(cart).toHaveLength(0);
  });

  it("recebe um produto", () => {
    cart.push("Teclado");
    expect(cart).toContain("Teclado");
  });
});

Prefira criar um estado novo para cada teste. Compartilhar dados mutáveis pode fazer um caso depender da ordem de execução de outro, tornando a suíte instável.

Mocks e spies

Mocks substituem dependências por versões controladas. Eles são úteis para impedir chamadas reais a APIs, serviços de e-mail ou pagamentos. O objeto vi fornece funções para criar mocks e observar chamadas.

import { expect, it, vi } from "vitest";

it("envia uma notificação", () => {
  const send = vi.fn();

  send("Pedido aprovado");

  expect(send).toHaveBeenCalledOnce();
  expect(send).toHaveBeenCalledWith("Pedido aprovado");
});

Um spy observa um método existente:

const spy = vi.spyOn(console, "log").mockImplementation(() => {});

console.log("teste");

expect(spy).toHaveBeenCalledWith("teste");
spy.mockRestore();

Restaure spies depois do teste para não afetar outros casos. Em suítes maiores, você pode configurar a limpeza automática ou usar um hook afterEach.

Testes unitários e de integração

Um teste unitário verifica uma unidade pequena, como uma função de cálculo. Um teste de integração avalia a colaboração entre partes, por exemplo uma rota HTTP, um serviço e um repositório em memória.

Mocks são úteis, mas o excesso pode criar testes que apenas confirmam a implementação atual. Use dependências falsas quando a integração real for lenta, cara ou imprevisível. Para regras centrais, mantenha também alguns testes que percorrem o fluxo completo.

O guia de testes unitários com Jest ajuda a comparar conceitos semelhantes. Embora as ferramentas tenham diferenças, organização, isolamento e clareza continuam essenciais.

Configurando o ambiente de teste

Projetos de back-end normalmente usam o ambiente padrão do Node.js. Aplicações que manipulam DOM podem precisar do jsdom. Uma configuração básica pode ser criada em vitest.config.ts:

import { defineConfig } from "vitest/config";

export default defineConfig({
  test: {
    environment: "node",
    globals: false,
    clearMocks: true
  }
});

Manter globals desativado exige importações explícitas, como import { expect, it } from "vitest". Isso facilita a leitura e evita depender de símbolos globais ocultos.

Cobertura de código

Cobertura mostra quais linhas, funções e ramificações foram executadas durante os testes. Instale o provedor recomendado para sua versão do Vitest e execute o script de cobertura. O relatório ajuda a localizar áreas sem testes, mas não mede automaticamente a qualidade dos casos.

Uma suíte pode alcançar cobertura alta e ainda ignorar cenários importantes. Priorize regras de negócio, limites, erros e caminhos alternativos. Use a porcentagem como indicador, não como objetivo isolado.

Executando no GitHub Actions

Em integração contínua, execute o modo que termina automaticamente:

npm ci
npm run test:run

O pipeline deve falhar quando um teste falhar. Assim, mudanças problemáticas não são integradas silenciosamente. O tutorial sobre GitHub Actions mostra como automatizar etapas do projeto.

Para projetos executados em contêineres, confira também o guia sobre Docker. Testes dentro de uma imagem consistente reduzem diferenças entre a máquina local e o ambiente de integração.

Boas práticas com Vitest

  • Teste comportamentos: descreva o resultado esperado, não detalhes internos.
  • Mantenha casos independentes: um teste não deve preparar o estado de outro.
  • Use nomes claros: a descrição deve explicar o cenário e o resultado.
  • Evite lógica complexa no teste: cálculos e condicionais podem esconder erros.
  • Teste falhas: entradas inválidas e exceções fazem parte do comportamento.
  • Controle tempo e aleatoriedade: relógios e valores aleatórios devem ser previsíveis.
  • Limpe mocks: chamadas anteriores não devem contaminar o próximo caso.
  • Execute frequentemente: testes rápidos oferecem retorno durante o desenvolvimento.

Erros comuns

  • Esquecer await: a Promise continua após o teste terminar.
  • Comparar objetos com toBe: use toEqual para estruturas.
  • Mockar tudo: o teste deixa de representar o comportamento real.
  • Compartilhar estado: a ordem de execução passa a alterar resultados.
  • Testar apenas o caminho feliz: erros e limites ficam sem proteção.
  • Usar snapshot sem revisão: atualizar automaticamente pode aceitar uma regressão.

Quando escolher Vitest?

Vitest é especialmente conveniente em projetos modernos que usam TypeScript, módulos ES ou Vite. Ele também atende bibliotecas e back-ends quando a equipe deseja uma configuração direta e uma API de testes familiar.

A escolha não precisa ser baseada apenas em velocidade. Considere integração com o projeto, experiência da equipe, plugins necessários e compatibilidade com bibliotecas. Em um sistema antigo já bem coberto por Jest, uma migração pode não trazer benefícios suficientes. Em um projeto novo, vale criar uma pequena prova de conceito e medir a experiência real.

Conclusão

Usar Vitest no TypeScript permite validar funções, Promises, erros e integrações com uma ferramenta alinhada ao ecossistema moderno do JavaScript. A configuração inicial é pequena, e o modo de observação oferece retorno rápido enquanto o código muda.

Comece pelas funções mais importantes do projeto. Adicione casos de sucesso, falha e limites. Depois, introduza mocks apenas onde houver dependências externas e execute a suíte na integração contínua. Com testes claros e independentes, refatorar deixa de ser uma atividade baseada apenas em confiança e passa a ser apoiada por verificações repetíveis.

Os 10 Melhores Cursos de Programação de 2026

Descubra os melhores cursos de programação. Aprenda a escolher o curso ideal para iniciar ou avançar na carreira de desenvolvedor

POSTS RELACIONADOS

Ver todos

Seta para a direita