Home > Blog > Desenvolvimento Web
Desenvolvimento Web
JavaScript
Programação

Pact no Node.js

Atualizado em: 25 de setembro de 2026

Rack de servidores processando fluxos de dados no Node.js

Pact é uma ferramenta de testes de contrato orientados pelo consumidor. Em uma integração entre serviços, o consumidor descreve as requisições que realmente faz e as respostas de que precisa. O teste gera um contrato compartilhável, e o provedor verifica se sua implementação atende essas expectativas.

O objetivo não é substituir todos os testes de integração, mas detectar mudanças incompatíveis sem depender de um ambiente completo com todos os serviços executando juntos. Os testes ficam rápidos, isolados e mais fáceis de diagnosticar.

Problema resolvido

Imagine uma API de pedidos consumindo uma API de clientes. Um teste end-to-end precisa subir bancos, filas, autenticação e ambos os serviços. Ele pode falhar por dados, rede ou ambiente, sem indicar claramente o contrato quebrado.

Com Pact:

  • o consumidor testa seu cliente contra um mock server;
  • o teste gera um arquivo pact;
  • o provedor executa o contrato contra sua API real;
  • um broker armazena versões e resultados;
  • o pipeline consulta se uma versão pode ser implantada.

Instalação

npm install -D @pact-foundation/pact

A biblioteca usa componentes nativos pré-compilados nas versões modernas. Em plataformas específicas, verifique suporte e requisitos.

Contrato orientado pelo consumidor

O consumidor define apenas o que utiliza. Se o provedor retorna vinte campos, mas o cliente lê três, o contrato pode exigir somente esses três. Isso evita contratos frágeis que quebram quando um campo irrelevante é adicionado.

Teste do consumidor

import path from 'node:path';
import assert from 'node:assert/strict';
import { test } from 'node:test';
import { PactV3, MatchersV3 } from '@pact-foundation/pact';

const { like, integer, string } = MatchersV3;

const pact = new PactV3({
  consumer: 'OrdersApi',
  provider: 'CustomersApi',
  dir: path.resolve('pacts'),
});

test('consulta cliente por id', async () => {
  pact
    .given('cliente 42 existe')
    .uponReceiving('uma consulta ao cliente 42')
    .withRequest({
      method: 'GET',
      path: '/customers/42',
      headers: { Accept: 'application/json' },
    })
    .willRespondWith({
      status: 200,
      headers: { 'Content-Type': 'application/json' },
      body: like({
        id: integer(42),
        name: string('Ana'),
      }),
    });

  await pact.executeTest(async (mockServer) => {
    const response = await fetch(`${mockServer.url}/customers/42`, {
      headers: { Accept: 'application/json' },
    });
    const body = await response.json();
    assert.equal(body.id, 42);
  });
});

O código de produção deve ser testado, não uma requisição duplicada criada apenas para o teste. Encapsule a chamada em um cliente e aponte sua base URL para o mock server.

Matchers

Valores literais exigem igualdade exata. Matchers descrevem a forma:

body: {
  id: MatchersV3.integer(42),
  email: MatchersV3.regex(
    'ana@example.com',
    '^[^@]+@[^@]+$',
  ),
  roles: MatchersV3.eachLike('user'),
}

Use matchers para evitar contratos frágeis, mas não torne tudo genérico. Campos discriminadores, enums e regras relevantes precisam ser restritos.

Provider states

given('cliente 42 existe') descreve o estado necessário. Durante verificação, o provedor configura dados antes da interação. O estado não deve conter detalhes de implementação do consumidor.

Exemplos:

  • usuário existe;
  • pedido está cancelado;
  • token está expirado;
  • não existem resultados;
  • limite de crédito foi atingido.

Verificação do provedor

import { Verifier } from '@pact-foundation/pact';

await new Verifier({
  provider: 'CustomersApi',
  providerBaseUrl: 'http://127.0.0.1:3000',
  pactUrls: ['./pacts/OrdersApi-CustomersApi.json'],
  stateHandlers: {
    'cliente 42 existe': async () => {
      await criarCliente({ id: 42, name: 'Ana' });
    },
  },
}).verifyProvider();

Suba a aplicação com dependências controladas, configure estados e execute a verificação. Dependências externas do provedor podem ser simuladas ou iniciadas com Testcontainers.

Dados determinísticos

Provider states precisam ser idempotentes. A execução pode ocorrer várias vezes e em qualquer ordem. Limpe ou substitua dados antes de criar o estado.

Pact Broker

O broker armazena contratos, versões, tags, branches e resultados de verificação. O consumidor publica o pact; o provedor recupera contratos relevantes e envia resultados.

Sem broker, arquivos locais funcionam para começar, mas não oferecem coordenação entre repositórios.

Publicando contratos

O pipeline do consumidor publica após testes:

pact-broker publish ./pacts \
  --consumer-app-version "$GIT_SHA" \
  --branch "$GIT_BRANCH" \
  --broker-base-url "$PACT_BROKER_URL"

Use a versão imutável do commit, não apenas latest.

Can I Deploy

Antes do deploy, consulte a matriz:

pact-broker can-i-deploy \
  --pacticipant OrdersApi \
  --version "$GIT_SHA" \
  --to-environment production

O comando bloqueia uma combinação que não foi verificada. Após deploy, registre a versão no ambiente para manter a matriz atualizada.

Branches e ambientes

Use branch, versão e ambiente como dimensões distintas. Tags genéricas podem gerar ambiguidades. Um fluxo moderno registra:

  • commit do consumidor;
  • commit do provedor;
  • branch;
  • resultado da verificação;
  • deploy em staging;
  • deploy em produção.

Pending pacts

Um novo contrato do consumidor não deve quebrar imediatamente a branch principal do provedor antes de a equipe ter chance de implementá-lo. Pending pacts permitem distinguir contratos novos de regressões em contratos já suportados.

WIP pacts

Work in progress pacts ajudam o provedor a verificar contratos recentes de branches consumidoras, antecipando incompatibilidades antes do merge.

Autenticação

Durante verificação, tokens reais podem ser dinâmicos. Use filtros ou callbacks para injetar autenticação válida sem gravar segredos no contrato. O pact não deve conter tokens de produção.

Erros e estados alternativos

Teste mais que sucesso:

  • 404 para recurso ausente;
  • 400 para entrada inválida;
  • 401 e 403;
  • 429 com retry-after;
  • resposta vazia;
  • campos opcionais;
  • paginação;
  • erro temporário.

Eventos e mensagens

Pact também suporta sistemas orientados a eventos. O consumidor declara a mensagem esperada, e o provedor verifica que consegue produzi-la. Contratos de mensagens devem cobrir payload, metadata e compatibilidade de schema.

GraphQL

Uma requisição GraphQL ainda trafega por HTTP, mas o contrato precisa considerar query, variáveis e resposta. Evite acoplar o contrato a campos que o consumidor não seleciona.

Contratos não são schemas completos

OpenAPI descreve a API disponível. Pact descreve interações realmente usadas. As duas abordagens são complementares: OpenAPI ajuda design e documentação; Pact valida compatibilidade entre versões reais de consumidor e provedor.

Testes de contrato e end-to-end

Contratos reduzem a necessidade de muitos testes integrados, mas não validam DNS, gateway, certificados, configuração de ambiente ou fluxo completo do usuário. Mantenha poucos testes E2E críticos.

CI do consumidor

  1. instala dependências;
  2. executa testes Pact;
  3. gera contratos;
  4. publica no broker;
  5. consulta compatibilidade antes do deploy;
  6. registra implantação.

CI do provedor

  1. inicia API e dependências;
  2. busca contratos relevantes;
  3. configura provider states;
  4. verifica interações;
  5. publica resultado;
  6. consulta compatibilidade;
  7. registra deploy.

Versionamento

Use SHA Git como versão de aplicação. Versões semânticas podem identificar releases, mas o broker precisa distinguir builds exatos.

Erros comuns

  • copiar a implementação para o teste;
  • usar exemplos exatos em todos os campos;
  • contratar campos não usados;
  • provider states frágeis;
  • publicar como latest;
  • não registrar deploys;
  • verificar apenas localmente;
  • tratar Pact como teste de schema genérico.

Segurança

Proteja credenciais do broker, não publique dados pessoais nos exemplos e limite acesso de pull requests externos. Contratos podem revelar endpoints e modelos de dados.

Fluxo recomendado

Comece por uma integração crítica, teste o cliente real, use matchers, configure estados idempotentes, publique contratos por SHA e bloqueie deploys incompatíveis. Combine com Testcontainers no Node.js, Node Test Runner, versionamento em Semantic Release e pipelines de GitHub Actions.

Consulte a documentação oficial do Pact JS e o workshop oficial de Pact para JavaScript.

10 melhores cursos de programação em 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