Skip to content

bun test é profundamente integrado com o runtime do Bun. Isso é parte do que torna bun test rápido e simples de usar.

Variáveis de Ambiente

NODE_ENV

bun test define automaticamente $NODE_ENV como "test", a menos que já esteja definido no ambiente ou via arquivos .env. Este é o comportamento padrão para a maioria dos executores de teste e ajuda a garantir comportamento de teste consistente.

test.ts
ts
import { test, expect } from "bun:test";

test("NODE_ENV é definido como test", () => {
  expect(process.env.NODE_ENV).toBe("test");
});

Você pode substituir isso definindo NODE_ENV explicitamente:

bash
NODE_ENV=development bun test

TZ (Fuso Horário)

Por padrão, todas as execuções de bun test usam UTC (Etc/UTC) como fuso horário, a menos que seja substituído pela variável de ambiente TZ. Isso garante comportamento consistente de data e hora em diferentes ambientes de desenvolvimento.

test.ts
ts
import { test, expect } from "bun:test";

test("fuso horário é UTC por padrão", () => {
  const date = new Date();
  expect(date.getTimezoneOffset()).toBe(0);
});

Para testar com um fuso horário específico:

bash
TZ=America/New_York bun test

Timeouts de Teste

Cada teste tem um timeout padrão de 5000ms (5 segundos) se não for substituído explicitamente. Testes que excedem este timeout falharão.

Timeout Global

Altere o timeout globalmente com a flag --timeout:

bash
bun test --timeout 10000  # 10 segundos

Timeout por Teste

Defina timeout por teste como o terceiro parâmetro para a função de teste:

test.ts
ts
import { test, expect } from "bun:test";

test("teste rápido", () => {
  expect(1 + 1).toBe(2);
}, 1000); // timeout de 1 segundo

test("teste lento", async () => {
  await new Promise(resolve => setTimeout(resolve, 8000));
}, 10000); // timeout de 10 segundos

Timeout Infinito

Use 0 ou Infinity para desabilitar timeout:

test.ts
ts
test("teste sem timeout", async () => {
  // Este teste pode rodar indefinidamente
  await someVeryLongOperation();
}, 0);

Tratamento de Erros

Erros Não Tratados

bun test rastreia rejeições de promise não tratadas e erros que ocorrem entre testes. Se tais erros ocorrerem, o código de saída final será diferente de zero (especificamente, a contagem de tais erros), mesmo que todos os testes passem.

Isso ajuda a detectar erros em código assíncrono que poderiam passar despercebidos:

test.ts
ts
import { test } from "bun:test";

test("teste 1", () => {
  // Este teste passa
  expect(true).toBe(true);
});

// Este erro acontece fora de qualquer teste
setTimeout(() => {
  throw new Error("Erro não tratado");
}, 0);

test("teste 2", () => {
  // Este teste também passa
  expect(true).toBe(true);
});

// A execução do teste ainda falhará com código de saída diferente de zero
// por causa do erro não tratado

Rejeições de Promise

Rejeições de promise não tratadas também são capturadas:

test.ts
ts
import { test } from "bun:test";

test("teste passando", () => {
  expect(1).toBe(1);
});

// Isso fará com que a execução do teste falhe
Promise.reject(new Error("Rejeição não tratada"));

Tratamento de Erros Personalizado

Você pode configurar handlers de erro personalizados no seu setup de teste:

test-setup.ts
ts
process.on("uncaughtException", error => {
  console.error("Exceção Não Capturada:", error);
  process.exit(1);
});

process.on("unhandledRejection", (reason, promise) => {
  console.error("Rejeição Não Tratada em:", promise, "motivo:", reason);
  process.exit(1);
});

Integração de Flags de CLI

Várias flags de CLI do Bun podem ser usadas com bun test para modificar seu comportamento:

Uso de Memória

bash
# Reduz uso de memória para a VM do executor de testes
bun test --smol

Depuração

bash
# Anexa o depurador ao processo do executor de testes
bun test --inspect
bun test --inspect-brk

Carregamento de Módulo

bash
# Executa scripts antes dos arquivos de teste (útil para setup/mocks globais)
bun test --preload ./setup.ts

# Define constantes em tempo de compilação
bun test --define "process.env.API_URL='http://localhost:3000'"

# Configura loaders personalizados
bun test --loader .special:special-loader

# Usa um tsconfig diferente
bun test --tsconfig-override ./test-tsconfig.json

# Define condições package.json para resolução de módulo
bun test --conditions development

# Carrega variáveis de ambiente para testes
bun test --env-file .env.test

Flags Relacionadas à Instalação

bash
# Afetam quaisquer requisições de rede ou instalações automáticas durante execução de teste
bun test --prefer-offline
bun test --frozen-lockfile

Watch e Hot Reloading

Modo Watch

Ao executar bun test com a flag --watch, o executor de testes observará alterações de arquivo e re-executará testes afetados.

bash
bun test --watch

O executor de testes é inteligente sobre quais testes re-executar:

math.test.ts
ts
import { add } from "./math.js";
import { test, expect } from "bun:test";

test("adição", () => {
  expect(add(2, 3)).toBe(5);
});

Se você modificar math.js, apenas math.test.ts será re-executado, não todos os testes.

Hot Reloading

A flag --hot fornece funcionalidade similar, mas é mais agressiva em tentar preservar estado entre execuções:

bash
bun test --hot

Para a maioria dos cenários de teste, --watch é a opção recomendada, pois fornece melhor isolamento entre execuções de teste.

Variáveis Globais

Os seguintes globals estão automaticamente disponíveis em arquivos de teste sem importar (embora possam ser importados de bun:test se preferir):

test.ts
ts
// Todos estes estão disponíveis globalmente
test("função de teste global", () => {
  expect(true).toBe(true);
});

describe("describe global", () => {
  beforeAll(() => {
    // beforeAll global
  });

  it("função it global", () => {
    // it é um alias para test
  });
});

// Compatibilidade com Jest
jest.fn();

// Compatibilidade com Vitest
vi.fn();

Você também pode importá-los explicitamente se preferir:

test.ts
ts
import { test, it, describe, expect, beforeAll, beforeEach, afterAll, afterEach, jest, vi } from "bun:test";

Integração de Processo

Códigos de Saída

bun test usa códigos de saída padrão:

  • 0: Todos testes passaram, sem erros não tratados
  • 1: Falhas de teste ocorreram
  • >1: Número de erros não tratados (mesmo se testes passaram)

Tratamento de Sinal

O executor de testes lida adequadamente com sinais comuns:

bash
# Para graciosamente execução de teste
kill -SIGTERM <pid-do-processo-de-teste>

# Para imediatamente execução de teste
kill -SIGKILL <pid-do-processo-de-teste>

Detecção de Ambiente

O Bun detecta automaticamente certos ambientes e ajusta o comportamento:

test.ts
ts
// Detecção do GitHub Actions
if (process.env.GITHUB_ACTIONS) {
  // Bun emite automaticamente anotações do GitHub Actions
}

// Detecção de CI
if (process.env.CI) {
  // Certos comportamentos podem ser ajustados para ambientes CI
}

Considerações de Desempenho

Processo Único

O executor de testes executa todos os testes em um único processo por padrão. Isso fornece:

  • Inicialização mais rápida - Sem necessidade de spawnar múltiplos processos
  • Memória compartilhada - Uso eficiente de recursos
  • Depuração simples - Todos testes em um processo

No entanto, isso significa:

  • Testes compartilham estado global (use hooks de lifecycle para limpar)
  • Uma falha de teste pode afetar outros
  • Sem paralelização verdadeira de testes individuais

Gerenciamento de Memória

bash
# Monitorar uso de memória
bun test --smol  # Reduz pegada de memória

# Para grandes suítes de teste, considere dividir arquivos
bun test src/unit/
bun test src/integration/

Isolamento de Teste

Como testes rodam no mesmo processo, certifique-se de limpeza adequada:

test.ts
ts
import { afterEach } from "bun:test";

afterEach(() => {
  // Limpar estado global
  global.myGlobalVar = undefined;
  delete process.env.TEST_VAR;

  // Redefinir módulos se necessário
  jest.resetModules();
});

Bun by www.bunjs.com.cn edit