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.
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.