node:test & node:assert
O Node 24 lança um runner de testes nativo e um módulo de asserção para que testes unitários rodem sem Jest ou Vitest para lógica de backend pura.
Receita
Cartão de receita de referência rápida - pronto para copiar e colar.
import assert from "node:assert/strict";
import { describe, it } from "node:test";
describe("math", () => {
it("adds", () => {
assert.equal(1 + 1, 2);
});
});node --import tsx --testQuando usar isso:
- Funções puras, parsers e lógica de domínio.
- Você quer zero dependências de runner de teste.
- Bibliotecas que não devem forçar Jest nos consumidores.
Exemplo de Trabalho
// src/pricing/discount.ts
export function applyDiscount(cents: number, percent: number): number {
if (percent < 0 || percent > 100) throw new Error("invalid percent");
return Math.round(cents * (1 - percent / 100));
}// test/pricing/discount.test.ts
import assert from "node:assert/strict";
import { describe, it } from "node:test";
import { applyDiscount } from "../../src/pricing/discount.js";
describe("applyDiscount", () => {
it("reduces price by percentage", () => {
assert.equal(applyDiscount(1000, 10), 900);
});
it("throws on invalid percent", () => {
assert.throws(() => applyDiscount(1000, -1), /invalid percent/);
});
});{
"scripts": {
"test": "node --import tsx --test --test-reporter spec"
}
}O que isso demonstra:
- Importações ESM com extensões
.jspara compatibilidade NodeNext. assert.throwsvalida caminhos de erro sem uma biblioteca de mock.--test-reporter specfornece saída legível para CI.
Mergulho Profundo
Como Funciona
node:testdescobre arquivos*.test.ts(ou caminhos explícitos) e executa em paralelo por padrão.- Hooks:
before,after,beforeEach,afterEachno escopo do describe. node:assert/strictlançaAssertionErrorem caso de incompatibilidade (deep equal usa regras===para primitivos).- Subtestes via aninhamento de
itoutest.context()para agrupamento granular.
Auxiliares de Asserção
| API | Uso |
|---|---|
assert.equal | Igualdade de primitivos |
assert.deepEqual | Estrutura de objeto/array |
assert.rejects | Lançamento assíncrono |
assert.match | Regex em strings |
Notas de TypeScript
node --import tsx --test- O loader
tsxcompila TypeScript na hora para desenvolvimento e CI. - A implantação de produção ainda usa a compilação
tsc; os testes não são enviados.
Armadilhas
- Sem ergonomia de mock/spy embutida - Verboso sem
node:test/mock(Node 22+). Correção: usemock.fn()denode:testou adicione Vitest para mocks pesados. - Testes paralelos compartilhando estado global - Falhas intermitentes. Correção:
describe(..., { concurrency: 1 })ou isolar o estado por teste. - Falta de tsx na CI -
node --testpuro falha em.ts. Correção: dependência de desenvolvimentotsxe--import tsx. - Caminho de importação
.tsem testes - Quebra a resolução ESM. Correção: importar caminhos.jsque correspondam ao layout de emissão. - Teste de snapshot ausente - Sem snapshots do Jest. Correção: afirmar campos explícitos ou adotar Vitest para necessidades de snapshot.
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
| Vitest | Mocking, snapshots, ecossistema Vite | Biblioteca pequena evitando dependências |
| Jest | Projeto existente já usa Jest | Projeto novo sem legado |
| tap / ava | Pipelines de saída TAP | Equipe padronizada em node:test |
FAQs
O node:test está pronto para produção?
Sim no Node 18+; Node 24 Active LTS é o alvo. API estável para describe/it/assert.
Como executo um arquivo?
node --import tsx --test test/pricing/discount.test.tsComo funcionam os mocks?
import { mock } from "node:test";
const fn = mock.fn(() => 42);Disponível em versões modernas do Node para necessidades simples de spy.
Posso usar com NestJS?
Sim para testes unitários de serviços isoladamente. Nest e2e geralmente usa Jest por padrão; node:test funciona com o Test.createTestingModule de configuração manual.
Como pular testes?
it.skip("motivo", fn) ou describe.skip para quarentena temporária com salto visível no reporter.
Qual reporter usar para CI?
spec legível; tap para parsers; dot saída mínima.
Como testar funções assíncronas?
Retorne promises dos callbacks it ou use funções async; falhas rejeitam o teste.
Suporte a cobertura?
node --import tsx --experimental-test-coverage --testExperimental; Vitest/Istanbul maduros para portões de cobertura.
Modo de observação?
Sem modo de observação embutido; use padrões tsx watch --test ou Vitest para loop TDD.
Como os hooks se ordenam?
before executa uma vez por describe; beforeEach antes de cada it; o oposto para hooks after.
Relacionados
- Noções Básicas de Teste - visão geral da pirâmide
- Vitest - quando você precisa de mocks e watch
- Supertest & Integração HTTP - testes de camada HTTP
Versões da Stack: Esta página foi escrita para Node.js 24.18.0 (Active LTS), npm 10+, TypeScript 5.6+, Express 5, Fastify 5 e NestJS 11.