Felipe Lima
Posted on April 18, 2021
Cobertura de testes é um assunto polêmico. Se meu código tem 100% de cobertura de código, significa que ele está a prova de falhas? Não exatamente. Mas é essencial ter uma boa noção da cobertura dos teste no nosso código e ter em mãos ferramentas de análise que nos ajudem a ter uma noção melhor dos pontos de atenção no código (seja quanto a sua complexididade, tamanho de classes, dependências etc).
Em alguns projetos que trabalhei muitas vezes utilizava apenas o Jacoco para analisar a cobertura dos meus testes a partir dos relatórios gerados por ele.
Com o SonarQube podemos dar um passo adiante, já que a partir do relatório gerado pelo Jacoco ele consegue dar um complemento na análise e saúde do nosso código, gerando um dashboard com várias informações. Ele complementa esse relatório de cobertura, trazendo informações de violações de boas práticas no código, potênciais bugs, duplicações, falhas de segurança e entre outras coisas...
Rodando SonarQube localmente
Nesta demonstração utilizei a versão 8.8-community.
Antes de mais nada é preciso seguir as recomendações da página do Dockerhub, que sugerem ajustar a quantidade de memória virtual:
For example, on Linux, you can set the recommended values for the current session by running the following commands as root on the host:
sysctl -w vm.max_map_count=262144
sysctl -w fs.file-max=65536
ulimit -n 65536
ulimit -u 4096
Após isso criar um docker-compose.yml seguindo as orientações fornecidas na documentação para Docker do SonarQube e subir o container localmente:
docker-compose up -d
No navegador acessar http://localhost:9000/
e entrar na tela de login, como abaixo:
Neste primeiro acesso conectei com login e senha admin/admin. Em seguida será solicitada uma nova senha:
Pronto! Podemos acessar nosso SonarQube:
Configurando meu projeto
Para fazer essa integração utilizei um projeto pessoal desenvolvido em Kotlin: https://github.com/flflima/shopping-cart.
Primeiramente no SonarQube criei e configurei um projeto manualmente:
Foi gerado um código para adicionar no meu arquivo de configuração do projeto. No meu caso, estou utilizando o Gradle como gerenciador de dependência:
Após adicionar o plugin conforme sugerido, bastou executar o comando que gera meus relatórios via Jacoco e integra com o SonarQube:
./gradlew clean test sonarqube \
-Dsonar.projectKey=<<your-project-key-configured>> \
-Dsonar.host.url=http://localhost:9000 \
-Dsonar.login=<<the-login>>
Na primeira vez que executei, o report marcou 0% de cobertura, o que não deveria ter acontecido já que o relatório do Jacoco marcava uma cobertura acima de 80%.
Mais precisamente 99% para cobertura por linha e 86% para cobertura por branches:
Já no SonarQube:
Após algumas pesquisas, descobri que precisava fazer alguns ajustes para que o Sonarqube pudesse enxergar o relatório gerado pelo Jacoco:
- habilitar a flag xml.enabled, para que o SonarQube pudesse ler o relatório gerado em formato XML (a partir da versão 8 ele deixou de suportar o arquivo .exec gerado pelo Jacoco - mais aqui)
jacocoTestReport {
reports {
xml.enabled true // a flag anteriormente era false
csv.enabled false
html.destination file("${buildDir}/jacocoHtml")
}
afterEvaluate {
excludeFiles(classDirectories, coverageExclusions)
}
}
- incluí uma configuração para o SonarQube localizar o relatório em XML e mapeei os mesmos arquivos excluídos da verificação do Jacoco:
sonarqube {
properties {
property "sonar.coverage.jacoco.xmlReportPaths", "${buildDir}/reports/jacoco/test/*.xml"
property "sonar.java.coveragePlugin", "jacoco"
property "sonar.coverage.exclusions", coverageExclusions
}
}
- na verificação da cobertura de código, removi a flag enabled = false, para que o relatório fosse gerado sempre, mesmo que a cobertura de código não fosse atingida:
jacocoTestCoverageVerification {
violationRules {
rule {
limit {
// enabled = false
counter = 'BRANCH'
value = 'COVEREDRATIO'
minimum = 0.8
}
}
}
afterEvaluate {
excludeFiles(classDirectories)
}
}
Após essas alterações o SonarQube começou a apresentar os valores de cobetura. Na aba 'Measures' podemos ver que o mesmo valor (ou uma aproximação) é marcado, tanto para cobertura por linhas como por branches:
E como cobertura geral do SonarQube temos:
Como comentei no início do texto, essas são ferramentas que agregam nossa busca em qualidade de código.
É claro que precisamos estar sempre atentos porque até mesmos os testes podem estar sujeitos a bugs e nos dar a falsa sensação de que por termos uma alta cobertura nosso código está protegido.
Mas como toda ferramenta de apoio é bem vinda, acredito que seja extremamente interessante que um desenvolvedor tenha conhecimento delas e ao longo do tempo vá usando todas com consciência.
Referências
https://www.eclemma.org/jacoco/
https://www.sonarqube.org/
https://hub.docker.com/_/sonarqube
https://docs.sonarqube.org/latest/setup/install-server/
Referência ao erro: https://github.com/SonarSource/docker-sonarqube/issues/317
Posted on April 18, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.