Como gerar relatórios de code coverage para código C#

Atualmente a discussão sobre “testar ou não testar” está obsoleta (ou pelo menos deveria estar). Testar é ponto pacífico. As polêmicas agora giram em torno da cobertura de código: Quais os números ideais para o code coverage? 100% de cobertura realmente é efetivo? O que deve ser testado? Independente da abordagem do seu time, em algum momento, você vai precisar gerar relatórios de code coverage. Nem que seja só para acompanhar o seu progresso.

Evidentemente você pode tratar o seu code coverage dentro no sonarqube, que inclusive possui uma cloud gratuita para projetos open source. Mas pode ser que por um motivo qualquer você não tenha acesso ao sonar no seu ambiente de trabalho. Ou não possua uma licença do Rider (IDE da Jetbrains) que também gera reports de code coverage. Neste caso, você vai precisar de opções gratuitas e que gerem informações de fácil interpretação e manipulação. É aqui que entram o coverlet e o report generator.

Adicionando coverlet ao seu projeto

O primeiro passo é conseguir, através do processo de testes, extrair as linhas que estão sendo cobertas. Cada linguagem/SDK tem a sua estratégia para atender a este fim. Para C#, o projeto coverlet consegue se integrar ao VSTest (coverlet.collector) e também ao MSBuild (coverlet.msbuild). Como usuário do VSCode, minha preferência é pelo último integrador. E é ele que vamos utilizar

Para adicionar o coverlet.msbuild ao seu projeto de testes, basta ir até a pasta do projeto e digitar:

dotnet add package coverlet.msbuild

E pronto! O seu projeto já está pronto para colher dados de cobertura.

Gerando dados de cobertura

Agora para gerar os dados de cobertura, você precisa incluir alguns parâmetros na execução do seu teste. O coverlet possui vários parâmetros de configuração disponíveis. Dê uma olhada no github deles para maiores informações. A seguir, vou mostrar pra você apenas os parâmetros que nos ajudarão na geração do nosso relatório:

dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:CoverletOutput=./coverage.opencover.xml

O que estamos fazendo?

  • /p:CollectCoverage=true: Habilita a coleta de dados de cobertura
  • /p:CoverletOutputFormat=opencover: Existem vários padrões para geração de arquivos de cobertura. O formato opencover resulta num arquivo xml que pode ser interpretado por ferramentas como o report generator.
  • /p:CoverletOutput=coverage.opencover.xml: Aqui você pode especificar um path para o arquivo. Eu aconselho você determine apenas o nome do arquivo.

E assim, para cada projeto com teste, será gerado um arquivo coverage.opencover.xml

Gerando relatório de cobertura

Se você abrir o XML, vai perceber que é um bocado… ilegível. Melhor seria se tivesse alguma ferramenta que transformasse esse conteúdo para um formato mais amigável. E é aí que entra o report generator.

O reporte generator é uma ferramenta gratuita e opensource, disponível no github. O único problema é que ela está disponível apenas para Windows. Para instalá-la é fácil: Basta digitar a seguinte linha de comando.

dotnet tool install -g dotnet-reportgenerator-globaltool

Particularmente prefiro instalar como ferramenta global no meu ambiente de desenvolvimento. E uma vez instalado, basta chamar:

reportgenerator -reports:**/coverage.opencover.xml -targetdir:coverage_report

Mais uma vez, existe um número enorme de parâmetros possíveis – que você pode verificar no github do projeto – mas vou abordar apenas os da linha de comando.

  • -reports: **/coverage.opencover.xml: Esse parâmetro informa ao reportgenerator o padrão de pesquisa para localizar os arquivos com os dados de cobertura. Como você pode perceber, o padrão glob de pesquisa está ativado;
  • -targetdir: coverage_report: Especifica qual é a pasta em que os relatórios serão salvos.

Ao acessar o arquivo HTML coverage_report\index.html, você vai ver o relatório formatado. Veja algumas imagens do resultado:

Página index.html
Visualização de cobertura de um arquivo

Últimos detalhes

São muitas linhas de código pra digitar. E para ganhar tempo, a melhor opção é automatizar esse processo. Como é uma solução Windows, a maneira mais fácil é criar um arquivo bat. coverage_report.bat

dotnet tool update -g dotnet-reportgenerator-globaltool
dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:CoverletOutput=coverage.opencover.xml
reportgenerator -reports:**/coverage.opencover.xml -targetdir:coverage_report
#Abre o arquivo no browser padrão
coverage_report\index.html

Quero chamar brevemente a atenção para a primeira linha, onde ao invés de install eu escrevi o comando update. Com install, é reportado no prompt uma mensagem de erro caso já esteja instalado. Com update, além de não reportar erro no stdout, também mantém o software atualizado.

Pode ser que, assim como eu, você goste de versionar os detalhes de ambiente. Assim garantimos que todo mundo que baixar o código já estará pronto para codificar. No entanto, com total certeza, você não vai querer versionar os relatórios gerados. Além de serem muitos arquivos, não faz sentido já que esses dados são automaticamente gerados em cada máquina. Sendo assim, adicione as seguintes linhas no seu .gitignore:

**/coverage.opencover.xml
coverage_report

E qual a relevância desse relatório?

Após escrever os testes, a visita ao relatório deve buscar responder a seguinte pergunta: Por que esta linha não está coberta? Pode ser que você tenha se esquecido de cobrir uma determinada condição. Ou ao olhar os casos de uso desenhados pelos teste, talvez você descubra que está tentando se prevenir de uma condição que nunca acontecerá – ou que seria melhor ser tratada de outra forma.

Utilize essa ferramenta com sabedoria e melhore a qualidade do seu código e dos seus testes!

Um abraço e até a próxima!

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.