Oefening: codedekking testen

Voltooid

Net als het hulpprogramma dat u gebruikt voor eenheidstests, is het hulpprogramma dat u gebruikt voor codedekking, afhankelijk van de programmeertaal en het toepassingsframework.

Wanneer u .NET-toepassingen op Linux wilt uitvoeren, is coverlet een populaire optie. Coverlet is een platformoverschrijdende bibliotheek voor codedekking voor .NET.

Hoe wordt codedekking uitgevoerd in .NET?

De manier waarop u codedekking verzamelt, is afhankelijk van de programmeertaal en frameworks die u gebruikt en welke hulpprogramma's voor codedekking beschikbaar zijn.

In ons Tailspin-scenario vinden we dat:

  • Visual Studio in Windows biedt een manier om codedekking uit te voeren.

  • Omdat we echter bouwen op Linux, kunnen we coverlet gebruiken, een platformoverschrijdende codedekkingsbibliotheek voor .NET.

    Voor het eenheidstestproject is het nuget-pakket coverlet.msbuild vereist.

  • Resultaten van codedekking worden geschreven naar een XML-bestand, zodat ze door een ander hulpprogramma kunnen worden verwerkt. Azure Pipelines ondersteunt resultatenindelingen voor Cobertura - en JaCoCo-dekking .

    Voor deze module gebruiken we Cobertura.

  • Als u cobertura-dekkingsresultaten wilt converteren naar een indeling die leesbaar is voor mensen, kunnen we een hulpprogramma met de naam ReportGenerator gebruiken.

  • ReportGenerator biedt veel indelingen, waaronder HTML. De HTML-indelingen maken gedetailleerde rapporten voor elke klasse in een .NET-project.

    Er is een HTML-indeling met de naam HtmlInline_AzurePipelines, die een visueel uiterlijk biedt dat overeenkomt met Azure Pipelines.

Hoe kan ik .NET-hulpprogramma's beheren?

Een .NET-hulpprogramma, zoals ReportGenerator een speciaal NuGet-pakket dat een consoletoepassing bevat. U kunt een .NET-hulpprogramma beheren als een globaal hulpprogramma of als een lokaal hulpprogramma.

Een globaal hulpprogramma wordt geïnstalleerd op een centrale locatie en kan worden aangeroepen vanuit elke map. Eén versie van een globaal hulpprogramma wordt gebruikt voor alle mappen op de computer.

Een lokaal hulpprogramma is een geïsoleerdere kopie van een .NET-hulpprogramma dat is gericht op een specifieke map. Met scope kunnen verschillende mappen verschillende versies van hetzelfde hulpprogramma bevatten.

U gebruikt een manifestbestand om lokale hulpprogramma's voor een bepaalde map te beheren. Dit bestand heeft de JSON-indeling en heeft meestal de naam dotnet-tools.json. Met een manifestbestand kunt u de specifieke hulpprogrammaversies beschrijven die u nodig hebt om uw toepassing te bouwen of uit te voeren.

Wanneer u het manifestbestand opneemt in broncodebeheer en uw toepassingsbronnen, kunnen ontwikkelaars en buildsystemen de dotnet tool restore opdracht uitvoeren om alle hulpprogramma's in het manifestbestand te installeren. Wanneer u een nieuwere versie van een lokaal hulpprogramma nodig hebt, werkt u de versie in het manifestbestand bij.

Als u dingen geïsoleerd wilt houden, werkt u met lokale hulpprogramma's in deze module. U maakt een hulpprogrammamanifest dat het ReportGenerator hulpprogramma bevat. U wijzigt ook uw build-pijplijn om het ReportGenerator hulpprogramma te installeren om resultaten van codedekking te converteren naar een door mensen leesbare indeling.

Codedekking lokaal uitvoeren

Voordat u pijplijncode schrijft, kunt u dingen handmatig proberen om het proces te verifiëren.

  1. Open in Visual Studio Code de geïntegreerde terminal.

  2. Voer de volgende dotnet new opdracht uit om een manifestbestand voor het lokale hulpprogramma te maken.

    dotnet new tool-manifest
    

    Met de opdracht maakt u een bestand met de naam .config/dotnet-tools.json.

  3. Voer de volgende dotnet tool install opdracht uit om ReportGenerator te installeren:

    dotnet tool install dotnet-reportgenerator-globaltool
    

    Met deze opdracht installeert u de nieuwste versie van ReportGenerator en voegt u een vermelding toe aan het manifestbestand van het hulpprogramma.

  4. Voer de volgende dotnet add package opdracht uit om het pakket toe te voegen aan het coverlet.msbuild project Tailspin.SpaceGame.Web.Tests :

    dotnet add Tailspin.SpaceGame.Web.Tests package coverlet.msbuild
    
  5. Voer de volgende dotnet test opdracht uit om uw eenheidstests uit te voeren en codedekking te verzamelen:

    Notitie

    Als u de PowerShell-terminal in Visual Studio gebruikt, is het vervolgteken voor de regel een backtick (`), dus gebruik dat teken in plaats van het backslashteken (\) voor opdrachten met meerdere regels.

    dotnet test --no-build \
      --configuration Release \
      /p:CollectCoverage=true \
      /p:CoverletOutputFormat=cobertura \
      /p:CoverletOutput=./TestResults/Coverage/
    

    Als de opdracht mislukt, voert u deze als volgt uit:

    MSYS2_ARG_CONV_EXCL="*" dotnet test --no-build \
      --configuration Release \
      /p:CollectCoverage=true \
      /p:CoverletOutputFormat=cobertura \
      /p:CoverletOutput=./TestResults/Coverage/
    

    Deze opdracht lijkt op de opdracht die u eerder hebt uitgevoerd. De /p: vlaggen vertellen coverlet welke codedekkingsindeling moet worden gebruikt en waar de resultaten moeten worden opgeslagen.

  6. Voer de volgende dotnet tool run opdracht uit om ReportGenerator het Cobertura-bestand te converteren naar HTML:

    dotnet tool run reportgenerator \
      -- -reports:./Tailspin.SpaceGame.Web.Tests/TestResults/Coverage/coverage.cobertura.xml \
      -targetdir:./CodeCoverage \
      -reporttypes:HtmlInline_AzurePipelines
    

    Veel HTML-bestanden worden weergegeven in de map CodeCoverage in de hoofdmap van het project.

  7. Vouw in Visual Studio Code de map CodeCoverage uit, klik met de rechtermuisknop op index.htm en selecteer Weergeven in Bestandenverkenner (Weergeven in Finder in macOS of Map openen in Linux).

  8. Dubbelklik in Windows Verkenner (Finder op macOS) op index.htm om deze te openen in een webbrowser.

    U ziet de samenvatting van het dekkingsrapport.

    A screenshot of the local code coverage report summary showing 7.7 percent line coverage.

  9. Schuif naar de onderkant van de pagina om een dekkingsanalyse per klassetype weer te geven.

    A screenshot of local coverage report class summary showing coverage stats across classes found in the Tailspin.SpaceGame.Web code.

  10. Selecteer de koppeling om meer details weer te TailSpin.SpaceGame.Web.LocalDocumentDBRepository<T> geven.

    U ziet dat de GetItemsAsync methode wordt gedekt door eenheidstests, maar de CountItemsAsync methode heeft geen dekking.

    A screenshot of local class coverage detail with a visual representation of unit test coverage for two C# methods, one with all code lines green (covered) and one with all lines red (not covered).

    Dit is logisch, omdat de FetchOnlyRequestedGameRegion testmethode de GetItemsAsync methode aanroept, maar de CountItemsAsync methode niet aanroept. (Als u de testcode wilt bekijken, bekijkt u de DocumentDBRepository_GetItemsAsyncShould.cs-bestand .)

Een vertakking maken

Nu u lokaal een codedekkingsrapport kunt maken, kunt u taken toevoegen aan uw build-pijplijn, waarmee dezelfde taken worden uitgevoerd.

In deze sectie maakt u een vertakking met de naam code-coverage, op basis van de unit-tests vertakking, om uw werk vast te houden. In de praktijk maakt u deze vertakking gewoonlijk vanuit de main vertakking.

  1. Open in Visual Studio Code de geïntegreerde terminal.

  2. Voer in de terminal de volgende git checkout opdracht uit om een vertakking met de naam code-coveragete maken:

    git checkout -B code-coverage
    

Buildtaken toevoegen

In deze sectie voegt u taken toe waarmee codedekking wordt gemeten aan uw build-pijplijn.

  1. Wijzig in Visual Studio Code azure-pipelines.yml als volgt:

    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()
    

    Deze versie is gebaseerd op uw bestaande configuratie. Hier volgt een samenvatting van wat er nieuw is:

    Azure Pipelines-taak Display name Beschrijving
    DotNetCoreCLI@2 .NET-hulpprogramma's installeren vanuit het lokale manifest Installeert hulpprogramma's die worden vermeld in het manifestbestand dotnet-tools.json
    DotNetCoreCLI@2 Eenheidstests uitvoeren - $(buildConfiguration) Voert eenheidstests uit en verzamelt ook codedekking in Cobertura-indeling
    DotNetCoreCLI@2 Codedekkingsrapport maken Converteert Cobertura-uitvoer naar HTML
    PublishCodeCoverageResults@1 Rapport codedekking publiceren Hiermee publiceert u het rapport naar de pijplijn

Uw wijzigingen doorvoeren en de vertakking pushen naar GitHub

Hier pusht u uw wijzigingen naar GitHub en ziet u de pijplijnuitvoering. Zoals u weet, bevindt u zich momenteel in de code-coverage vertakking.

Hoewel dit niet vereist is, voegt u hier elk bestand afzonderlijk toe en voert u dit door, zodat elke wijziging is gekoppeld aan een beschrijvend doorvoerbericht.

  1. Ga in Visual Studio Code naar de terminal.

  2. Voeg het bestand Tailspin.SpaceGame.Web.Tests.csproj toe en voer het door, dat nu een verwijzing naar het coverlet.msbuild pakket bevat:

    git add Tailspin.SpaceGame.Web.Tests/Tailspin.SpaceGame.Web.Tests.csproj
    git commit -m "Add coverlet.msbuild package"
    
  3. Voeg het manifestbestand van het hulpprogramma toe en voer dit door, dotnet-tools.json:

    git add .config/dotnet-tools.json
    git commit -m "Add code coverage"
    
  4. Voeg azure-pipelines.yml toe en voer deze door, die uw bijgewerkte buildconfiguratie bevat:

    git add azure-pipelines.yml
    git commit -m "Add code coverage"
    
  5. Push de code-coverage vertakking naar GitHub.

    git push origin code-coverage
    

Bekijk hoe Azure Pipelines de tests uitvoert

Hier ziet u dat de tests worden uitgevoerd in de pijplijn en vervolgens de resultaten van Azure Test Plans visualiseren.

  1. Traceer in Azure Pipelines de build via elk van de stappen.

  2. Wanneer de build is voltooid, gaat u terug naar de pagina Samenvatting en selecteert u het tabblad Codedekking .

    U bekijkt dezelfde resultaten die u hebt gedaan toen u de tests lokaal hebt uitgevoerd.

    A screenshot of Azure Pipelines showing the Code Coverage tab, with code coverage report summary showing 7.7 percent line coverage.

    Als optionele stap kunt u de resultaten van Azure Pipelines verkennen.

De dashboardwidget toevoegen

In de vorige sectie hebt u de widget Trend van testresultaten toegevoegd aan uw dashboard, zodat anderen snel trends in het testresultaat in de loop van de tijd kunnen bekijken.

Hier voegt u een tweede widget toe waarmee de codedekking wordt samengevat.

  1. Ga in een nieuw browsertabblad naar marketplace.visualstudio.com.

  2. Zoek op het tabblad Azure DevOps naar codedekking.

  3. Selecteer Code Coverage Widgets (gepubliceerd door Shane Davis).

  4. Selecteer Gratis downloaden.

  5. Selecteer uw Azure DevOps-organisatie in de vervolgkeuzelijst.

  6. Selecteer Installeren.

  7. Ga terug naar Azure DevOps.

  8. Ga naar Overzichtsdashboards>.

  9. Selecteer Bewerken.

  10. Zoek naar codedekking en selecteer vervolgens Codedekking.

    A screenshot of Visual Studio Marketplace showing the Code Coverage widget card.

  11. Sleep codedekking naar het canvas.

  12. Selecteer het tandwielpictogram om de widget te configureren.

  13. Behoud alle standaardinstellingen, met uitzondering van:

    • Breedte: Voer 2 in
    • Builddefinitie: Selecteer uw pijplijn
    • Dekkingsmeting: lijnen selecteren
  14. Selecteer Opslaan.

  15. Selecteer Klaar met bewerken.

    De widget toont het percentage code dat door uw eenheidstests wordt behandeld.

    A screenshot of Azure DevOps Code Coverage widget showing 8 percent coverage of the sample project.

U hebt nu codedekking ingesteld in uw pijplijn. Hoewel uw bestaande codedekking laag is, hebt u een basislijn die u in de loop van de tijd kunt verbeteren.

Later kunt u coverlet configureren om te controleren of uw tests een minimale dekkingsdrempel bieden. Uw drempelwaarde kan 30 procent, 50 procent of 80 procent dekking zijn, afhankelijk van uw vereisten. De build mislukt als uw tests minder dan dit bedrag dekken.

Codedekkingsbestanden verwijderen

Zoals u zich herinnert, Reportgenerator worden veel HTML-bestanden weergegeven in de map CodeCoverage in de hoofdmap van het project.

Deze HTML-bestanden zijn niet bedoeld om in broncodebeheer te worden opgenomen en u hebt ze niet meer nodig. Hoewel het .gitignore-bestand van het project al is ingesteld om iets in de map CodeCoverage te negeren, is het een goed idee om deze bestanden te verwijderen, zodat ze niet worden toegevoegd aan uw Git-opslagplaats in toekomstige modules.

Ga in Visual Studio Code naar het terminalvenster en voer vervolgens in de hoofdmap van uw project de volgende opdracht uit:

rm -rf CodeCoverage/