Exercício – Executar o teste de cobertura de código
De modo muito semelhante à ferramenta usada para o teste de unidade, a ferramenta usada para cobertura de código depende da linguagem de programação e da estrutura de aplicativo.
Ao direcionar aplicativos .NET para execução no Linux, coverlet é uma opção popular. Coverlet é uma biblioteca de cobertura de código multiplataforma para o .NET.
Como a cobertura de código é feita no .NET?
A maneira de você coletar a cobertura de código depende de qual linguagem de programação e estrutura você está usando e também das ferramentas de cobertura de código disponíveis.
Em nosso cenário de Tailspin, descobrimos que:
O Visual Studio no Windows oferece uma maneira de executar a cobertura de código.
No entanto, como a estamos desenvolvendo no Linux, podemos usar coverlet, uma biblioteca de cobertura de código multiplataforma para .NET.
O projeto de teste de unidade exige o pacote do NuGet coverlet.msbuild.
Os resultados da cobertura de código são gravados em um arquivo XML para que possam ser processados por outra ferramenta. O Azure Pipelines dá suporte aos formatos de resultados de cobertura do Cobertura e do JaCoCo.
Nesse módulo, estamos usando a Cobertura.
Para converter os resultados de cobertura da Cobertura em um formato legível por humanos, podemos usar uma ferramenta chamada ReportGenerator.
ReportGenerator fornece muitos formatos, incluindo HTML. Os formatos HTML criam relatórios detalhados para cada classe em um projeto do .NET.
Especificamente, há um formato HTML chamado HtmlInline_AzurePipelines que fornece uma aparência visual que corresponde ao Azure Pipelines.
Como posso gerenciar as ferramentas do .NET?
Uma ferramenta do .NET como ReportGenerator
é um pacote NuGet especial que contém um aplicativo de console. Você pode gerenciar uma ferramenta do .NET como uma ferramenta global ou uma ferramenta local.
Uma ferramenta global é instalada em um local centralizado e pode ser chamada de qualquer diretório. Uma versão de uma ferramenta global é usada para todos os diretórios no computador.
Uma ferramenta local é uma cópia mais isolada de uma ferramenta .NET que tem como escopo um diretório específico. O escopo permite que diretórios diferentes contenham versões diferentes da mesma ferramenta.
Você usa um arquivo de manifesto para gerenciar as ferramentas locais de um determinado diretório. Esse arquivo está no formato JSON e normalmente é chamado de dotnet-tools.json. Um arquivo de manifesto permite que você descreva as versões específicas da ferramenta de que você precisa para compilar ou executar seu aplicativo.
Quando você inclui o arquivo de manifesto no controle do código-fonte e suas fontes de aplicativo, os desenvolvedores e os sistemas de compilação podem executar o comando dotnet tool restore
para instalar todas as ferramentas listadas no arquivo de manifesto. Quando você precisa de uma versão mais recente de uma ferramenta local, basta atualizar a versão no arquivo de manifesto.
Para manter as coisas mais isoladas, você trabalhará com ferramentas locais neste módulo. Você criará um manifesto de ferramenta que inclui a Ferramenta ReportGenerator
. Você também modificará seu pipeline de build para instalar a Ferramenta ReportGenerator
e converter os resultados da cobertura de código em um formato legível.
Executar cobertura de código localmente
Antes escrever qualquer código de pipeline, você pode experimentar trabalhar manualmente para verificar o processo.
No Visual Studio Code, abra o terminal integrado.
Execute o comando
dotnet new
a seguir para criar um arquivo de manifesto de ferramenta local.dotnet new tool-manifest
O comando cria um arquivo chamado .config/dotnet-tools.json.
Execute o seguinte comando
dotnet tool install
para instalar o ReportGenerator:dotnet tool install dotnet-reportgenerator-globaltool
Esse comando instala a versão mais recente do
ReportGenerator
e adiciona uma entrada ao arquivo de manifesto da ferramenta.Execute o seguinte comando
dotnet add package
para adicionar o pacotecoverlet.msbuild
ao projeto Tailspin.SpaceGame.Web.Tests:dotnet add Tailspin.SpaceGame.Web.Tests package coverlet.msbuild
Execute o seguinte comando
dotnet test
para executar seus testes de unidade e coletar a cobertura de código:Observação
Se você estiver usando o terminal do PowerShell no Visual Studio, o caractere de continuação de linha será um acento grave (`), então use esse caractere no lugar no lugar da barra invertida (\) para comandos em várias linhas.
dotnet test --no-build \ --configuration Release \ /p:CollectCoverage=true \ /p:CoverletOutputFormat=cobertura \ /p:CoverletOutput=./TestResults/Coverage/
Se o comando falhar, tente executá-lo da seguinte forma:
MSYS2_ARG_CONV_EXCL="*" dotnet test --no-build \ --configuration Release \ /p:CollectCoverage=true \ /p:CoverletOutputFormat=cobertura \ /p:CoverletOutput=./TestResults/Coverage/
Esse comando é semelhante ao que foi executado anteriormente. Os sinalizadores
/p:
informam o coverlet do formato de cobertura de código a ser usado e em que local colocar os resultados.Execute o seguinte comando
dotnet tool run
para usarReportGenerator
para converter o arquivo Cobertura em HTML:dotnet tool run reportgenerator \ -- -reports:./Tailspin.SpaceGame.Web.Tests/TestResults/Coverage/coverage.cobertura.xml \ -targetdir:./CodeCoverage \ -reporttypes:HtmlInline_AzurePipelines
Muitos arquivos HTML serão exibidos na pasta CodeCoverage na raiz do projeto.
No Visual Studio Code, expanda a pasta CodeCoverage, clique com o botão direito do mouse em index.htm e selecione Revelar no Explorador de Arquivos (Revelar no Finder no macOS ou Abrir Pasta Recipiente no Linux).
No Windows Explorer (Finder, no macOS), clique duas vezes em index.htm para abri-lo em um navegador da Web.
Você verá o resumo do relatório de cobertura.
Role até a parte inferior da página para ver um detalhamento de cobertura por tipo de classe.
Selecione o link para
TailSpin.SpaceGame.Web.LocalDocumentDBRepository<T>
para ver mais detalhes.Observe o método
GetItemsAsync
está coberto por testes de unidade, mas o métodoCountItemsAsync
não tem nenhuma cobertura.Isso faz sentido, pois o método de teste
FetchOnlyRequestedGameRegion
chama o métodoGetItemsAsync
, mas não chama o métodoCountItemsAsync
. (Para examinar o código de teste, veja o arquivo DocumentDBRepository_GetItemsAsyncShould.cs.)
Criar um branch
Agora que você pode compilar um relatório de cobertura de código localmente, está pronto para adicionar tarefas ao seu pipeline de build que executa as mesmas tarefas.
Nesta seção, você criará um branch chamado code-coverage
, com base no branch unit-tests
, para armazenar seu trabalho. Na prática, você normalmente criaria esse branch com base no branch main
.
No Visual Studio Code, abra o terminal integrado.
No terminal, execute o seguinte comando
git checkout
para criar um branch chamadocode-coverage
:git checkout -B code-coverage
Adicionar tarefas de build
Nesta seção, você adicionará tarefas que medem a cobertura de código para o pipeline de build.
No Visual Studio Code, modifique azure-pipelines.yml desta forma:
trigger: - '*' pool: vmImage: 'ubuntu-20.04' demands: - npm variables: buildConfiguration: 'Release' wwwrootDir: 'Tailspin.SpaceGame.Web/wwwroot' dotnetSdkVersion: '6.x' steps: - task: UseDotNet@2 displayName: 'Use .NET SDK $(dotnetSdkVersion)' inputs: version: '$(dotnetSdkVersion)' - task: Npm@1 displayName: 'Run npm install' inputs: verbose: false - script: './node_modules/.bin/node-sass $(wwwrootDir) --output $(wwwrootDir)' displayName: 'Compile Sass assets' - task: gulp@1 displayName: 'Run gulp tasks' - script: 'echo "$(Build.DefinitionName), $(Build.BuildId), $(Build.BuildNumber)" > buildinfo.txt' displayName: 'Write build info' workingDirectory: $(wwwrootDir) - task: DotNetCoreCLI@2 displayName: 'Restore project dependencies' inputs: command: 'restore' projects: '**/*.csproj' - task: DotNetCoreCLI@2 displayName: 'Build the project - $(buildConfiguration)' inputs: command: 'build' arguments: '--no-restore --configuration $(buildConfiguration)' projects: '**/*.csproj' - task: DotNetCoreCLI@2 displayName: 'Install .NET tools from local manifest' inputs: command: custom custom: tool arguments: 'restore' - task: DotNetCoreCLI@2 displayName: 'Run unit tests - $(buildConfiguration)' inputs: command: 'test' arguments: '--no-build --configuration $(buildConfiguration) /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:CoverletOutput=$(Build.SourcesDirectory)/TestResults/Coverage/' publishTestResults: true projects: '**/*.Tests.csproj' - task: DotNetCoreCLI@2 displayName: 'Create code coverage report' inputs: command: custom custom: tool arguments: 'run reportgenerator -reports:$(Build.SourcesDirectory)/**/coverage.cobertura.xml -targetdir:$(Build.SourcesDirectory)/CodeCoverage -reporttypes:HtmlInline_AzurePipelines' - task: PublishCodeCoverageResults@1 displayName: 'Publish code coverage report' inputs: codeCoverageTool: 'cobertura' summaryFileLocation: '$(Build.SourcesDirectory)/**/coverage.cobertura.xml' - task: DotNetCoreCLI@2 displayName: 'Publish the project - $(buildConfiguration)' inputs: command: 'publish' projects: '**/*.csproj' publishWebProjects: false arguments: '--no-build --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)/$(buildConfiguration)' zipAfterPublish: true - task: PublishBuildArtifacts@1 displayName: 'Publish Artifact: drop' condition: succeeded()
Esta versão tem como base a configuração existente. Aqui está um resumo das novidades:
Tarefa do Azure Pipelines Nome de exibição Descrição DotNetCoreCLI@2
Instalar as ferramentas do .NET do manifesto local Instala as ferramentas listadas no arquivo de manifesto, dotnet-tools.json DotNetCoreCLI@2
Executar testes de unidade – $(buildConfiguration) Executa testes de unidade e também coleta de cobertura de código no formato Cobertura DotNetCoreCLI@2
Criar relatório de cobertura de código Converte a saída de Cobertura em HTML PublishCodeCoverageResults@1
Publicar o relatório de cobertura de código Publica o relatório para o pipeline
Fazer commit das alterações e enviar o branch por push ao GitHub
Aqui você enviará as alterações por push ao GitHub e verá a execução de pipeline. Lembre-se de que, no momento, você está no branch code-coverage
.
Embora não seja necessário, aqui você adicionará e fará commit de cada arquivo separadamente para que cada alteração seja associada a uma mensagem de commit descritiva.
No Visual Studio Code, acesse o terminal.
Adicione e faça commit do arquivo Tailspin.SpaceGame.Web.Tests.csproj, que agora contém uma referência ao pacote
coverlet.msbuild
:git add Tailspin.SpaceGame.Web.Tests/Tailspin.SpaceGame.Web.Tests.csproj git commit -m "Add coverlet.msbuild package"
Adicione e faça commit do arquivo de manifesto da ferramenta, dotnet-tools.json:
git add .config/dotnet-tools.json git commit -m "Add code coverage"
Adicione e faça commit de azure-pipelines.yml, que contém a configuração de build atualizada:
git add azure-pipelines.yml git commit -m "Add code coverage"
Envie o branch
code-coverage
por push ao GitHub.git push origin code-coverage
Assista aos Azure Pipelines executarem os testes
Aqui, você verá os testes serem executados no pipeline e, em seguida, visualizará os resultados do Azure Test Plans.
No Azure Pipelines, rastreie o build por meio de cada uma das etapas.
Quando a compilação terminar, volte para a página Resumo e selecione a guia Cobertura de código.
Você vê os mesmos resultados de quando executou os testes localmente.
Como uma etapa opcional, você pode explorar os resultados no Azure Pipelines.
Adicionar o widget ao painel
Na seção anterior, você adicionou o widget Tendência dos Resultados de Teste ao painel, possibilitando que outras pessoas analisem rapidamente as tendências dos resultados dos testes ao longo do tempo.
Aqui, você adicionará um segundo widget que resume a cobertura de código.
Em uma nova guia do navegador, acesse marketplace.visualstudio.com.
Na guia Azure DevOps, pesquise code coverage.
Selecione Code Coverage Widgets (publicados por Shane Davis).
Selecione Get it free.
Na lista suspensa, selecione sua organização do Azure DevOps.
Selecione Instalar.
Volte para o Azure DevOps.
Vá para Overview>Dashboards.
Selecione Editar.
Pesquise Code Coverage e selecione Code Coverage.
Arraste Cobertura de Código para a tela.
Selecione o ícone de Engrenagem para configurar o widget.
Mantenha todas as configurações padrão, exceto por:
- Largura: Insira 2
- Definição de build: Selecione seu pipeline
- Medida de cobertura: selecione Linhas
Selecione Salvar.
Selecione Done Editing.
O widget mostra o percentual de código que seus testes de unidade cobrem.
Agora você tem cobertura de código definida no seu pipeline. Embora sua cobertura de código existente seja baixa, você tem uma linha de base que pode aprimorar ao longo do tempo.
Posteriormente, você pode configurar o coverlet para ver se os testes fornecem um limite mínimo de cobertura. Seu limite pode ser de 30%, 50% ou 80% de cobertura, dependendo dos seus requisitos. A compilação falhará se testes cobrirem uma quantidade inferior a essa.
Remover arquivos de cobertura de código
Lembre-se de que, quando você executou Reportgenerator
anteriormente, viu muitos arquivos HTML serem exibidos na pasta CodeCoverage na raiz do projeto.
Esses arquivos HTML não devem ser incluídos no controle do código-fonte e você não precisa mais deles. Embora o arquivo .gitignore do projeto já esteja configurado para ignorar tudo no diretório CodeCoverage, é uma boa ideia excluir esses arquivos para que não sejam adicionados ao seu repositório Git em módulos futuros.
No Visual Studio Code, vá para a janela do terminal e, no diretório raiz do projeto, execute este comando:
rm -rf CodeCoverage/