af aprenda frontend
módulo 07 qualidade

Vitest — primeiros testes.

Instalação, primeiro arquivo .test.ts, describe, test, expect. Matchers mais usados (toBe, toEqual, toContain, toThrow).

Vitest é o framework de testes natural para projetos Vite. Ele reutiliza a mesma configuração — TypeScript, aliases, plugins — e oferece uma API idêntica à do Jest, com o benefício de ser significativamente mais rápido. Para o blog React com Vite e TypeScript, praticamente não há configuração adicional.

Instalação e configuração

bash
npm install -D vitest
Instalar Vitest e adicionar o script de test.
json
{
  "scripts": {
    "dev": "vite",
    "build": "tsc -b && vite build",
    "test": "vitest",
    "test:ui": "vitest --ui",
    "coverage": "vitest run --coverage"
  }
}
package.json — adicionar o script test.

Para a maioria dos projetos Vite + TypeScript, isso é suficiente. Vitest lê o vite.config.ts automaticamente. Se você precisar de configuração específica para testes (como o ambiente jsdom para componentes React), adicione uma seção test no vite.config.ts ou crie um vitest.config.ts separado:

ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

export default defineConfig({
  plugins: [react()],
  test: {
    environment: "jsdom",          // simula o DOM do navegador
    globals: true,                 // describe, test, expect sem import
    setupFiles: ["./src/test/setup.ts"],  // arquivo de setup global
  },
});
vite.config.ts — configuração mínima com jsdom para React.
ts
import "@testing-library/jest-dom"; // matchers adicionais de DOM (opcional, para lição 7)
src/test/setup.ts — setup global dos testes.

Estrutura de um arquivo de teste

ts
import { describe, it, expect } from "vitest";
import { formatarData, gerarSlug } from "./utils";

// describe agrupa testes relacionados — geralmente uma função ou módulo
describe("formatarData", () => {

  // it (ou test) descreve um comportamento específico
  it("retorna 'agora' para datas dos últimos 60 segundos", () => {
    // Arrange — preparar o cenário
    const agora = new Date();

    // Act — executar
    const resultado = formatarData(agora);

    // Assert — verificar
    expect(resultado).toBe("agora");
  });

  it("retorna data formatada para datas com mais de 7 dias", () => {
    const dataAntiga = new Date("2024-01-15");
    expect(formatarData(dataAntiga)).toBe("15 de jan. de 2024");
  });
});
utils.test.ts — estrutura básica de um arquivo de teste.

Convenções de nomes de arquivo:

  • utils.test.ts — junto ao arquivo testado (padrão mais comum)
  • utils.spec.ts — equivalente, preferido em alguns projetos
  • __tests__/utils.ts — em pasta separada (comum em projetos maiores)

Matchers essenciais

ts
// .toBe() — igualdade estrita (===)
// Use para primitivos: strings, números, booleans
expect(2 + 2).toBe(4);
expect("slug-gerado").toBe("slug-gerado");
expect(true).toBe(true);

// .toEqual() — igualdade profunda de conteúdo
// Use para objetos e arrays — .toBe() falha com referências diferentes
expect([1, 2, 3]).toEqual([1, 2, 3]);             // ✅
expect({ id: 1 }).toEqual({ id: 1 });              // ✅
expect([1, 2, 3]).toBe([1, 2, 3]);                // ❌ referências diferentes

// .toBeTruthy() e .toBeFalsy()
// Para verificar truthiness sem checar o valor exato
expect("algum texto").toBeTruthy();
expect(null).toBeFalsy();
expect(0).toBeFalsy();

// .toContain() — verifica que array contém item ou string contém substring
expect(["css", "html", "js"]).toContain("css");
expect("Introdução ao React").toContain("React");

// .toHaveLength() — tamanho de array ou string
expect([1, 2, 3]).toHaveLength(3);
expect("abc").toHaveLength(3);

// .toBeNull() e .toBeUndefined()
expect(null).toBeNull();
expect(undefined).toBeUndefined();

// .toBeGreaterThan() e similares
expect(5).toBeGreaterThan(3);
expect(2).toBeLessThanOrEqual(2);

// .toThrow() — verifica que uma função lança erro
// Sempre passe a função como callback — não chame diretamente
expect(() => gerarSlug(null as any)).toThrow();
expect(() => dividir(10, 0)).toThrow("Divisão por zero");
Matchers mais usados no dia a dia.

Primeiro teste real — gerarSlug

ts
import { describe, it, expect } from "vitest";
import { gerarSlug } from "./utils";

describe("gerarSlug", () => {
  it("converte texto simples para slug", () => {
    expect(gerarSlug("Introdução ao CSS")).toBe("introducao-ao-css");
  });

  it("converte para minúsculas", () => {
    expect(gerarSlug("React e TypeScript")).toBe("react-e-typescript");
  });

  it("substitui espaços por hífens", () => {
    expect(gerarSlug("como a web funciona")).toBe("como-a-web-funciona");
  });

  it("remove acentos e caracteres especiais", () => {
    expect(gerarSlug("Flexbox: guia completo")).toBe("flexbox-guia-completo");
  });

  it("remove espaços extras nas bordas", () => {
    expect(gerarSlug("  CSS Grid  ")).toBe("css-grid");
  });

  it("retorna string vazia para entrada vazia", () => {
    expect(gerarSlug("")).toBe("");
  });
});
gerarSlug.test.ts — cobrindo casos normais e limite.

Rodando os testes

bash
# rodar uma vez — para CI ou verificação rápida
npm test -- --run

# modo watch — re-roda quando arquivos mudam (padrão de desenvolvimento)
npm test

# filtrar por nome — rodar apenas testes com "slug" no nome
npm test -- --reporter=verbose gerarSlug

# relatório de cobertura
npm run coverage
Comandos para rodar os testes.

O output de uma suite passando:

plaintext
 ✓ src/utils.test.ts (6)
   ✓ gerarSlug (6)
     ✓ converte texto simples para slug
     ✓ converte para minúsculas
     ✓ substitui espaços por hífens
     ✓ remove acentos e caracteres especiais
     ✓ remove espaços extras nas bordas
     ✓ retorna string vazia para entrada vazia

 Test Files  1 passed (1)
      Tests  6 passed (6)
   Duration  187ms

E quando um teste falha — a mensagem mostra exatamente o que era esperado e o que chegou:

plaintext
 FAIL src/utils.test.ts > gerarSlug > remove acentos e caracteres especiais
AssertionError: expected 'flexbox:-guia-completo' to be 'flexbox-guia-completo'

 - Expected: "flexbox-guia-completo"
 + Received: "flexbox:-guia-completo"

Resumo

  • Instalação: npm install -D vitest + script "test": "vitest" no package.json. Para React, adicione environment: "jsdom" na config.
  • Estrutura: describe agrupa, it/test descreve um comportamento, expect faz a asserção.
  • Matchers essenciais: .toBe() para igualdade estrita, .toEqual() para objetos/arrays, .toContain() para listas e strings, .toThrow() para erros esperados.
  • npm test roda em modo watch — re-roda automaticamente ao salvar. npm test -- --run roda uma vez.
  • Mensagens de falha mostram o valor esperado vs. o recebido — fácil de diagnosticar.
/ checkpoint verifique seu entendimento
questão 1 de 4

Por que Vitest precisa de pouca configuração em projetos Vite?