O que os testes de contrato verificam

Que o formato esperado pelos dois lados é o mesmo. Nomes de campos, tipos, obrigatórios e opcionais, códigos de status. Se um produtor remove um campo do qual um consumidor depende, o teste de contrato falha no build, e não às três da manhã.

Em um sistema com muitos serviços e deploys independentes, isso é genuinamente valioso e muito mais barato do que ambientes de integração ponta a ponta.

O que eles deliberadamente não verificam

  • Se o valor está certo. Uma resposta com o formato correto contendo o total errado satisfaz qualquer contrato.

  • Se o fluxo funciona. Cada chamada pode satisfazer seu contrato enquanto a sequência produz um resultado sem sentido.

  • O que o usuário vê. Contratos tratam de serviços conversando com serviços. Ninguém abriu o produto.

Nada disso é uma crítica. Um teste de contrato que verificasse valores ficaria acoplado aos dados e quebraria o tempo todo, que é exatamente o que os testes de contrato foram criados para evitar. O escopo restrito é justamente a vantagem.

O modo de falha a que você precisa ficar atento

Um time adota testes de contrato, as falhas de integração param e a confiança aumenta. Seis meses depois, algo quebra em produção mesmo com todos os testes de contrato passando, porque o formato estava certo e o comportamento estava errado. A lição que as pessoas costumam tirar é que os testes de contrato falharam, e essa é a lição errada.

Os testes de contrato fizeram o trabalho deles. A lacuna era que nada estava verificando comportamento, e o sucesso da camada de contratos tornou essa lacuna mais difícil de enxergar.

O que precisa vir ao lado deles

Verificação funcional contra os serviços em execução: a sequência de chamadas produz o resultado certo, os caminhos de erro se comportam como deveriam, a autorização se sustenta. Essa é outra camada e é ela que responde às perguntas que os contratos não conseguem responder.

Essas verificações precisam lidar com sessões, valores capturados entre chamadas, ordenação e limpeza, temas cobertos na documentação de testes de API.

Terminal

npm install -g @testsprite/testsprite-cli
testsprite setup

Se você preferir não instalar nada, o dashboard faz a mesma coisa. Todo o resto que a linha de comando permite fazer está no repositório do CLI.

Orientado ao consumidor, e por que essa abordagem costuma vencer

As duas abordagens diferem em quem escreve o contrato, e a diferença aparece um ano depois, não de imediato.

Contratos orientados ao produtor codificam o que o serviço pretende oferecer. Isso é útil e tende a ser generoso: o contrato descreve a resposta inteira, incluindo campos que ninguém consome. Mudanças incompatíveis em campos que ninguém usa passam a quebrar o build, e os times começam a ignorar falhas de contrato, o que anula o propósito.

Contratos orientados ao consumidor codificam o que cada consumidor realmente lê. O contrato é menor, as falhas são reais e você ganha um subproduto genuinamente útil: um mapa preciso de quais campos importam para quem. É esse mapa que permite a um produtor depreciar algo com confiança, que é o que todo mundo realmente queria.

Onde cada um roda

Testes de contrato no build, rápidos e a cada commit, porque todo o valor deles está em pegar desvios de formato antes da integração. Verificação de comportamento contra um ambiente implantado, a cada pull request.

O gatilho importa mais do que o mecanismo. Apontar isso para o seu evento de deploy faz com que toda mudança seja verificada sem que ninguém precise decidir por isso; o GitHub App faz isso pelo dashboard, e um passo do GitHub Actions faz isso de dentro do seu workflow.

O que o TestSprite responde e os contratos não conseguem

Se os valores estão certos e se a sequência produz o resultado correto. Ele exercita os serviços em execução pelas interfaces deles, então uma resposta que satisfaz todos os contratos e traz o total errado é detectada.

Fluxos de múltiplas etapas são a lacuna específica. Integration Tests encadeiam chamadas em que uma resposta alimenta a próxima, e Dependency Chains derivam uma ordem segura a partir do que cada caso precisa e produz. Auto-Authentication mantém as sessões vivas ao longo de uma execução, Dynamic Variables levam valores de uma chamada para outra, Dependency Chains derivam a ordem de execução a partir do que cada caso precisa e produz, e Auto-Cleanup remove exatamente o que a execução criou.

O que você acaba tendo são duas camadas que não se sobrepõem: contratos pegando desvios de formato no build, a baixo custo e a cada commit, e verificação de comportamento cobrindo as questões de correção para as quais os contratos são deliberadamente cegos.

O TestSprite faz testes de contrato?

Não. Ele verifica comportamento contra os serviços em execução. Teste de contrato é outro instrumento, e os dois se complementam.

Testes de contrato bastam para microsserviços?

São a resposta certa para desvios de formato entre serviços e não dizem se um fluxo que atravessa vários serviços produz o resultado correto.

Orientado ao consumidor ou orientado ao produtor?

O orientado ao consumidor pega mais quebras reais, porque codifica o que os consumidores de fato usam em vez do que o produtor pretendia oferecer.

Ainda precisamos de testes de integração?

De menos deles, e esse é justamente o ponto. Mantenha um conjunto pequeno cobrindo os fluxos que atravessam serviços e deixe os contratos cuidarem da questão do formato.

E se a gente controlar os dois lados?

O valor cai, porque você consegue mudar os dois juntos. A utilidade é maior quando os times fazem deploy de forma independente.

Em resumo

Formato certo, comportamento desconhecido.

Testes de contrato pegam desvios de formato entre serviços a baixo custo e são deliberadamente cegos quanto a saber se algum dos lados está correto. Mantenha-os no build e coloque, ao lado deles, a verificação de comportamento contra os serviços em execução.