Olá! Bem-vindo de volta ao Módulo 9 do nosso curso.
Nas lições anteriores, estabelecemos os dois primeiros portões de qualidade para o seu agente: o linting para garantir a conformidade do estilo e o build para verificar a correção da sintaxe e das dependências. Um código que compila, no entanto, não é necessariamente um código que funciona corretamente.
Nesta lição, vamos implementar o próximo portão de qualidade, que foca na validação da lógica do seu código. O objetivo é aprender a identificar e executar testes de unidade relevantes para validar a lógica do código gerado. Este é um passo crucial para garantir que as funcionalidades implementadas ou corrigidas pelo seu agente se comportem como esperado.
1. Por Que Validar a Lógica com Testes de Unidade?
Uma etapa de build bem-sucedida apenas confirma que o código-fonte pode ser transformado em um artefato executável. Ela não diz nada sobre se a lógica de negócios está correta. O agente de IA pode gerar um método que compila perfeitamente, mas que retorna o resultado de a - b em vez de a + b.
É aqui que entram os testes de unidade. Eles servem para verificar pequenas "unidades" isoladas de código — como um método em C# ou um componente React — para garantir que, para um conjunto de entradas conhecidas, elas produzam as saídas esperadas.
Para o seu agente, a execução automatizada de testes é a principal maneira de obter um feedback rápido sobre a correção funcional do código que ele produz.
2. Executando Testes de Unidade no Pipeline de CI
Assim como nas etapas de lint e build, o GitHub Actions é a ferramenta ideal para automatizar a execução de testes sempre que seu agente criar um Pull Request. Vamos ver como configurar isso para as tecnologias do seu stack.
Para o Backend .NET/C#
Em projetos .NET, o comando dotnet test é usado para descobrir e executar testes. O vídeo a seguir, embora um pouco longo, oferece uma visão abrangente de como integrar isso em um fluxo de trabalho do GitHub Actions.
Running Unit Tests with GitHub Actions (10 of 12) | Automated Software Testing
O vídeo 'Running Unit Tests with GitHub Actions' do canal Microsoft Visual Studio demonstra o processo completo de configuração de testes .NET em um pipeline de CI.
Assista aos seguintes segmentos para entender os principais conceitos: 03:07 - 05:12: Foco em como o arquivo YAML é configurado com a etapa run: dotnet test. Observe que isso se baseia na estrutura que você já viu para dotnet build. 05:12 - 07:29: Preste atenção à discussão sobre por que a Integração Contínua (CI) é tão importante. Isso reforça a ideia de que os testes no CI servem como uma verificação de sanidade para todo o time, evitando o clássico "mas funcionava na minha máquina". 13:28 - 24:12: Esta seção aborda um ponto prático muito útil: como publicar e visualizar os resultados dos testes. Ela mostra como usar uma ação do Marketplace para processar um arquivo de resultados de teste (formato TRX) e exibi-los diretamente na interface do GitHub. Seu agente poderia, no futuro, analisar esses arquivos de resultados estruturados.
Integrar isso em seu fluxo de trabalho é simples. Você adiciona uma nova etapa após a etapa de build:
- name: Test
run: dotnet test MySolution.sln --no-build --verbosity normal --logger "trx;LogFileName=test-results.trx"
- A flag
--no-buildé uma otimização; como já executamos uma etapa debuildantes, não precisamos compilar o código novamente. - O argumento
--loggerinstrui odotnet testa gerar um arquivotest-results.trx, que pode ser usado pela etapa de publicação de resultados demonstrada no vídeo.
Para o Mobile com Dart/Flutter
O ecossistema Flutter também possui um conjunto robusto de ferramentas de teste, que podem ser executadas com o comando flutter test.
Flutter GitHub Actions - Automate Your Workflow
Este vídeo de Robert Brunhage, 'Flutter GitHub Actions - Automate Your Workflow', mostra como configurar um pipeline de CI para um projeto Flutter.
Assista a estas duas seções para ver a teoria e a prática em ação: 01:31 - 03:53: Veja como o arquivo de fluxo de trabalho YAML é construído. Observe as etapas para configurar o Java (uma dependência do SDK do Android) e o Flutter, seguidas pelos comandos flutter analyze (semelhante ao linting) e flutter test. 04:20 - 06:22: Esta é uma demonstração prática do poder do CI. O apresentador quebra um teste de propósito, e o pipeline do GitHub Actions falha, bloqueando o Pull Request. Em seguida, ele corrige o teste, e o pipeline passa. Isso ilustra perfeitamente o ciclo de feedback que seu agente utilizará.
Seu fluxo de trabalho para Flutter incluiria uma etapa como esta:
- name: Analyze and Test
run: |
flutter analyze
flutter test
Para o Frontend React/JS
Em um projeto React configurado com create-react-app, os testes (geralmente escritos com Jest e React Testing Library) são executados com npm test.
A etapa no seu fluxo de trabalho do GitHub Actions, após a instalação das dependências com npm ci, seria:
- name: Test
run: npm test -- --watchAll=false
A flag --watchAll=false é importante em um ambiente de CI. Por padrão, npm test entra em modo interativo ("watch mode"), aguardando por alterações nos arquivos. Essa flag garante que os testes sejam executados uma vez e que o processo termine, permitindo que o pipeline continue (ou falhe, se um teste quebrar).
3. Identificando Testes Relevantes: Test Impact Analysis (TIA)
Executar todos os testes de unidade em cada commit pode se tornar lento e caro à medida que o projeto cresce. Uma estratégia mais eficiente é executar apenas os testes que são relevantes para o código que foi alterado. É disso que trata a Test Impact Analysis (TIA).
A ideia central da TIA é mapear o código de produção aos testes que o exercitam. Quando uma parte do código de produção muda, você usa esse mapa para identificar e executar apenas o subconjunto de testes afetado.
The Rise of Test Impact Analysis
Para entender profundamente este conceito, vamos estudar o artigo clássico de Martin Fowler, 'The Rise of Test Impact Analysis'. Ele fornece uma base teórica e prática sólida.
Leia as seguintes seções do artigo: Introdução: A primeira seção, sob o título principal, define o que é TIA e seu objetivo principal: acelerar a automação de testes. 'Test Impact Analysis': Esta seção explica como a TIA funciona em princípio, usando ferramentas de cobertura de código para criar um mapa de dependências entre o código de produção e os testes. 'Microsoft's extensive TIA work': Dado seu background com .NET, esta seção é particularmente relevante. Ela detalha como a Microsoft implementou a TIA, criando um mapa dinâmico Testcasemethod <--> source_file.cs durante a execução dos testes.
Implementar a TIA para seu agente seria um recurso avançado, mas o processo geral seria:
- Fase de Mapeamento (periódica): Executar cada teste isoladamente e, usando uma ferramenta de cobertura de código, registrar quais arquivos-fonte de produção foram "tocados". Isso cria um mapa, por exemplo:
{'UserService.cs': ['TestUserCreation', 'TestUserUpdate'], 'OrderService.cs': ['TestOrderPlacement']}. - Fase de Execução (no PR do agente):
a. O agente faz um commit alterandoUserService.cs.
b. O pipeline de CI identifica os arquivos alterados.
c. Ele consulta o mapa da TIA e descobre que apenasTestUserCreationeTestUserUpdateprecisam ser executados.
d. O comando de teste é invocado com um filtro para executar apenas esses testes, economizando o tempo de execução deTestOrderPlacement.
4. Indo Além: A Qualidade dos seus Testes
Ter testes que passam é bom, mas como você sabe se seus testes são realmente eficazes em detectar bugs? É possível ter 100% de cobertura de código e ainda assim ter uma suíte de testes fraca.
É aqui que entra o Mutation Testing. A ideia é introduzir pequenas "mutações" (bugs) deliberadas no seu código em tempo de execução (ex: trocar um > por um >=) e verificar se seus testes de unidade falham.
- Se um teste falha, a mutação é "morta". Isso é bom! Significa que seu teste detectou o bug.
- Se nenhum teste falha, a mutação "sobreviveu". Isso é um sinal de que sua suíte de testes tem um ponto cego.
Rovo Dev CLI and Mutation Testing to Write Better Tests
O ecossistema Atlassian está explorando ativamente como a IA pode interagir com o mutation testing. Este post do blog de engenharia da Atlassian é uma leitura fascinante que conecta diretamente com seus objetivos.
Leia este artigo para entender: 'What is mutation testing...': A definição do conceito e por que ele é mais valioso que a simples cobertura de linha. 'Mutation Testing with Java': Ignore a sintaxe Java e foque no exemplo. Veja como um teste que parece bom (100% de cobertura) pode ser ineficaz, e como o relatório de mutação (SURVIVED vs. KILLED) revela essa fraqueza. 'Using Rovo Dev CLI...': Esta é a parte mais importante. Veja como eles instruem o Rovo Dev (um agente de IA) a usar os resultados do mutation testing como um objetivo. O agente tem a tarefa de escrever novos testes especificamente para "matar" as mutações que sobreviveram, melhorando ativamente a qualidade da suíte de testes. Este é um exemplo perfeito de um agente de codificação avançado em ação.
5. O Ciclo de Feedback para Falhas nos Testes
Assim como nas falhas de build, as falhas nos testes são uma fonte valiosa de feedback para o seu agente se auto-corrigir. O ciclo é muito semelhante:
- O agente envia o código para um PR, o que aciona o pipeline de CI.
- O build passa, mas um ou mais testes de unidade falham.
- O agente (ou seu orquestrador) recupera os logs de falha dos testes. Esses logs geralmente são bem estruturados (ex: formato TRX, JUnit XML) e contêm detalhes como: "Teste
TestUserCreation: Esperadotrue, mas recebeufalse". - Essas informações são formatadas e enviadas de volta ao LLM com um prompt como: "O código gerado falhou no seguinte teste de unidade: [detalhes da falha]. A lógica parece estar incorreta. Analise o erro e forneça a versão corrigida do método."
- O agente aplica a correção, faz o commit e aciona o pipeline novamente, repetindo o ciclo até que todos os testes passem.

Conclusão
Nesta lição, você adicionou um dos mais importantes portões de qualidade ao seu pipeline: a validação da lógica do código. Agora, seu agente não está apenas escrevendo código que compila, mas pode começar a verificar se ele funciona como o esperado.
Principais Pontos:
- Testes de Unidade validam a lógica funcional do código gerado, indo além da verificação de sintaxe do build.
- Os comandos
dotnet test,npm testeflutter testsão os pilares para executar testes em seus respectivos stacks e podem ser facilmente integrados em fluxos de trabalho do GitHub Actions. - Test Impact Analysis (TIA) é uma técnica avançada para otimizar o tempo do pipeline, executando apenas os testes relevantes para as alterações de código.
- Mutation Testing é uma forma ainda mais sofisticada de avaliar a qualidade e eficácia da sua suíte de testes, servindo como um excelente objetivo para um agente de IA auto-aperfeiçoável.
- As falhas nos testes são um feedback essencial para o ciclo de auto-correção do agente.
Até agora, seu pipeline pode executar os testes e relatar sucesso ou falha. Mas como o agente pode, programaticamente, saber quais testes falharam e por quê?
Na próxima lição, vamos mergulhar nesse tópico: "Implementar um processo para analisar os resultados dos testes e determinar se o código gerado atende aos padrões de qualidade." Você aprenderá a consumir e interpretar os arquivos de resultado (como TRX ou JUnit XML) para alimentar seu ciclo de feedback de forma mais inteligente.