Boas Práticas Nathan Geeksman

Automação de Testes em CI/CD: Falhando o build corretamente.

Automação de Testes em CI/CD: Falhando o build corretamente.

Automação de Testes em CI/CD: Falhando o build corretamente.

Introdução

A automação de testes é uma prática fundamental no desenvolvimento de software, pois permite garantir a qualidade e estabilidade dos sistemas. No contexto atual, a integração contínua (CI) e entrega contínua (CD) têm se tornado cada vez mais comuns, tornando-se essencial a automação de testes para evitar falhas nos builds.

A automação de testes não apenas garante que o código esteja correto, mas também ajuda a identificar problemas antes que eles afetem os usuários finais. Além disso, ao integrar a automação de testes com a CI/CD, é possível otimizar o tempo de desenvolvimento e entrega, reduzindo a quantidade de tempo gasto em revisões manuais.

Neste artigo, você aprenderá como realizar a automação de testes de forma eficaz, utilizando ferramentas de testes unitários e integração com as pipelines CI/CD. Além disso, vamos explorar práticas recomendadas para garantir que os builds sejam falhados corretamente, evitando assim problemas ao longo do tempo.

O que é e por que importa

A automação de testes unitários e de integração é um processo no qual scripts são escritos para automatizar a execução de testes em código, garantindo que as funcionalidades desenvolvidas funcionem corretamente. Isso inclui verificar se os inputs são tratados corretamente, se as saídas estão dentro dos limites esperados e se os erros são gerados corretamente.

A automação de testes é essencial para evitar problemas ao longo do tempo, pois permite identificar bugs e problemas antes que eles afetem os usuários finais. Ao integrar a automação de testes com as pipelines CI/CD, é possível otimizar o tempo de desenvolvimento e entrega, reduzindo a quantidade de tempo gasto em revisões manuais.

Além disso, a automação de testes garante que o código esteja correto, desde a pequena alteração até a grande refatoração. Isso impede que falhas sejam implantadas no sistema sem serem detectadas, reduzindo assim os custos e tempo perdido em problemas críticos.

A automação de testes também ajuda a garantir que as mudanças no código não afetem funcionalidades previamente desenvolvidas. Isso é especialmente importante quando há equipes diferentes trabalhando em diferentes partes do código, pois permite garantir que cada uma delas esteja fazendo as coisas corretas.

Por fim, a automação de testes ajuda a cumprir os objetivos de qualidade e segurança dos projetos. Ela garante que todos os critérios de aceitação estejam sendo atendidos e que as funcionalidades desenvolvidas estejam funcionando corretamente.

Com o uso correto da automação de testes, é possível garantir a qualidade do código, reduzindo assim o tempo e custo gastos em problemas críticos ao longo do tempo.

Como funciona na prática

A automação de testes é essencial para garantir a qualidade e integridade do código ao longo das diferentes etapas de desenvolvimento. Aqui está como ela funciona na prática:

  • Preparação: Antes de executar os testes, é necessário configurar o ambiente de execução, incluindo as bibliotecas e frameworks necessários para a execução dos testes.
  • Execução: O processo de automação de testes começa com a execução dos testes, que podem ser divididos em diferentes categorias, como:
  • Teste unitário: Verifica se cada unidade do código está funcionando corretamente.
  • Teste de integração: Verifica se as unidades funcionais estão integradas corretamente.
  • Teste de aceitação: Verifica se o sistema está cumprindo os requisitos previstos.
  • Análise: Após a execução dos testes, é necessário analisar os resultados obtidos. Isso pode incluir a análise das saídas esperadas e compará-las com as saídas obtidas.
  • Regressão: Se algum teste falhar, o processo de automação de testes deve entrar em uma etapa de regressão, onde será re-executado o conjunto de testes para verificar se a causa raiz do problema foi resolvida.

Nesse ciclo contínuo, é possível garantir que o código esteja correto e funcional ao longo das diferentes etapas de desenvolvimento.

Exemplo real

Vamos apresentar um exemplo de como a automação de testes pode ser implementada em uma pipeline de Continuous Integration/Continuous Deployment (CI/CD).

Suponha que tenhamos um projeto de desenvolvimento de software chamado "E-commerce" e que queremos garantir que as alterações feitas nos códigos não comprometam a funcionalidade do sistema. Para isso, vamos criar uma pipeline de CI/CD com a seguinte estrutura:


// Etapa 1: Compilar o código
pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                sh 'mvn clean package'
            }
        }
        // Etapa 2: Executar os testes unitários e de integração
        stage('Teste Unitário') {
            steps {
                sh './gradle test --tests com.example.EcommerceApplicationTests'
            }
        }
        stage('Teste de Integração') {
            steps {
                sh './gradle test --tests com.example.IntegrationTests'
            }
        }
        // Etapa 3: Executar os testes de aceitação
        stage('Teste de Aceitação') {
            steps {
                sh './gradle test --tests com.example.AcceptanceTests'
            }
        }
    }
}

Nesse exemplo, estamos utilizando o Jenkinsfile para definir a pipeline de CI/CD. A etapa 1 consiste em compilar o código utilizando Maven. As etapas 2 e 3 consistem em executar os testes unitários e de integração, respectivamente. Caso algum dos testes falhem, a pipeline entrará em uma etapa de regressão para verificar se a causa raiz do problema foi resolvida.

Essa é apenas uma visão geral de como a automação de testes pode ser implementada em uma pipeline de CI/CD. É importante lembrar que a configuração exata depende das necessidades específicas do projeto e da tecnologia utilizada.

Boas práticas

Executar testes em paralelo

  • Utilizar ferramentas como parallel para executar testes unitários e de integração em paralelo, reduzindo o tempo de execução da pipeline.

Manter testes isolados

  • Evitar compartilhar estado entre testes, garantindo que cada teste seja executado independentemente dos outros, facilitando a depuração e manutenção.

Utilizar técnicas de mockagem

  • Utilizar bibliotecas de mockagem como Mockito para isolar dependências e permitir que os testes sejam executados em isolamento.

Armadilhas comuns

  • ### Testar código "limpo"
  • Esquecer de limpar o estado do sistema antes de executar os testes, causando falhas na pipeline.
  • Utilizar técnicas como mockagem e injeção de dependência para evitar alterações no comportamento do sistema.

Testar códigos complexos

  • Executar testes nos componentes mais simples de um sistema em vez de em seus componentes mais complexos, comprometendo a confiabilidade da pipeline.
  • Utilizar técnicas como divisão e conquista para dividir os testes em componentes menores e executáveis.

Conclusão

Implementar a automação de testes em uma pipeline CI/CD é fundamental para garantir a qualidade e confiabilidade do software. Além disso, é crucial evitar armadilhas como o teste de código "sujo" ou executar testes nos componentes mais complexos. Proximos passos incluem:

  • Continuar refinando os testes unitários e de integração para garantir a cobertura dos requisitos do projeto.
  • Implementar técnicas de mockagem e injeção de dependência para evitar alterações no comportamento do sistema durante os testes.
  • Dividir os testes complexos em componentes menores e executáveis utilizando técnicas como divisão e conquista.

Referências

  • Martin Fowler. Mock Objects. Disponível em: https://martinfowler.com/articles/mockObjects.html. Acesso: 2024.
  • ThoughtWorks. Test-Driven Development by Example. Disponível em: https://www.thoughtworks.com/insights/blog/test-driven-development-example. Acesso: 2024.
  • OWASP. Testing for Code Injection (OTG-INJ-001). Disponível em: https://owasp.org/www-content/library/html/testing-guide/en/0c.html#5C1E7F2. Acesso: 2024.
  • Martin Fowler. Dependency Injection. Disponível em: https://martinfowler.com/articles/injection.html. Acesso: 2024.
  • J.B. Rainsberger. . (entrevista). Disponível em: https://www.infoq.com/interviews/jeff-rainsberger-test-driven-development/. Acesso: 2024.
  • Wikipedia. Behavior Driven Development. Disponível em: https://en.wikipedia.org/wiki/Behavior_driven_development#cite_note-5. Acesso: 2024.