Övning – Utföra kodtäckningstestning
Precis som verktyget du använder för enhetstestning beror verktyget du använder för kodtäckning på programmeringsspråket och programramverket.
När du riktar in dig på .NET-program som ska köras på Linux är coverlet ett populärt alternativ. Coverlet är ett plattformsoberoende kodtäckningsbibliotek för .NET.
Hur görs kodtäckning i .NET?
Hur du samlar in kodtäckning beror på vilket programmeringsspråk och ramverk du använder och vilka kodtäckningsverktyg som är tillgängliga.
I vårt Tailspin-scenario ser vi följande:
Visual Studio i Windows är ett sätt att utföra kodtäckning.
Men eftersom vi bygger på Linux kan vi använda coverlet, ett plattformsoberoende kodtäckningsbibliotek för .NET.
Enhetstestprojektet kräver coverlet.msbuild NuGet-paketet.
Kodtäckningsresultat skrivs till en XML-fil så att de kan bearbetas av ett annat verktyg. Azure Pipelines stöder Cobertura - och JaCoCo-täckningsresultatformat .
För den här modulen använder vi Cobertura.
Om du vill konvertera Cobertura-täckningsresultat till ett format som kan läsas av människor kan vi använda ett verktyg med namnet ReportGenerator.
ReportGenerator innehåller många format, inklusive HTML. HTML-formaten skapar detaljerade rapporter för varje klass i ett .NET-projekt.
Mer specifikt finns det ett HTML-format som heter HtmlInline_AzurePipelines, som ger ett visuellt utseende som matchar Azure Pipelines.
Hur kan jag hantera .NET-verktyg?
Ett .NET-verktyg som ReportGenerator
är ett särskilt NuGet-paket som innehåller ett konsolprogram. Du kan hantera ett .NET-verktyg som ett globalt verktyg eller som ett lokalt verktyg.
Ett globalt verktyg installeras på en central plats och kan anropas från valfri katalog. En version av ett globalt verktyg används för alla kataloger på datorn.
Ett lokalt verktyg är en mer isolerad kopia av ett .NET-verktyg som är begränsat till en specifik katalog. Omfång gör att olika kataloger kan innehålla olika versioner av samma verktyg.
Du använder en manifestfil för att hantera lokala verktyg för en viss katalog. Den här filen är i JSON-format och heter vanligtvis dotnet-tools.json. Med en manifestfil kan du beskriva de specifika verktygsversioner som du behöver för att skapa eller köra ditt program.
När du inkluderar manifestfilen i källkontrollen och dina programkällor kan utvecklare och byggsystem köra dotnet tool restore
kommandot för att installera alla verktyg som anges i manifestfilen. När du behöver en nyare version av ett lokalt verktyg uppdaterar du helt enkelt versionen i manifestfilen.
För att hålla saker och ting mer isolerade arbetar du med lokala verktyg i den här modulen. Du skapar ett verktygsmanifest som innehåller verktyget ReportGenerator
. Du kommer också att ändra bygg-pipelinen för att installera ReportGenerator
verktyget för att konvertera kodtäckningsresultat till ett format som kan läsas av människor.
Köra kodtäckning lokalt
Innan du skriver någon pipelinekod kan du prova saker manuellt för att verifiera processen.
Öppna den integrerade terminalen i Visual Studio Code.
Kör följande
dotnet new
kommando för att skapa en lokal verktygsmanifestfil.dotnet new tool-manifest
Kommandot skapar en fil med namnet .config/dotnet-tools.json.
Kör följande
dotnet tool install
kommando för att installera ReportGenerator:dotnet tool install dotnet-reportgenerator-globaltool
Det här kommandot installerar den senaste versionen av
ReportGenerator
och lägger till en post i verktygets manifestfil.Kör följande
dotnet add package
kommando för att lägga tillcoverlet.msbuild
paketet i projektet Tailspin.SpaceGame.Web.Tests :dotnet add Tailspin.SpaceGame.Web.Tests package coverlet.msbuild
Kör följande
dotnet test
kommando för att köra enhetstesterna och samla in kodtäckning:Kommentar
Om du använder PowerShell-terminalen i Visual Studio är radfortsättningstecknet en backtick (`), så använd det tecknet i stället för omvänt snedstreck (\) för flerradskommandon.
dotnet test --no-build \ --configuration Release \ /p:CollectCoverage=true \ /p:CoverletOutputFormat=cobertura \ /p:CoverletOutput=./TestResults/Coverage/
Om kommandot misslyckas kan du prova att köra det på följande sätt:
MSYS2_ARG_CONV_EXCL="*" dotnet test --no-build \ --configuration Release \ /p:CollectCoverage=true \ /p:CoverletOutputFormat=cobertura \ /p:CoverletOutput=./TestResults/Coverage/
Det här kommandot liknar det som du körde tidigare. Flaggorna
/p:
anger vilket kodtäckningsformat som ska användas och var resultatet ska placeras.Kör följande
dotnet tool run
kommando för att konverteraReportGenerator
Cobertura-filen till HTML:dotnet tool run reportgenerator \ -- -reports:./Tailspin.SpaceGame.Web.Tests/TestResults/Coverage/coverage.cobertura.xml \ -targetdir:./CodeCoverage \ -reporttypes:HtmlInline_AzurePipelines
Många HTML-filer visas i mappen CodeCoverage i projektets rot.
I Visual Studio Code expanderar du mappen CodeCoverage, högerklickar på index.htm och väljer sedan Visa i Utforskaren (Visa i Finder på macOS eller Öppna innehållande mapp i Linux).
I Utforskaren (Finder på macOS) dubbelklickar du på index.htm för att öppna den i en webbläsare.
Du ser sammanfattningen av täckningsrapport.
Rulla längst ned på sidan för att se en täckningsuppdelning efter klasstyp.
Välj länken för att
TailSpin.SpaceGame.Web.LocalDocumentDBRepository<T>
visa ytterligare information.Observera att
GetItemsAsync
metoden omfattas av enhetstester, men metodenCountItemsAsync
har ingen täckning.Det är vettigt eftersom
FetchOnlyRequestedGameRegion
testmetoden anroparGetItemsAsync
metoden, men inte anroparCountItemsAsync
metoden. (Om du vill granska testkoden tittar du på DocumentDBRepository_GetItemsAsyncShould.cs fil.)
Skapa en gren
Nu när du kan skapa en kodtäckningsrapport lokalt är du redo att lägga till uppgifter i bygg-pipelinen, som utför samma uppgifter.
I det här avsnittet skapar du en gren med namnet code-coverage
, baserat på grenen unit-tests
, för att lagra ditt arbete. I praktiken skulle du vanligtvis skapa den här grenen från grenen main
.
Öppna den integrerade terminalen i Visual Studio Code.
I terminalen kör du följande
git checkout
kommando för att skapa en gren med namnetcode-coverage
:git checkout -B code-coverage
Lägga till bygguppgifter
I det här avsnittet lägger du till uppgifter som mäter kodtäckning i bygg-pipelinen.
Ändra azure-pipelines.yml på följande sätt i Visual Studio Code:
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()
Den här versionen bygger på din befintliga konfiguration. Här är en sammanfattning av vad som är nytt:
Azure Pipelines-uppgift Display name beskrivning DotNetCoreCLI@2
Installera .NET-verktyg från det lokala manifestet Installerar verktyg som anges i manifestfilen dotnet-tools.json DotNetCoreCLI@2
Köra enhetstester – $(buildConfiguration) Kör enhetstester och samlar även in kodtäckning i Cobertura-format DotNetCoreCLI@2
Skapa kodtäckningsrapport Konverterar Cobertura-utdata till HTML PublishCodeCoverageResults@1
Publicera kodtäckningsrapport Publicerar rapporten till pipelinen
Checka in dina ändringar och skicka grenen till GitHub
Här push-överför du ändringarna till GitHub och ser pipelinekörningen. Kom ihåg att du för närvarande är i grenen code-coverage
.
Även om det inte krävs lägger du till och checkar in varje fil separat så att varje ändring associeras med ett beskrivande incheckningsmeddelande.
I Visual Studio Code går du till terminalen.
Lägg till och checka in filen Tailspin.SpaceGame.Web.Tests.csproj , som nu innehåller en referens till
coverlet.msbuild
paketet:git add Tailspin.SpaceGame.Web.Tests/Tailspin.SpaceGame.Web.Tests.csproj git commit -m "Add coverlet.msbuild package"
Lägg till och checka in verktygets manifestfil dotnet-tools.json:
git add .config/dotnet-tools.json git commit -m "Add code coverage"
Lägg till och checka in azure-pipelines.yml, som innehåller din uppdaterade byggkonfiguration:
git add azure-pipelines.yml git commit -m "Add code coverage"
Skicka grenen
code-coverage
till GitHub.git push origin code-coverage
Se hur Azure Pipelines kör testerna
Här visas testerna som körs i pipelinen och sedan visualisera resultaten från Azure Test Plans.
I Azure Pipelines spårar du bygget genom vart och ett av stegen.
När bygget är klart går du tillbaka till sidan Sammanfattning och väljer fliken Kodtäckning .
Du visar samma resultat som du gjorde när du körde testerna lokalt.
Som ett valfritt steg kan du utforska resultaten från Azure Pipelines.
Lägg till instrumentpanelswidgeten
I föregående avsnitt lade du till widgeten Trend för testresultat på instrumentpanelen, vilket gör att andra snabbt kan granska testresultattrender över tid.
Här lägger du till en andra widget som sammanfattar kodtäckningen.
Gå till marketplace.visualstudio.com på en ny webbläsarflik.
På fliken Azure DevOps söker du efter kodtäckning.
Välj Kodtäckningswidgetar (publicerade av Shane Davis).
Välj Hämta kostnadsfritt.
I listrutan väljer du din Azure DevOps-organisation.
Välj Installera.
Gå tillbaka till Azure DevOps.
Gå till Översiktsinstrumentpaneler>.
Välj Redigera.
Sök efter kodtäckning och välj sedan Kodtäckning.
Dra Kodtäckning till arbetsytan.
Välj kugghjulsikonen för att konfigurera widgeten.
Behåll alla standardinställningar, förutom:
- Bredd: Ange 2
- Versionsdefinition: Välj din pipeline
- Täckningsmätning: välj Linjer
Välj Spara.
Välj Klar med redigering.
Widgeten visar procentandelen kod som enhetstesterna täcker.
Nu har du konfigurerat kodtäckning i din pipeline. Även om din befintliga kodtäckning är låg har du en baslinje som du kan förbättra med tiden.
Senare kan du konfigurera coverlet för att kontrollera om dina tester ger ett minsta tröskelvärde för täckning. Tröskelvärdet kan vara 30 procent, 50 procent eller 80 procent täckning, beroende på dina krav. Bygget misslyckas om dina tester täcker mindre än det här beloppet.
Ta bort kodtäckningsfiler
Kom ihåg att när du körde Reportgenerator
tidigare visades många HTML-filer i mappen CodeCoverage i projektets rot.
Dessa HTML-filer är inte avsedda att ingå i källkontrollen och du behöver dem inte längre. Även om projektets .gitignore-fil redan har konfigurerats för att ignorera något i katalogen CodeCoverage, är det en bra idé att ta bort filerna så att de inte läggs till i Git-lagringsplatsen i framtida moduler.
I Visual Studio Code går du till terminalfönstret och kör sedan följande kommando i projektets rotkatalog:
rm -rf CodeCoverage/