<h2>O Que é Contract Testing com Pact?</h2>
<p>Contract Testing é uma metodologia que valida a comunicação entre serviços (consumidor e provedor) sem depender de ambientes integrados completos. O Pact é um framework open-source que implementa essa abordagem de forma elegante, permitindo que cada serviço defina contratos — acordos sobre como devem se comunicar. Ao invés de testes de integração pesados, você cria "contratos" que garantem compatibilidade mútua, detectando quebras de contrato antes de chegarem à produção.</p>
<p>A grande vantagem? Equipes podem trabalhar independentemente. O consumidor define o que espera do provedor, e o provedor valida se consegue entregar. Não é necessário que ambos os serviços estejam rodando simultaneamente durante os testes. Isso acelera o ciclo de desenvolvimento e reduz custos de infraestrutura de testes.</p>
<h2>Entendendo os Componentes Principais</h2>
<h3>Consumer-Driven Contracts</h3>
<p>No Pact, o consumidor define primeiro o contrato. Ele escreve testes especificando exatamente como vai chamar o provedor: qual endpoint, que parâmetros envia, que resposta espera. O consumidor não fica preso à implementação real do provedor — apenas ao contrato acordado. Esse arquivo de contrato é compartilhado com o provedor, que valida se consegue cumprir as promessas.</p>
<h3>O Arquivo de Contrato (JSON)</h3>
<p>O Pact gera automaticamente um arquivo JSON documentando o contrato. Este arquivo contém todas as interações esperadas entre consumidor e provedor. É um documento vivo que evolui com o tempo, funcionando simultaneamente como teste e documentação.</p>
<pre><code class="language-json">{
"consumer": {
"name": "UserService"
},
"provider": {
"name": "AuthService"
},
"interactions": [
{
"description": "Validar token do usuário",
"request": {
"method": "POST",
"path": "/auth/validate",
"body": {
"token": "abc123"
}
},
"response": {
"status": 200,
"body": {
"valid": true,
"userId": "user-1"
}
}
}
]
}</code></pre>
<h2>Implementação Prática com Pact (JavaScript/Node.js)</h2>
<h3>Escrevendo Testes do Consumidor</h3>
<p>O consumidor começa definindo o que espera do provedor. Aqui, o UserService espera chamar o AuthService:</p>
<pre><code class="language-javascript">const { PactV3 } = require("@pact-foundation/pact");
const axios = require("axios");
const pact = new PactV3({
consumer: "UserService",
provider: "AuthService",
port: 9876,
});
describe("AuthService Contract", () => {
it("deve validar token com sucesso", async () => {
pact.addInteraction({
states: ["token válido existe"],
uponReceiving: "validação de token",
withRequest: {
method: "POST",
path: "/auth/validate",
body: { token: "abc123" },
headers: { "Content-Type": "application/json" },
},
willRespondWith: {
status: 200,
body: { valid: true, userId: "user-1" },
},
});
await pact.executeTest(async (mockServer) => {
const response = await axios.post(
${mockServer.url}/auth/validate,
{ token: "abc123" }
);
expect(response.data.valid).toBe(true);
expect(response.data.userId).toBe("user-1");
});
});
});</code></pre>
<h3>Validando o Contrato no Provedor</h3>
<p>O AuthService agora valida se consegue cumprir o contrato. O Pact fornece um arquivo gerado no consumidor que o provedor testa contra sua implementação real:</p>
<pre><code class="language-javascript">const { Verifier } = require("@pact-foundation/pact");
const app = require("./app"); // Sua aplicação Express
describe("AuthService Pact Verification", () => {
it("honra o contrato com UserService", async () => {
const verificationOptions = {
provider: "AuthService",
providerBaseUrl: "http://localhost:3000",
pactFiles: [
"./pacts/UserService-AuthService.json",
],
stateHandlers: {
"token válido existe": async () => {
// Preparar estado: inserir token no banco de dados
await db.tokens.create({ value: "abc123", userId: "user-1" });
},
},
};
return new Verifier(verificationOptions).verifyProvider();
});
});</code></pre>
<h2>Fluxo de Trabalho Completo</h2>
<p>O processo segue um ciclo bem definido: <strong>(1)</strong> Consumidor escreve testes, <strong>(2)</strong> Pact gera arquivo de contrato, <strong>(3)</strong> Provedor executa verificação, <strong>(4)</strong> Se falhar, provedor ajusta sua API, <strong>(5)</strong> Se passar, integração é segura. Contratos são compartilhados via repositório ou Pact Broker (servidor centralizado que gerencia contratos e pode disparar deploys automaticamente).</p>
<p>Para ambientes corporativos, o Pact Broker é essencial. Ele centraliza contratos, permite que qualquer serviço consulte o que é esperado dele, e integra-se com pipelines CI/CD. Quando um contrato quebra, o Broker notifica automaticamente qual serviço está incompatível com qual outro.</p>
<pre><code class="language-bash"># Publicar contrato no Pact Broker
pact-broker publish ./pacts \
--consumer-app-version=1.0.0 \
--broker-base-url=https://pact-broker.company.com \
--broker-token=$PACT_BROKER_TOKEN
Verificar compatibilidade antes de fazer deploy
pact-broker can-i-deploy \
--pacticipant=AuthService \
--version=1.0.0 \
--broker-base-url=https://pact-broker.company.com</code></pre>
<h2>Conclusão</h2>
<p>Contract Testing com Pact resolve um problema real: como garantir compatibilidade entre serviços distribuídos sem testes de integração lentos e frágeis. Você aprendeu que <strong>(1)</strong> contratos são documentos acordados entre consumidor e provedor, não imposições unilaterais, <strong>(2)</strong> o framework gera automaticamente provas de compatibilidade que podem ser reutilizadas em CI/CD, e <strong>(3)</strong> escalabilidade cresce com ferramentas como Pact Broker, não com complexidade dos testes. Implemente Pact em um microsserviço hoje e veja a qualidade dos seus deploys aumentar.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://docs.pactup.com/" target="_blank" rel="noopener noreferrer">Pact Official Documentation</a></li>
<li><a href="https://github.com/pact-foundation/pact-js" target="_blank" rel="noopener noreferrer">Pact JS Implementation Guide</a></li>
<li><a href="https://martinfowler.com/articles/consumerDrivenContracts.html" target="_blank" rel="noopener noreferrer">Contract Testing: A Smart Way to Test Microservices</a></li>
<li><a href="https://docs.pactup.com/pact_broker/overview" target="_blank" rel="noopener noreferrer">Pact Broker Setup and Usage</a></li>
<li><a href="https://learning.oreilly.com/library/view/testing-microservices/9781491944165/" target="_blank" rel="noopener noreferrer">Microservices Testing Strategies - O'Reilly</a></li>
</ul>