Por que os testes de API com Selenium sequer entram em pauta
Três motivos, e só um deles é bom.
A suíte já existe. Já existe um job do Selenium no CI, as pessoas sabem executá-lo e acrescentar verificações de API ali é o caminho de menor resistência. É compreensível, mas é uma razão organizacional, não técnica.
O fluxo passa pelos dois. Enviar um formulário e depois confirmar que o registro criado pela API está correto. Esse caso é legítimo e é aquele para o qual vale a pena projetar.
Setup e teardown. Criar fixtures pela API porque fazer isso pela interface é lento. Faz sentido, embora seja trabalho de infraestrutura, não de teste.
O que isso custa
| Feedback lento | A inicialização do navegador domina uma verificação que poderia ter sido uma requisição. Uma suíte que leva vinte minutos é executada com menos frequência, e essa é a perda real. |
| Falhas confusas | Quando um teste combinado falha, você precisa descobrir se quebrou a interface ou a API. Suítes separadas entregam essa resposta de graça. |
| Cobertura moldada pela UI | Você acaba cobrindo os endpoints que a interface por acaso chama, o que é uma fração da superfície. Códigos de erro e parâmetros de borda nunca são exercitados. |
A divisão que funciona
Use o Selenium para o que só um navegador consegue responder: o fluxo visível para o usuário funciona. Cubra a API no nível dela, onde uma verificação é uma requisição, e não o carregamento de uma página. Use a API dentro da suíte Selenium apenas para setup e teardown, onde o que importa é velocidade e não há nenhuma asserção envolvida.
O único caso realmente transversal, enviar um formulário e verificar o que o backend armazenou, merece ser escrito de forma deliberada, e não por acaso. São poucos testes, e eles compensam o custo.
O que uma camada de API independente precisa resolver
Quatro coisas determinam 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 os detalhes de funcionamento.
Acertar esses quatro pontos é o que separa uma suíte que dura de uma que é apagada depois de dois trimestres, e isso é muito mais fácil de fazer no nível da API do que enxertado em uma suíte de navegador.
O caso de setup, feito do jeito certo
Usar a API para criar fixtures de um teste de navegador é o único ponto em que essas duas coisas realmente andam juntas, e vale a pena fazer isso de forma deliberada, e não por acaso.
A regra que mantém tudo limpo é que chamadas de setup nunca fazem asserção. O trabalho delas é colocar o sistema em um estado conhecido o mais rápido possível e, se uma delas quebrar, o teste deve dar erro em vez de falhar, porque uma fixture que não funcionou é um problema de infraestrutura, não um defeito do produto. Misturar as duas coisas produz uma suíte em que metade do vermelho é ruído.
A segunda regra é que tudo o que o setup criou o teardown remove, vinculado àquele teste em vez de identificado por nome. Suítes de navegador acumulam dados mais rápido do que qualquer um espera, e uma tela de listagem que fica mais lenta a cada semana normalmente é um teardown que nunca foi escrito.
Executando as duas
Nenhuma das suítes precisa saber da outra. O Selenium roda no seu job de CI como já roda hoje, e a cobertura de API roda ao lado.
Se o pipeline pertence a outro time, o GitHub App é o caminho de menor resistência: é um webhook, não muda nada no seu repositório e dispara quando o seu build informa que a nova versão está no ar. Se você prefere que a verificação fique visível no repositório, um passo do GitHub Actions faz isso. Veja o repositório do CLI.
O que a TestSprite cobre no nível da API
A TestSprite cuida da camada de API independente para que você não precise enxertá-la em uma suíte de navegador. O API Discovery enumera o que o serviço em execução expõe, o Plan Generation propõe casos nas categorias funcional, de schema, de autorização, de tratamento de erros e de limites, e você os refina em linguagem simples.
Os quatro problemas de estado vêm como produto, e não como infraestrutura sua: o Auto-Authentication mantém as sessões vivas, as Dynamic Variables levam valores de uma chamada para outra, as Dependency Chains derivam a ordem de execução, o Auto-Cleanup remove o que uma execução criou. São essas as coisas que tornam difícil manter uma suíte de API viva, e elas são muito mais fáceis de resolver no nível da API do que dentro de um runner de navegador.
Sua suíte Selenium continua onde está, cobrindo o que só um navegador consegue responder. As duas rodam a partir do mesmo pipeline.
O Selenium consegue enviar requisições HTTP diretamente?
Pelos bindings da linguagem, sim, porque você está apenas escrevendo código. A questão é se uma sessão de navegador deveria estar envolvida, e para uma verificação puramente de API a resposta costuma ser não.
Devemos migrar nossa suíte Selenium?
Não por completo. Uma suíte Selenium em que as pessoas confiam é um ativo. Acrescente cobertura de API no nível dela, em vez de mover qualquer coisa.
Como testamos um fluxo que passa pelos dois?
Escreva-o como um único teste, de forma deliberada, mantenha a quantidade pequena e deixe a asserção específica o bastante para que uma falha diga qual dos lados quebrou.
O Playwright é melhor para isso?
Ele tem uma API de requisições de primeira classe, então a mecânica é mais agradável. O argumento arquitetural não muda: verificações de navegador e verificações de API respondem a perguntas diferentes e é melhor mantê-las separadas.
E a autenticação nos dois lados?
Compartilhe a fonte das credenciais, não a sessão. Cada camada deve obter a própria sessão, para que uma falha em uma não se propague para a outra.
Use o navegador para perguntas de navegador.
Testes de API com Selenium normalmente significam coordenar dois tipos de verificação, em vez de forçar uma única ferramenta a fazer as duas coisas. Use o Selenium para os fluxos visíveis ao usuário, cubra a API no nível dela e escreva de propósito os testes realmente transversais.