Exercício – Realizar testes de cobertura do código
Assim como a ferramenta que você usa para teste de unidade, a ferramenta que você usa para cobertura de código depende da linguagem de programação e da estrutura do aplicativo.
Quando você direciona aplicativos .NET para serem executados no Linux, o coverlet é uma opção popular. Coverlet é uma biblioteca de cobertura de código multiplataforma para .NET.
Como é feita a cobertura de código no .NET?
A maneira como você coleta a cobertura de código depende de qual linguagem de programação e estruturas você está usando e quais ferramentas de cobertura de código estão disponíveis.
Em nosso cenário Tailspin, descobrimos que:
O Visual Studio no Windows fornece uma forma de realizar a cobertura do código.
No entanto, como estamos construindo no Linux, podemos usar coverlet, uma biblioteca de cobertura de código multiplataforma para .NET.
O projeto de teste de unidades requer o pacote NuGet coverlet.msbuild.
Os resultados da cobertura do código são escritos num ficheiro XML para que possam ser processados por outra ferramenta. O Azure Pipelines suporta os formatos de resultados de cobertura Cobertura e JaCoCo.
Para este módulo, estamos usando Cobertura.
Para converter os resultados da cobertura do Cobertura para 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 .NET.
Especificamente, há um formato HTML chamado HtmlInline_AzurePipelines, que fornece uma aparência visual que corresponde aos Pipelines do Azure.
Como posso gerenciar ferramentas .NET?
Uma ferramenta .NET, como ReportGenerator
é um pacote NuGet especial que contém um aplicativo de console. Você pode gerenciar uma ferramenta .NET como uma ferramenta global ou como 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 na máquina.
Uma ferramenta local é uma cópia mais isolada de uma ferramenta .NET com escopo para 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 ferramentas locais para um determinado diretório. Esse arquivo está no formato JSON e normalmente é chamado dotnet-tools.json. Um arquivo de manifesto permite que você descreva as versões específicas da ferramenta que você precisa para criar ou executar seu aplicativo.
Quando você inclui o arquivo de manifesto no controle do código-fonte e nas fontes do aplicativo, os desenvolvedores e os sistemas de compilação podem executar o dotnet tool restore
comando para instalar todas as ferramentas listadas no arquivo de manifesto. Quando você precisar 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 da ferramenta que inclui a ReportGenerator
ferramenta. Você também modificará seu pipeline de compilação para instalar a ferramenta para converter os resultados da ReportGenerator
cobertura de código em um formato legível por humanos.
Executar a cobertura do código localmente
Antes de escrever qualquer código de pipeline, você pode tentar coisas manualmente para verificar o processo.
No Visual Studio Code, abra o terminal integrado.
Execute o seguinte
dotnet new
comando para criar um arquivo de manifesto da ferramenta local.dotnet new tool-manifest
O comando cria um arquivo chamado .config/dotnet-tools.json.
Execute o seguinte
dotnet tool install
comando para instalar o ReportGenerator:dotnet tool install dotnet-reportgenerator-globaltool
Este comando instala a versão mais recente e adiciona uma entrada ao arquivo de
ReportGenerator
manifesto da ferramenta.Execute o seguinte
dotnet add package
comando para adicionar ocoverlet.msbuild
pacote ao projeto Tailspin.SpaceGame.Web.Tests :dotnet add Tailspin.SpaceGame.Web.Tests package coverlet.msbuild
Execute o seguinte
dotnet test
comando para executar seus testes de unidade e coletar cobertura de código:Nota
Se você estiver usando o terminal do PowerShell no Visual Studio, o caractere de continuação de linha será um backtick (), portanto, use esse caractere no lugar do caractere de barra invertida (`\) para comandos de 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/
Este comando é semelhante a um que executou anteriormente. Os sinalizadores
/p:
indicam ao coverlet qual formato de cobertura de código utilizar e onde colocar os resultados.Execute o seguinte
dotnet tool run
comando para converterReportGenerator
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 aparecerão 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 contendo no Linux).
No Windows Explorer (Finder no macOS), clique duas vezes em índice.htm para abri-lo em um navegador da Web.
Você verá o resumo do relatório de cobertura.
Desloque-se para a parte inferior da página para ver uma discriminação da cobertura por tipo de classe.
Selecione o link para para
TailSpin.SpaceGame.Web.LocalDocumentDBRepository<T>
ver mais detalhes.Observe que o método é coberto por testes de unidade, mas o
GetItemsAsync
CountItemsAsync
método não tem cobertura.Isso faz sentido, porque o método de teste chama o método, mas não chama o
FetchOnlyRequestedGameRegion
GetItemsAsync
CountItemsAsync
método. (Para rever o código de teste, olhe para o DocumentDBRepository_GetItemsAsyncShould.cs arquivo.)
Criar um ramo
Agora que você pode criar um relatório de cobertura de código localmente, está pronto para adicionar tarefas ao seu pipeline de compilação, que executa as mesmas tarefas.
Nesta seção, você criará uma ramificação chamada code-coverage
, com base na unit-tests
ramificação, para manter seu trabalho. Na prática, você normalmente criaria esse ramo a partir do main
ramo.
No Visual Studio Code, abra o terminal integrado.
No terminal, execute o seguinte
git checkout
comando para criar uma ramificação chamadacode-coverage
:git checkout -B code-coverage
Adicionar tarefas de compilação
Nesta seção, você adicionará tarefas que medem a cobertura de código ao seu pipeline de compilação.
No Visual Studio Code, modifique azure-pipelines.yml da seguinte maneira:
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 baseia-se na configuração existente. Aqui está um resumo das novidades:
Tarefa do Azure Pipelines Display name Descrição DotNetCoreCLI@2
Instalar ferramentas .NET a partir do manifesto local Instala ferramentas listadas no arquivo de manifesto, dotnet-tools.json DotNetCoreCLI@2
Run unit tests - $(buildConfiguration) Executa os testes de unidades e também recolhe a cobertura do código no formato Cobertura DotNetCoreCLI@2
Create code coverage report Converte o resultado de Cobertura em HTML PublishCodeCoverageResults@1
Publish code coverage report Publica o relatório no pipeline
Confirme suas alterações e envie a ramificação para o GitHub
Aqui você envia suas alterações para o GitHub e vê o pipeline ser executado. Lembre-se de que você está atualmente no code-coverage
ramo.
Embora não seja necessário, aqui você adicionará e confirmará cada arquivo separadamente para que cada alteração seja associada a uma mensagem de confirmação descritiva.
No Visual Studio Code, aceda ao terminal.
Adicione e confirme o arquivo Tailspin.SpaceGame.Web.Tests.csproj , que agora contém uma referência ao
coverlet.msbuild
pacote:git add Tailspin.SpaceGame.Web.Tests/Tailspin.SpaceGame.Web.Tests.csproj git commit -m "Add coverlet.msbuild package"
Adicione e confirme o arquivo de manifesto da ferramenta, dotnet-tools.json:
git add .config/dotnet-tools.json git commit -m "Add code coverage"
Adicione e confirme azure-pipelines.yml, que contém sua configuração de compilação atualizada:
git add azure-pipelines.yml git commit -m "Add code coverage"
Empurre a ramificação para o
code-coverage
GitHub.git push origin code-coverage
Veja o Azure Pipelines a executar os testes
Aqui, você verá os testes executados no pipeline e, em seguida, visualizará os resultados dos Planos de Teste do Azure.
No Azure Pipelines, rastreie a compilação através 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ê visualiza os mesmos resultados que fez quando executou os testes localmente.
Como passo opcional, pode explorar os resultados do Azure Pipelines.
Adicionar o widget do painel
Na seção anterior, você adicionou o widget Tendência de resultados de teste ao seu painel, que permite que outras pessoas analisem rapidamente as tendências de resultados de teste ao longo do tempo.
Aqui, você adicionará um segundo widget que resume a cobertura do código.
Em uma nova guia do navegador, vá para marketplace.visualstudio.com.
Na guia Azure DevOps, procure cobertura de código.
Selecione Widgets de cobertura de código (publicado por Shane Davis).
Selecione Obter gratuitamente.
Na lista suspensa, selecione sua organização do Azure DevOps.
Selecione Instalar.
Volte para o Azure DevOps.
Vá para Painéis de visão geral>.
Selecione Editar.
Procure Cobertura de código e, em seguida, selecione Cobertura de código.
Arraste Cobertura do Código para a tela.
Selecione o ícone de engrenagem para configurar o widget.
Mantenha todas as configurações padrão, exceto para:
- Largura: Digite 2
- Definição de compilação: selecione seu pipeline
- Medição de cobertura: selecione Linhas
Selecione Guardar.
Selecione Edição Concluída.
O widget mostra a percentagem de código que os seus testes de unidades abrangem.
Agora tem a cobertura do código configurada no pipeline. Embora a sua cobertura do código existente seja baixa, tem uma linha de base que pode melhorar ao longo do tempo.
Mais tarde, você pode configurar o coverlet para verificar se seus testes fornecem um limite mínimo de cobertura. Seu limite pode ser de 30%, 50% ou 80% de cobertura, dependendo de suas necessidades. A compilação falhará se seus testes cobrirem menos do que esse valor.
Remover ficheiros da cobertura do código
Lembre-se de que, quando você executou Reportgenerator
anteriormente, muitos arquivos HTML apareceram na pasta CodeCoverage na raiz do projeto.
Esses arquivos HTML não se destinam a 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 qualquer coisa no diretório CodeCoverage, é uma boa ideia excluir esses arquivos para que eles não sejam adicionados ao seu repositório Git em módulos futuros.
No Visual Studio Code, vá para a janela do terminal e, em seguida, no diretório raiz do projeto, execute este comando:
rm -rf CodeCoverage/