Onde os testes de API com Cypress são realmente bons

  • Setup e teardown. Criar pela API o estado de que um teste de UI precisa, em vez de percorrer cinco telas no clique. Mais rápido, mais confiável e o uso certo do recurso.

  • Asserções entre camadas. Fazer algo na interface e depois confirmar que o backend registrou aquilo corretamente. É uma categoria legítima de teste, e o Cypress lida com ela muito bem.

  • Algumas poucas verificações de endpoints. Quando a superfície da API é pequena, mantê-la na mesma suíte é uma troca razoável em nome da simplicidade.

Os quatro problemas que chegam com a escala

Duração da sessão

  • Tokens expiram no meio da suíte e as falhas parecem bugs do produto.

  • A lógica de refresh acaba escrita à mão em um arquivo de suporte.

Valores entre chamadas

  • Um identificador vindo de uma chamada de criação precisa chegar à chamada de exclusão, e o encadeamento de comandos do Cypress torna isso desajeitado entre testes.

  • Alguém fixa o valor no código, e a suíte funciona uma única vez.

Ordenação

  • A cobertura real de uma API é um grafo, e arquivos de teste são uma lista. Codificar esse grafo à mão é para onde vai toda a manutenção.

O quarto é a limpeza. Registros se acumulam, restrições de unicidade começam a disparar e as asserções de paginação vão se desviando conforme os dados crescem.

Por que esses não são exatamente problemas do Cypress

O Cypress foi desenhado em torno de um ciclo de vida de teste conduzido pelo navegador. Tudo o que está acima diz respeito a estado que vive fora de um único teste e fora de uma única execução. Dá para resolver tudo isso em arquivos de suporte, e a solução vira um pequeno framework que alguém precisa manter — que é o custo que ninguém planeja.

O que uma camada feita sob medida para API resolve no lugar

Quatro coisas decidem se uma suíte de API sobrevive ao primeiro ano, seja qual for a ferramenta: sessões que expiram, valores que só existem em tempo de execução, chamadas que dependem umas das outras e registros que ninguém limpa. A TestSprite chama isso de Auto-Authentication, Dynamic Variables, Dependency Chains e Auto-Cleanup, e a documentação de testes de API cobre como isso funciona.

Quando o arquivo de suporte vira um framework

Existe um ponto identificável em que uma suíte de API dentro do Cypress deixa de ser algumas requisições e vira infraestrutura, e vale a pena nomeá-lo para que você decida de forma deliberada em vez de ir à deriva.

Começa com um comando de login no arquivo de suporte. Depois um cache de token, porque fazer login a cada teste é lento. Depois a lógica de refresh, porque o cache fica obsoleto no meio da execução. Depois um helper que guarda os identificadores criados para que testes posteriores os encontrem, depois convenções de ordem nos nomes dos arquivos, depois uma tarefa de limpeza que roda ao fim da suíte e conhece tudo isso.

Nenhum desses passos está errado, e cada um é o próximo movimento óbvio. O resultado são algumas centenas de linhas de framework morando em um diretório de suporte, compreendidas por uma única pessoa e fora do runner sobre o qual foram construídas. Reconhecer essa trajetória cedo é todo o valor de descrevê-la.

A divisão que vale a pena adotar

Mantenha o cy.request para setup, teardown e as asserções entre camadas que realmente precisam dos dois lados em um mesmo teste. Mova a cobertura independente de endpoints e de integração para uma camada que trate esses quatro problemas como parte do próprio trabalho, e não como lição de casa sua.

As duas suítes não precisam saber uma da outra, e ambas podem rodar no mesmo pipeline.

O gatilho importa mais que o mecanismo. Apontá-lo 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 a partir do painel, e um passo do GitHub Actions faz isso de dentro do seu workflow. Detalhes no repositório da CLI.

O que você deixa de manter

O framework em arquivos de suporte descrito acima é justamente o que a TestSprite substitui. Auto-Authentication cuida da duração da sessão. Dynamic Variables levam um identificador da chamada de criação até a chamada de exclusão. Dependency Chains derivam uma ordem segura a partir do que cada caso precisa e produz. Auto-Cleanup remove exatamente o que a execução criou, que é o que torna a execução paralela segura.

A cobertura também deixa de depender de quem tem tempo. Os planos são gerados a partir de uma especificação ou de uma varredura de descoberta sobre o serviço em execução, incluindo os caminhos de erro e os valores de fronteira que nunca são escritos à mão, e são refinados em linguagem natural.

O Cypress fica com aquilo em que é bom: setup, teardown e as verificações entre camadas em que você realmente precisa do navegador e da API em um mesmo teste. Os dois rodam no mesmo pipeline sem saber um do outro.

cy.request é má prática?

De jeito nenhum. É a ferramenta certa para setup e para verificações entre camadas. O limite é de escala, não de correção.

Dá para manter tudo no Cypress?

Dá, e você vai acabar mantendo por conta própria o tratamento de sessão, a captura de valores, a ordenação e a limpeza. Vale a pena para uma superfície pequena; além disso, fica caro.

E os testes de componente do Cypress?

Nada disso os afeta. Testes de componente respondem a uma pergunta diferente e é melhor mantê-los onde estão.

Como evitar cobertura duplicada?

Divida pela pergunta. O Cypress responde se o fluxo visível ao usuário funciona. A camada de API responde se os endpoints se comportam como deveriam. Se um teste passaria nos dois lugares, ele pertence ao mais barato.

A camada de API precisa do nosso código-fonte?

Não. Ela trabalha contra o serviço em execução, usando uma especificação ou uma varredura de descoberta para saber o que existe.

A versão curta

Use cy.request para setup, não para a suíte de API inteira.

Testes de API com Cypress são excelentes para fixtures e asserções entre camadas. Quando a cobertura independente de API cresce, sessões, valores capturados, ordenação e limpeza viram um framework que você mantém à mão — e esse é o momento de mover essa camada para algo feito para isso.