GitHub Actions: testes automatizados em Node.js
Testes automáticos no CI bloqueiam merges com código quebrado — sem precisar de ninguém revisar manualmente se "ainda funciona". Com GitHub Actions, cada PR exibe cobertura de código, relatório de falhas e pode bloquear o merge até todos os testes passarem.
Workflow de testes com Vitest
Pipeline de testes para projetos TypeScript com Vitest:
yaml
# .github/workflows/tests.yml
name: Testes
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [20, 22] # testar em múltiplas versões
steps:
- uses: actions/checkout@v4
- name: Configurar Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: Instalar dependências
run: npm ci
- name: Verificar TypeScript
run: npx tsc --noEmit
- name: Lint
run: npm run lint
- name: Testes unitários
run: npm run test:unit -- --reporter=verbose
- name: Relatório de cobertura
run: npm run test:coverage
- name: Upload cobertura para Codecov
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./coverage/lcov.info
fail_ci_if_error: falseTestes de integração com banco de dados real
Rodar testes de integração com PostgreSQL e Redis no CI:
yaml
# .github/workflows/tests.yml — job de integração:
integration:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_DB: testdb
POSTGRES_USER: testuser
POSTGRES_PASSWORD: testpass
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
redis:
image: redis:7-alpine
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-retries 5
ports:
- 6379:6379
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
- run: npm ci
- name: Rodar migrations no banco de teste
env:
DATABASE_URL: postgresql://testuser:testpass@localhost:5432/testdb
run: npm run db:migrate
- name: Testes de integração
env:
DATABASE_URL: postgresql://testuser:testpass@localhost:5432/testdb
REDIS_URL: redis://localhost:6379
NODE_ENV: test
JWT_SECRET: segredo-de-teste-123
run: npm run test:integrationConfigurar Vitest para CI
vitest.config.ts com configurações para ambiente de CI:
typescript
// vitest.config.ts
import { defineConfig } from 'vitest/config'
import path from 'path'
export default defineConfig({
test: {
globals: true,
environment: 'node',
// Separar testes unitários de integração por pasta:
include: ['src/**/*.{test,spec}.{ts,tsx}'],
exclude: ['src/**/*.integration.test.ts'],
// Configuração de cobertura:
coverage: {
provider: 'v8',
reporter: ['text', 'lcov', 'html'],
include: ['src/**/*.ts'],
exclude: ['src/**/*.test.ts', 'src/types/**'],
thresholds: {
lines: 70, // bloquear CI se cobertura < 70%
functions: 70,
branches: 60,
statements: 70,
},
},
// Timeout mais longo para integração:
testTimeout: 30_000,
// Relatório para o GitHub Actions (faz anotações no PR):
reporter: process.env.CI ? ['verbose', 'github-actions'] : ['verbose'],
// Rodar em paralelo (mais rápido no CI):
pool: 'threads',
poolOptions: {
threads: { maxThreads: 4 },
},
},
resolve: {
alias: { '@': path.resolve(__dirname, 'src') },
},
})Comentar cobertura de código no Pull Request
Exibir diff de cobertura diretamente nos comentários do PR:
yaml
# .github/workflows/tests.yml — adicionar após os testes:
- name: Relatório de cobertura no PR
uses: davelosert/vitest-coverage-report-action@v2
if: always()
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
# Comentar no PR com o relatório de cobertura:
# - linhas novas sem cobertura ficam marcadas
# - comparação com a cobertura da branch main
json-summary-path: ./coverage/coverage-summary.json
json-final-path: ./coverage/coverage-final.json
# package.json — scripts de teste:
# {
# "scripts": {
# "test": "vitest run",
# "test:unit": "vitest run --exclude='**/*.integration.*'",
# "test:integration": "vitest run --include='**/*.integration.*'",
# "test:coverage": "vitest run --coverage",
# "test:watch": "vitest watch"
# }
# }Bloquear merge se testes falharem
Configurar branch protection para exigir CI verde antes do merge:
bash
# No GitHub — Settings → Branches → Branch protection rules:
# Branch name pattern: main
# Marcar: ✓ Require status checks to pass before merging
# Status checks required:
# - test (Node.js 22)
# - integration
# - TypeScript check
# Marcar: ✓ Require branches to be up to date before merging
# Resultado:
# - PRs com testes vermelhos não podem ser mergeados
# - O botão de merge fica bloqueado
# - Cada push no PR roda os testes automaticamente
# Tornar o workflow obrigatório (required check):
# O nome do check é o campo "name:" do job no workflow
# Exemplo: se o job se chama "test", o check é "test"
# Para múltiplos SO ou versões (matrix):
# Cada combinação gera um check separado:
# "test (ubuntu-latest, 20)"
# "test (ubuntu-latest, 22)"
# Adicione todos que quiser como obrigatórios$ runstack deploy --plan starter
Não quer configurar manualmente?
Não quer configurar manualmente? Implante o VPS para APIs em menos de 3 minutos com a Runstack. Infraestrutura da OPEN DATACENTER, com servidores no Brasil.