Testes no pipeline
Nesta aula, você aprenderá a integrar diferentes tipos de testes (unitários, integração e E2E) em um pipeline de CI/CD, quando executá-los, como usar a qualidade como gate e como medir cobertura de código. Serão apresentados exemplos práticos com bash para configuração de pipelines.
Nesta aula, vamos explorar como integrar testes no pipeline de CI/CD, garantindo que o código entregue tenha qualidade. Testes são essenciais para detectar regressões e validar funcionalidades antes da implantação. Abordaremos os tipos de testes, o momento ideal para executá-los, como usar métricas de qualidade como gate e a importância da cobertura de código.
Um pipeline bem estruturado executa testes em diferentes estágios, permitindo feedback rápido e evitando que problemas cheguem à produção. Vamos detalhar cada tipo de teste e como configurá-los no pipeline.
Testes unitários, integração, E2E
Testes unitários verificam pequenas unidades de código (funções, métodos) de forma isolada, geralmente com mocks de dependências externas. São rápidos e devem ser executados primeiro no pipeline. Exemplo com pytest (Python):
pytest tests/unit/ --junitxml=report-unit.xmlTestes de integração validam a interação entre componentes, como acesso a banco de dados ou APIs. Eles são mais lentos e exigem ambiente preparado. Exemplo com docker-compose:
docker-compose up -d
pytest tests/integration/ --junitxml=report-integration.xml
docker-compose downTestes E2E (end-to-end) simulam o fluxo completo do usuário, testando a aplicação como um todo. São os mais lentos e frágeis, mas essenciais para validar cenários críticos. Exemplo com Cypress:
npx cypress run --reporter junit --reporter-options 'mochaFile=report-e2e.xml'Quando rodar cada um
Em um pipeline, a ordem de execução deve ser: primeiro os testes unitários (rápidos), depois os de integração e, por fim, os E2E. Isso permite falhar rápido e economizar recursos. Em um pipeline de CI/CD, você pode definir stages:
stages:
- unit
- integration
- e2e
unit:
script: pytest tests/unit/
integration:
script: docker-compose up -d && pytest tests/integration/ && docker-compose down
e2e:
script: npx cypress runSe os testes unitários falharem, o pipeline para e não executa os demais. Isso evita desperdício de tempo e recursos. Em ambientes de deploy contínuo, os testes de integração e E2E podem ser executados em paralelo após os unitários passarem.
Qualidade como gate
Qualidade como gate significa que métricas de qualidade (como cobertura de código, número de falhas, tempo de execução) são usadas para decidir se o pipeline prossegue ou não. Por exemplo, se a cobertura cair abaixo de um limite, o pipeline falha. Ferramentas como SonarQube ou Codecov podem ser integradas. Exemplo de script para verificar cobertura mínima de 80%:
coverage=$(grep -oP 'line-rate=\"\K[^\"]+' coverage.xml | head -1)
threshold=0.8
if (( $(echo "$coverage < $threshold" | bc -l) )); then
echo "Cobertura $coverage abaixo do limite $threshold"
exit 1
fiOutro gate comum é a quantidade de testes falhos. Se houver falhas, o pipeline é interrompido. Isso garante que apenas código de qualidade seja promovido para os próximos estágios.
Cobertura
Cobertura de código mede a porcentagem de linhas, branches ou funções executadas pelos testes. Ferramentas como pytest-cov, Istanbul (JS) ou gcov (C/C++) geram relatórios. Exemplo de geração de relatório com pytest-cov:
pytest --cov=src --cov-report=xml:coverage.xmlO relatório XML pode ser publicado em ferramentas como SonarQube ou Codecov. É importante definir um limite mínimo aceitável (ex: 80%) e monitorar a evolução. No entanto, cobertura não é garantia de qualidade; testes mal escritos podem ter alta cobertura sem testar cenários importantes. Use cobertura como um dos indicadores, não o único.
Boas práticas
- Mantenha os testes unitários independentes e rápidos.
- Use mocks para isolar unidades.
- Execute testes de integração em ambientes limpos (containers).
- Priorize testes E2E para fluxos críticos.
- Defina gates realistas e ajuste conforme necessário.
- Publique relatórios de teste e cobertura para visibilidade.
Referências
- GitLab CI/CD Testing
- GitHub Actions - Building and testing
- pytest documentation
- Cypress documentation
- SonarQube documentation
- Codecov documentation
- Practical Test Pyramid - Martin Fowler
Exercícios
- Explique a diferença entre teste unitário e teste de integração, com exemplos.
- Escreva um script bash que execute testes unitários e, se falharem, interrompa o pipeline.
- Como configurar um gate de qualidade baseado em cobertura mínima de 70%? Dê um exemplo de script.
- Cite três ferramentas de cobertura de código e para quais linguagens são usadas.
- Descreva um cenário onde testes E2E são mais importantes que testes unitários.
#!/bin/bash
pytest tests/unit/ --junitxml=report.xml
if [ $? -ne 0 ]; then
echo "Testes unitários falharam"
exit 1
ficobertura=$(grep -oP 'line-rate="\K[^"]+' coverage.xml | head -1)
if (( $(echo "$cobertura < 0.7" | bc -l) )); then
echo "Cobertura $cobertura abaixo de 70%"
exit 1
fi