O objetivo deste post é destacar a importância da fase de testes no loop infinito do DevOps, além de apresentar as ferramentas, frameworks e métodos, os tipos de testes e uma visão geral do ecossistema da AWS e dos serviços disponíveis para implementar as boas práticas de DevOps e, em especial, a fase de testes. Este não é um post técnico, e sim um conteúdo mais abrangente e informativo. Não traz detalhes técnicos sobre como configurar uma pipeline ou fazer deploy do código na sua infraestrutura, mas sim uma explicação dos pontos principais, das opções e dos serviços envolvidos.
Fase de testes
As práticas de DevOps exigem entregas rápidas de software, com a possibilidade de vários deployments por dia. Para atender a esses requisitos, os times precisam conseguir testar o código em minutos e com a maior frequência possível. A fase de testes determina se o build está pronto para avançar para o próximo estágio ou se será bloqueado com base nos resultados dos testes, sem nenhuma intervenção humana.
Testar software é uma etapa essencial do Software Development Life Cycle (SDLC): conseguir detectar bugs cedo e resolvê-los antes do release em produção tem um valor enorme. Incluir uma fase de testes na sua pipeline traz o grande benefício de identificar bugs existentes. Nessa fase, usamos ferramentas de teste automatizado, que variam conforme a aplicação. Por exemplo, ferramentas como o Newman são uma maneira fácil de testar os métodos públicos da sua API; JUnit/Xunit ou Jest são ótimos para testes unitários do seu código e dos seus componentes; e Playwright ou Cypress são ideais para implementar testes e2e completos até o nível de UI, caso sua aplicação seja Web.
A fase de testes também é o momento em que você pode integrar ferramentas de gestão de testes como o TestRail. Ela gera relatórios completos sobre o codebase e os resultados dos testes, dando aos stakeholders uma visão clara do ciclo de desenvolvimento e da maturidade da aplicação. Esse tipo de recurso ajuda os stakeholders da sua empresa a entender melhor o ciclo de desenvolvimento e a maturidade do produto. Vale adotar uma mentalidade em que a qualidade está em todos os cantos da organização, e não apenas dentro dos limites de um departamento de QA. Essa mentalidade vai te ajudar a alcançar os melhores resultados, e a fase de testes vai pavimentar o caminho do sucesso nessa jornada.
Por que a fase de testes é importante
O benefício mais importante e crítico da fase de testes é permitir que os testes, a validação de qualidade e a avaliação de performance aconteçam o mais cedo possível no SDLC. Essa prática de shift left rompe com os testes tradicionais ou manuais, que costumam ficar para o final do ciclo.

Veja alguns benefícios evidentes da fase de testes:
- Implementar testes cedo no SDLC viabiliza um processo de teste contínuo, possibilitando entregas mais rápidas e contínuas de software. Essa abordagem favorece testar de forma rápida, frequente e antecipada, reduzindo o risco de erros passarem despercebidos.
- Automatizar os testes elimina o fator humano de deixar erros escaparem, embora exija a manutenção e a atualização dos cenários de teste. Por isso, pode ser necessário ter um time dedicado de desenvolvedores focado em testes.
- Cada etapa do SDLC envolve diferentes formas de teste (testes unitários, testes de API, e2e e testes de UI). Isso reduz o retrabalho quando algum erro é detectado.
Implementar essa fase reduz o tempo de entrega das aplicações e minimiza erros e bugs, ajudando a estabelecer um modelo de responsabilidade compartilhada pela qualidade, em que toda a área de Engenharia responde pela qualidade da aplicação.
Sobre a Pirâmide de Testes
A Pirâmide de Testes é um conceito bastante conhecido no desenvolvimento de software e já apareceu em vários artigos e publicações, mas a descrição original é de Mike Cohn, no livro Succeeding with Agile. A metáfora da pirâmide ajuda a visualizar as diferentes camadas de teste que devem ser implementadas no desenvolvimento de software.

Os testes Behavior-Driven são os mais eficazes, pois incorporam cenários de teste e resultados esperados. Esses testes pressupõem cobrir a integração entre componentes, o que torna os testes de integração os mais valiosos, já que validam o sistema como um todo ou em módulos isolados e complexos, em vez de apenas unidades individuais. Por isso, pode parecer que investir em testes e2e de UI (executados sobre o sistema depois de implantado e totalmente integrado) é uma ótima ideia — e, de fato, é. Mas também tem suas armadilhas: por exemplo, contar apenas com testes e2e de UI pode levar a gastos desproporcionais, dor de cabeça com manutenção e estresse.
Investir exclusivamente em testes end-to-end de UI costuma resultar no antipadrão de "casquinha de sorvete" na pirâmide de testes, também chamado de pirâmide de testes atípica ou invertida.

A manutenção dessa casquinha vira um pesadelo, o custo pode sair do controle, os resultados dos testes podem ficar inconsistentes e sua organização provavelmente vai perder os benefícios de uma fase de testes bem estruturada.
Agora podemos passar pelas camadas da Pirâmide de Testes, pelos tipos de teste mais populares e pelos benefícios de cada um.
- Testes unitários: os mais básicos e granulares, focados em uma unidade de trabalho — geralmente um método ou um componente. Ficam na base da Pirâmide de Testes e podem ser compilados e executados dentro do estágio de Build. São fáceis de implementar, baratos e simples, e funcionam como uma primeira linha de defesa quando o assunto é qualidade de código.
- Testes de integração/Testes de API: a integração é feita pela API, então testar essa camada é fundamental para os seus sistemas. Esses testes precisam validar a capacidade do sistema de funcionar de forma integrada (ou seja, garantir que as unidades de trabalho conseguem coexistir e operar em conjunto). Podem ser implementados por desenvolvedores ou por profissionais de qualidade, dependendo da estrutura da organização. No fim das contas, ninguém quer embarcar num avião que passou apenas por testes unitários.
Automação de testes é…
Quando você tem uma quantidade cada vez maior de software sob sua responsabilidade — ou mesmo quando ela é relativamente estática —, fica difícil testar a aplicação manualmente. Garantir que o processo repetitivo seja feito do jeito certo e reduzir o fator de erro humano é praticamente impossível quando tudo é feito de forma manual. É aí que a automação entra em cena. A automação virou padrão em praticamente tudo: da infraestrutura à orquestração dos seus builds, passando pelos testes do seu código e das suas aplicações.
Na prática, isso significa que os desenvolvedores vão focar em escrever testes unitários e de integração como parte das entregas ou tarefas, enquanto os profissionais de qualidade vão focar nos testes e2e de UI, com base em cenários fornecidos pelo negócio ou pelos product owners. A fase de descoberta de testes, feita majoritariamente por meio de testes manuais, seria uma etapa pré-requisito antes da automação.
Para automatizar a fase de testes, você pode usar uma das ferramentas disponíveis hoje no mercado. As possibilidades são infinitas e dependem principalmente das suas necessidades e das competências da sua área de desenvolvimento. Playwright e Cypress vão te ajudar a atingir os objetivos com foco em testes e2e de UI; ambas têm prós e contras e, hoje em dia, dá até para usá-las como solução única (cobrindo todas as camadas da sua Pirâmide de Testes), se sua stack for em JS, por exemplo. Outra camada é a de integração, e a variedade de ferramentas também é bem ampla: Katalon, Newman da Postman, entre outras. Sempre avalie as funcionalidades e leve em conta a complexidade, a interoperabilidade e a capacidade de ser integrada à pipeline de CI/CD (afinal, todo o propósito dessas ferramentas é poder integrá-las à sua fase de testes, ou seja, incluí-las na sua pipeline de CI/CD). Por último, mas não menos importante, está a camada de testes unitários. Para escrevê-los e executá-los, use as ferramentas que combinam melhor com o seu codebase: para código .Net, dá para usar XUnit; para Java, JUnit; e para código em JS ou TS, Jest (ou, como mencionei acima, ferramentas como o Playwright, que são modernas e versáteis e, se seu codebase for em JS ou TS, permitem testar toda a sua pirâmide. Consulte a documentação oficial do Playwright).
AWS CodePipeline para implementar sua fase de testes
A fase de testes pode ser implementada usando diferentes ferramentas e serviços que existem hoje no mercado. Soluções como Jenkins e CircleCI permitem executar os mesmos passos para alcançar os resultados desejados: você precisa puxar o código do repositório > fazer o Build > testar > fazer Deploy para Pré-Produção (Staging) > opcionalmente testar de novo > fazer Deploy para Produção. Pronto, o deployment foi concluído.

Existem muitas ferramentas e serviços por aí, mas vamos falar dos serviços da AWS. O AWS CodePipeline é um serviço totalmente gerenciado de continuous delivery (CD) que ajuda a construir pipelines, orquestrar estágios e entregar atualizações para sua aplicação e infraestrutura. O AWS CodePipeline funciona muito bem com outros serviços DevOps da AWS, como AWS CodeDeploy, AWS CodeCommit e AWS CodeBuild, além de provedores de ações de terceiros bastante conhecidos, como Jenkins e Github.
O caso de uso simples para a pipeline é: Pull do código > Build > Deploy. Parece simples e, nesse cenário, você só consegue executar os testes unitários no estágio de Build da pipeline. Ótimo! Mas e quando você quer ter uma pipeline mais complexa, com fase de testes que inclua testes de integração e até testes e2e de UI? Aí a pipeline fica assim: Pull do código > Build > Deploy para Staging > Testar > Deploy para Produção. A diferença é que, ao estender a pipeline, adicionamos o estágio de testes que pode rodar testes de integração e/ou testes e2e de UI contra o ambiente de Staging implantado no estágio anterior. Ficou bem melhor!! Adicionar a fase de testes aqui é direto: basta incluir o passo extra (Stage) pela página de edição da pipeline existente e configurar a execução dos seus testes usando o framework nativo de execução (depende da ferramenta de teste que você usa).
Como esse serviço é versátil e interage com muitos outros serviços da AWS e de terceiros, é difícil escolher um único exemplo, mas vale destacar algumas funcionalidades úteis e importantes do AWS CodePipeline:
Opção de detecção: é uma propriedade da pipeline que a inicia com base no local de origem dos artefatos. A AWS recomenda usar webhooks do Github para o Github ou Amazon CloudWatch Events para artefatos armazenados em um bucket do AWS S3, por exemplo.
Desabilitar/Habilitar transição: a transição liga os estágios da pipeline e fica habilitada por padrão. Se, por algum motivo, você não quiser avançar automaticamente de um estágio para outro, basta desabilitar clicando no botão "Disable transition". Com isso, a execução contínua da pipeline é interrompida. Reativar depois é fácil.
Adicionar Stage: para editar a sequência da pipeline e introduzir um novo estágio ou remover/atualizar um existente, clique em "Edit" na pipeline. Isso vai te levar para a página de edição, onde dá para adicionar ações ao seu estágio em série ou em paralelo às ações já existentes. Essa funcionalidade torna sua pipeline flexível e extensível.
Approval Action: quando você quiser gerenciar os estágios da pipeline — por exemplo, exigir que alguém aprove o estágio de deploy —, pode usar essa funcionalidade. Ela pausa a pipeline até a aprovação e retoma a execução depois que ela acontece.
Outros serviços DevOps da AWS com os quais o CodePipeline funciona e se integra bem:
- AWS CodeCommit
- AWS CodeDeploy
- AWS CodeBuild
Resumo e conclusão
Nenhuma pipeline deveria existir sem uma fase de testes, e nenhum release deveria sair sem passar por ela. Minimize o fator humano e conte com a automação e com as ferramentas disponíveis — esse deve ser o foco do especialista de DevOps responsável pelo CI/CD. E não só dele, que provavelmente vai construir a pipeline, mas de toda a área de desenvolvimento, incluindo Developers, equipe de QA e o time de DevOps. A abordagem certa é enxergar a qualidade como responsabilidade de todos e ver a fase de testes como uma etapa disponível, conveniente, flexível e à prova de falhas. Usar um serviço apropriado, como o AWS CodePipeline, vai ajudar a alcançar os resultados desejados!
Links e recursos: