Ćwiczenie — wykonywanie testów pokrycia kodu
Podobnie jak narzędzie używane do testowania jednostkowego, narzędzie używane do pokrycia kodu zależy od języka programowania i platformy aplikacji.
Jeśli aplikacja platformy .NET ma być uruchamiana w systemie Linux, coverlet jest popularną opcją. Coverlet to międzyplatformowa biblioteka pokrycia kodu dla platformy .NET.
W jaki sposób pokrycie kodu odbywa się na platformie .NET?
Sposób zbierania pokrycia kodu zależy od używanego języka programowania i platform oraz dostępnych narzędzi pokrycia kodu.
W naszym scenariuszu tailspin widzimy, że:
Program Visual Studio w systemie Windows umożliwia wykonywanie pokrycia kodu.
Jednak ponieważ kompilujemy w systemie Linux, możemy użyć coverletu , międzyplatformowej biblioteki pokrycia kodu dla platformy .NET.
Projekt testu jednostkowego wymaga pakietu NuGet coverlet.msbuild .
Wyniki pokrycia kodu są zapisywane w pliku XML, aby można je było przetworzyć za pomocą innego narzędzia. Usługa Azure Pipelines obsługuje formaty wyników pokrycia Cobertura i JaCoCo.
W tym module używamy narzędzia Cobertura.
Aby przekonwertować wyniki pokrycia Cobertura na format czytelny dla człowieka, możemy użyć narzędzia o nazwie ReportGenerator.
Narzędzie ReportGenerator udostępnia wiele formatów, w tym HTML. Formaty HTML tworzą szczegółowe raporty dla każdej klasy w projekcie platformy .NET.
W szczególności istnieje format HTML o nazwie HtmlInline_AzurePipelines, który zapewnia wygląd zgodny z usługą Azure Pipelines.
Jak mogę zarządzać narzędziami platformy .NET?
Narzędzie .NET, takie jak ReportGenerator
to specjalny pakiet NuGet, który zawiera aplikację konsolową. Narzędzie platformy .NET można zarządzać jako narzędzie globalne lub jako narzędzie lokalne.
Narzędzie globalne jest instalowane w centralnej lokalizacji i może być wywoływane z dowolnego katalogu. Jedna wersja narzędzia globalnego jest używana dla wszystkich katalogów na maszynie.
Narzędzie lokalne to bardziej izolowana kopia narzędzia platformy .NET, która jest ograniczona do określonego katalogu. Zakres umożliwia różnym katalogom zawierać różne wersje tego samego narzędzia.
Plik manifestu służy do zarządzania lokalnymi narzędziami dla danego katalogu. Ten plik jest w formacie JSON i zazwyczaj nosi nazwę dotnet-tools.json. Plik manifestu umożliwia opisanie określonych wersji narzędzi, które należy skompilować lub uruchomić aplikację.
Po dołączeniu pliku manifestu do kontroli źródła i źródeł aplikacji deweloperzy i systemy kompilacji mogą uruchomić dotnet tool restore
polecenie , aby zainstalować wszystkie narzędzia wymienione w pliku manifestu. Jeśli potrzebujesz nowszej wersji narzędzia lokalnego, wystarczy zaktualizować wersję w pliku manifestu.
Aby zachować większą izolację elementów, będziesz pracować z lokalnymi narzędziami w tym module. Utworzysz manifest narzędzia zawierający ReportGenerator
narzędzie. Zmodyfikujesz również potok kompilacji, aby zainstalować ReportGenerator
narzędzie w celu przekonwertowania wyników pokrycia kodu na format czytelny dla człowieka.
Lokalne uruchamianie pokrycia kodu
Przed napisaniem dowolnego kodu potoku możesz spróbować wykonać czynności ręcznie, aby zweryfikować proces.
W programie Visual Studio Code otwórz zintegrowany terminal.
Uruchom następujące
dotnet new
polecenie, aby utworzyć lokalny plik manifestu narzędzia.dotnet new tool-manifest
Polecenie tworzy plik o nazwie .config/dotnet-tools.json.
Uruchom następujące
dotnet tool install
polecenie, aby zainstalować narzędzie ReportGenerator:dotnet tool install dotnet-reportgenerator-globaltool
To polecenie instaluje najnowszą wersję programu
ReportGenerator
i dodaje wpis do pliku manifestu narzędzia.Uruchom następujące
dotnet add package
polecenie, aby dodaćcoverlet.msbuild
pakiet do projektu Tailspin.SpaceGame.Web.Tests :dotnet add Tailspin.SpaceGame.Web.Tests package coverlet.msbuild
Uruchom następujące
dotnet test
polecenie, aby uruchomić testy jednostkowe i zebrać pokrycie kodu:Uwaga
Jeśli używasz terminalu programu PowerShell w programie Visual Studio, znak kontynuacji wiersza jest znakiem odwrotnym (`), więc użyj tego znaku zamiast znaku ukośnika odwrotnego (\) dla poleceń wielowierszowych.
dotnet test --no-build \ --configuration Release \ /p:CollectCoverage=true \ /p:CoverletOutputFormat=cobertura \ /p:CoverletOutput=./TestResults/Coverage/
Jeśli polecenie zakończy się niepowodzeniem, spróbuj uruchomić polecenie w następujący sposób:
MSYS2_ARG_CONV_EXCL="*" dotnet test --no-build \ --configuration Release \ /p:CollectCoverage=true \ /p:CoverletOutputFormat=cobertura \ /p:CoverletOutput=./TestResults/Coverage/
To polecenie przypomina uruchomioną wcześniej. Flagi
/p:
informują coverlet, który format pokrycia kodu ma być używany i gdzie umieścić wyniki.Uruchom następujące
dotnet tool run
polecenie, aby użyćReportGenerator
polecenia , aby przekonwertować plik Cobertura na html:dotnet tool run reportgenerator \ -- -reports:./Tailspin.SpaceGame.Web.Tests/TestResults/Coverage/coverage.cobertura.xml \ -targetdir:./CodeCoverage \ -reporttypes:HtmlInline_AzurePipelines
Wiele plików HTML zostanie wyświetlonych w folderze CodeCoverage w katalogu głównym projektu.
W programie Visual Studio Code rozwiń folder CodeCoverage, kliknij prawym przyciskiem myszy index.htm, a następnie wybierz polecenie Ujawnij w Eksplorator plików (odsłaniaj w programie Finder w systemie macOS lub Otwórz folder zawierający w systemie Linux).
W Eksploratorze Windows (Finder w systemie macOS) kliknij dwukrotnie index.htm , aby otworzyć go w przeglądarce internetowej.
Zobaczysz podsumowanie raportu pokrycia.
Przewiń do dołu strony, aby wyświetlić podział pokrycia według typu klasy.
Wybierz link, aby wyświetlić
TailSpin.SpaceGame.Web.LocalDocumentDBRepository<T>
dalsze szczegóły.Zwróć uwagę, że
GetItemsAsync
metoda jest objęta testami jednostkowym, aleCountItemsAsync
metoda nie ma pokrycia.Ma to sens, ponieważ metoda testowa
FetchOnlyRequestedGameRegion
wywołuje metodęGetItemsAsync
, ale nie wywołujeCountItemsAsync
metody . (Aby przejrzeć kod testowy, przyjrzyj się DocumentDBRepository_GetItemsAsyncShould.cs pliku).
Tworzenie gałęzi
Teraz, gdy możesz utworzyć raport pokrycia kodu lokalnie, możesz przystąpić do dodawania zadań do potoku kompilacji, który wykonuje te same zadania.
W tej sekcji utworzysz gałąź o nazwie code-coverage
, w oparciu unit-tests
o gałąź do przechowywania pracy. W praktyce zwykle należy utworzyć tę gałąź z main
gałęzi .
W programie Visual Studio Code otwórz zintegrowany terminal.
W terminalu uruchom następujące
git checkout
polecenie, aby utworzyć gałąź o nazwiecode-coverage
:git checkout -B code-coverage
Dodawanie zadań kompilacji
W tej sekcji dodasz zadania, które mierzą pokrycie kodu do potoku kompilacji.
W programie Visual Studio Code zmodyfikuj azure-pipelines.yml w następujący sposób:
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()
Ta wersja opiera się na istniejącej konfiguracji. Oto podsumowanie nowości:
Zadanie usługi Azure Pipelines Display name Opis DotNetCoreCLI@2
Instalowanie narzędzi platformy .NET z manifestu lokalnego Instaluje narzędzia wymienione w pliku manifestu dotnet-tools.json DotNetCoreCLI@2
Uruchamianie testów jednostkowych — $(buildConfiguration) Uruchamia testy jednostkowe, a także zbiera pokrycie kodu w formacie Cobertura DotNetCoreCLI@2
Tworzenie raportu pokrycia kodu Konwertuje dane wyjściowe Cobertura na HTML PublishCodeCoverageResults@1
Publikowanie raportu pokrycia kodu Publikuje raport w potoku
Zatwierdź zmiany i wypchnij gałąź do usługi GitHub
W tym miejscu wypchniesz zmiany do usługi GitHub i zobaczysz przebieg potoku. Pamiętaj, że jesteś obecnie w code-coverage
gałęzi .
Mimo że nie jest to wymagane, należy dodać i zatwierdzić każdy plik oddzielnie, aby każda zmiana skojarzyła się z opisowym komunikatem zatwierdzenia.
W programie Visual Studio Code przejdź do terminalu.
Dodaj i zatwierdź plik Tailspin.SpaceGame.Web.Tests.csproj , który zawiera teraz odwołanie do
coverlet.msbuild
pakietu:git add Tailspin.SpaceGame.Web.Tests/Tailspin.SpaceGame.Web.Tests.csproj git commit -m "Add coverlet.msbuild package"
Dodaj i zatwierdź plik manifestu narzędzia, dotnet-tools.json:
git add .config/dotnet-tools.json git commit -m "Add code coverage"
Dodaj i zatwierdź azure-pipelines.yml, która zawiera zaktualizowaną konfigurację kompilacji:
git add azure-pipelines.yml git commit -m "Add code coverage"
code-coverage
Wypchnij gałąź do usługi GitHub.git push origin code-coverage
Obejrzyj, jak usługa Azure Pipelines uruchamia testy
W tym miejscu zobaczysz przebieg testów w potoku, a następnie zwizualizujesz wyniki z planów testów platformy Azure.
W usłudze Azure Pipelines prześledzić kompilację za pomocą każdego z kroków.
Po zakończeniu kompilacji wróć do strony Podsumowanie i wybierz kartę Pokrycie kodu.
Wyświetlane są te same wyniki, które wykonaliśmy podczas uruchamiania testów lokalnie.
Opcjonalnie możesz eksplorować wyniki z usługi Azure Pipelines.
Dodawanie widżetu pulpitu nawigacyjnego
W poprzedniej sekcji dodano widżet Trend wyników testów do pulpitu nawigacyjnego, co pozwala innym osobom szybko przeglądać trendy wyników testów w czasie.
W tym miejscu dodasz drugi widżet, który podsumowuje pokrycie kodu.
Na nowej karcie przeglądarki przejdź do marketplace.visualstudio.com.
Na karcie Azure DevOps wyszukaj pokrycie kodu.
Wybierz pozycję Widżety pokrycia kodu (opublikowane przez Shane Davis).
Wybierz pozycję Pobierz bezpłatnie.
Z listy rozwijanej wybierz organizację usługi Azure DevOps.
Wybierz Zainstaluj.
Wróć do usługi Azure DevOps.
Przejdź do pozycji Przegląd>Pulpity nawigacyjne.
Zaznacz Edytuj.
Wyszukaj pozycję Pokrycie kodu, a następnie wybierz pozycję Pokrycie kodu.
Przeciągnij pole Pokrycie kodu na kanwę.
Wybierz ikonę Koła zębatego , aby skonfigurować widżet.
Zachowaj wszystkie ustawienia domyślne, z wyjątkiem:
- Szerokość: wprowadź wartość 2
- Definicja kompilacji: wybierz potok
- Pomiar pokrycia: wybierz pozycję Linie
Wybierz pozycję Zapisz.
Wybierz pozycję Zakończono edytowanie.
Widżet przedstawia procent kodu, który obejmuje testy jednostkowe.
Teraz masz skonfigurowane pokrycie kodu w potoku. Mimo że istniejące pokrycie kodu jest niskie, masz punkt odniesienia, który można poprawić w czasie.
Później można skonfigurować coverlet, aby sprawdzić, czy testy zapewniają minimalny próg pokrycia. Próg może wynosić 30 procent, 50 procent lub 80 procent pokrycia, w zależności od wymagań. Kompilacja zakończy się niepowodzeniem, jeśli testy obejmują mniej niż ta kwota.
Usuwanie plików pokrycia kodu
Pamiętaj, że po uruchomieniu Reportgenerator
wcześniej wiele plików HTML pojawiło się w folderze CodeCoverage w katalogu głównym projektu.
Te pliki HTML nie mają być uwzględniane w kontroli źródła i nie są już potrzebne. Mimo że plik gitignore projektu jest już skonfigurowany tak, aby ignorował wszystkie elementy w katalogu CodeCoverage, dobrym pomysłem jest usunięcie tych plików, aby nie zostały dodane do repozytorium Git w przyszłych modułach.
W programie Visual Studio Code przejdź do okna terminalu, a następnie w katalogu głównym projektu uruchom następujące polecenie:
rm -rf CodeCoverage/