Упражнение. Проверка объема протестированного кода

Завершено

Как и в случае с модульным тестированием, выбор инструмента для проверки объема протестированного кода зависит от языка программирования и платформы приложений.

Если вы создаете приложения .NET для Linux, вы можете воспользоваться популярным инструментом coverlet. Coverlet — это кроссплатформенная библиотека средств для определения объема протестированного кода для .NET.

Каким образом можно проверить объем протестированного кода в .NET?

Способ сбора сведений об объеме протестированного кода зависит от того, какие язык программирования и платформу вы используете, а также от доступных вам инструментов.

В нашем сценарии Tailspin мы обнаружили, что:

  • В Visual Studio для Windows предусмотрены собственные средства для проверки объема протестированного кода.

  • Тем не менее, поскольку мы используем Linux, мы можем использовать обложку, кроссплатформенную библиотеку покрытия кода для .NET.

    Для проекта модульного тестирования требуется пакет NuGet coverlet.msbuild.

  • Результаты проверки объема протестированного кода записываются в XML-файл, что позволяет обрабатывать их в другом средстве. Платформа Azure Pipelines поддерживает форматы данных об объеме протестированного кода Cobertura и JaCoCo.

    Для этого модуля мы используем Cobertura.

  • Чтобы преобразовать результаты покрытия Cobertura в формат, доступный для чтения, можно использовать средство ReportGenerator.

  • ReportGenerator поддерживает множество форматов, включая HTML. Форматы HTML создают подробные отчеты для каждого класса в проекте .NET.

    В частности, существует формат HTML с именем HtmlInline_AzurePipelines, который предоставляет визуальный вид, соответствующий Azure Pipelines.

Как управлять инструментами .NET?

Средство .NET, такое как ReportGenerator, — это специальный пакет NuGet, который содержит консольное приложение. Вы можете управлять средством .NET в качестве глобального или локального инструмента.

Глобальное средство устанавливается в централизованном расположении и может вызываться из любого каталога. Одна из версий глобального инструмента используется для всех каталогов на компьютере.

Локальный инструмент — это более изолированная копия средства .NET, относящаяся к определенному каталогу. Область позволяет разным каталогам содержать разные версии одного и того же средства.

Файл манифеста используется для управления локальными инструментами для данного каталога. Этот файл находится в формате JSON и обычно называется dotnet-tools.json. Файл манифеста позволяет описать определенные версии инструментов, необходимые для сборки или запуска приложения.

При включении файла манифеста в систему управления версиями и источники приложения разработчики и системы сборки могут выполнить команду dotnet tool restore, чтобы установить все средства, перечисленные в файле манифеста. Если вам нужна более новая версия локального средства, вы просто обновите версию в файле манифеста.

Чтобы обеспечить более изолированные возможности, вы будете работать с локальными инструментами в этом модуле. Вы создадите манифест средства, включающий ReportGenerator средство. Вы также измените конвейер сборки, чтобы установить ReportGenerator средство для преобразования результатов покрытия кода в удобочитаемый для человека формат.

Локальная проверка объема протестированного кода

Прежде чем писать любой код конвейера, можно попробовать выполнить проверку процесса вручную.

  1. В Visual Studio Code откройте интегрированный терминал.

  2. Выполните следующую dotnet new команду, чтобы создать файл манифеста локального средства.

    dotnet new tool-manifest
    

    Команда создает файл с именем .config/dotnet-tools.json.

  3. Выполните следующую dotnet tool install команду, чтобы установить ReportGenerator:

    dotnet tool install dotnet-reportgenerator-globaltool
    

    Эта команда устанавливает последнюю версию ReportGenerator и добавляет запись в файл манифеста средства.

  4. Выполните следующую команду dotnet add package, чтобы добавить пакет coverlet.msbuild в проект Tailspin.SpaceGame.Web.Tests:

    dotnet add Tailspin.SpaceGame.Web.Tests package coverlet.msbuild
    
  5. Выполните следующую dotnet test команду, чтобы запустить модульные тесты и собрать покрытие кода:

    Примечание.

    Если вы используете терминал PowerShell в Visual Studio, символ продолжения строки является обратным символом (`), поэтому используйте этот символ вместо символа обратной косой черты (\) для команд с несколькими строками.

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

    Если команда завершается ошибкой, попробуйте запустить ее следующим образом:

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

    Эта команда похожа на ту, которая была выполнена ранее. Флаг /p: указывает средству coverlet, какой формат данных об объеме протестированного кода будет использоваться и где будут размещены результаты.

  6. Выполните следующую dotnet tool run команду, чтобы использовать ReportGenerator для преобразования файла Cobertura в HTML:

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

    В папке CodeCoverage в корневом каталоге проекта появится множество HTML-файлов.

  7. В Visual Studio Code разверните папку CodeCoverage, щелкните правой кнопкой мыши index.htm, а затем выберите "Показать" в проводник (показать в Finder в macOS или открыть папку с папкой в Linux).

  8. В Windows Обозреватель (Finder в macOS) дважды щелкните index.htm, чтобы открыть его в веб-браузере.

    Вы увидите сводку отчета о охвате.

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

  9. Прокрутите страницу вниз, чтобы просмотреть разбивку данных об объеме протестированного кода по типу класса.

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

  10. Выберите ссылку, чтобы TailSpin.SpaceGame.Web.LocalDocumentDBRepository<T> просмотреть дополнительные сведения.

    Обратите внимание, что метод GetItemsAsync охватывается модульными тестами, но метод CountItemsAsync не имеет покрытия.

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

    Это имеет смысл, так как FetchOnlyRequestedGameRegion метод теста вызывает GetItemsAsync метод, но не вызывает CountItemsAsync этот метод. (Чтобы просмотреть тестовый код, просмотрите DocumentDBRepository_GetItemsAsyncShould.cs file.)

Создание ветви

Теперь, когда вы можете создать отчет о охвате кода локально, вы готовы добавить задачи в конвейер сборки, который выполняет те же задачи.

В этом разделе вы создадите ветвь с именем code-coverage(на unit-tests основе ветви) для хранения работы. На практике вы обычно создаете эту ветвь из main ветви.

  1. В Visual Studio Code откройте интегрированный терминал.

  2. В терминале выполните следующую git checkout команду, чтобы создать ветвь с именем code-coverage:

    git checkout -B code-coverage
    

Добавление задач сборки

В этом разделе вы добавите задачи, которые измеряют покрытие кода в конвейер сборки.

  1. В Visual Studio Code измените azure-pipelines.yml следующим образом:

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

    Эта версия основывается на вашей текущей конфигурации. Ниже приведены общие сведения о новых возможностях:

    Задача Azure Pipelines отображаемое имя; Description
    DotNetCoreCLI@2 Установка средств .NET из локального манифеста Устанавливает средства, перечисленные в файле манифеста, dotnet-tools.json
    DotNetCoreCLI@2 Выполнение модульных тестов — $(buildConfiguration) Выполняет модульные тесты и собирает данные об объеме протестированного кода в формате Cobertura
    DotNetCoreCLI@2 Создание отчета об объеме протестированного кода Преобразует данные в формате Cobertura в формат HTML
    PublishCodeCoverageResults@1 Публикация отчета об объеме протестированного кода Публикует отчет в конвейере

Зафиксируйте изменения и отправьте ветвь в GitHub

Здесь вы отправляете изменения в GitHub и видите выполнение конвейера. Помните, что в настоящее время вы находитесь в code-coverage ветви.

Хотя это не обязательно, здесь вы добавите и зафиксируйте каждый файл отдельно, чтобы каждое изменение связано с описательным сообщением фиксации.

  1. В Visual Studio Code перейдите в терминал.

  2. Добавьте и зафиксируйте файл Tailspin.SpaceGame.Web.Tests.csproj, который сейчас содержит ссылку на пакет coverlet.msbuild:

    git add Tailspin.SpaceGame.Web.Tests/Tailspin.SpaceGame.Web.Tests.csproj
    git commit -m "Add coverlet.msbuild package"
    
  3. Добавьте и зафиксируйте файл манифеста средства dotnet-tools.json:

    git add .config/dotnet-tools.json
    git commit -m "Add code coverage"
    
  4. Добавьте и зафиксируйте azure-pipelines.yml, содержащий обновленную конфигурацию сборки:

    git add azure-pipelines.yml
    git commit -m "Add code coverage"
    
  5. Отправьте ветвь в code-coverage GitHub.

    git push origin code-coverage
    

Просмотр выполнения тестов в Azure Pipelines

Здесь вы увидите тесты, выполняемые в конвейере, а затем визуализировать результаты из планов тестирования Azure.

  1. В Azure Pipelines выполните трассировку сборки с помощью каждого шага.

  2. Когда сборка завершится, вернитесь на страницу сводки и выберите вкладку "Покрытие кода".

    Вы просматриваете те же результаты, что и при локальном выполнении тестов.

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

    При необходимости вы можете просмотреть результаты в Azure Pipelines.

Добавление мини-приложения панели мониторинга

В предыдущем разделе вы добавили мини-приложение "Тренд результатов теста" на панель мониторинга, что позволяет другим пользователям быстро просматривать тенденции результатов теста с течением времени.

Здесь вы добавите второе мини-приложение, которое суммирует покрытие кода.

  1. На новой вкладке браузера перейдите к marketplace.visualstudio.com.

  2. На вкладке Azure DevOps найдите покрытие кода.

  3. Выберите мини-приложения покрытия кода (опубликовано Шейн Дэвис).

  4. Выберите Получить бесплатно.

  5. В раскрывающемся списке выберите организацию Azure DevOps.

  6. Выберите Установить.

  7. Вернитесь в Azure DevOps.

  8. Перейдите в раздел Overview>Dashboards (Обзор > Панели мониторинга).

  9. Выберите команду Изменить.

  10. Найдите покрытие кода и выберите "Покрытие кода".

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

  11. Перетащите элемент Объем протестированного кода на холст.

  12. Щелкните значок Шестеренки, чтобы настроить мини-приложение.

  13. Сохраните все параметры по умолчанию, за исключением следующих значений:

    • Ширина: ввод 2
    • Определение сборки: выбор конвейера
    • Измерение покрытия: выберите "Линии"
  14. Выберите Сохранить.

  15. Нажмите Done Editing (Завершить правку).

    Это мини-приложение показывает процент кода, который протестирован с помощью модульных тестов.

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

Теперь в вашем конвейере настроена проверка объема протестированного кода. Несмотря на то, что на данный момент доля протестированного кода невелика, вы уже заложили фундамент, на котором будет строиться вся работа по дальнейшему улучшению результатов.

Позже можно настроить крышку для проверка, чтобы узнать, предоставляют ли тесты минимальное пороговое значение покрытия. Пороговое значение может составлять 30 процентов, 50 процентов или 80 процентов покрытия в зависимости от ваших требований. Сборка завершится ошибкой, если тесты охватывают меньше этой суммы.

Удаление файлов со сведениями об объеме протестированного кода

Как вы помните, при запуске средства Reportgenerator ранее в папке CodeCoverage в корневом каталоге проекта появилось множество HTML-файлов.

Эти HTML-файлы не предназначены для включения в систему управления версиями и больше не нужны. Несмотря на то, что файл gitignore проекта уже настроен, чтобы игнорировать что-либо в каталоге CodeCoverage, рекомендуется удалить эти файлы, чтобы они не были добавлены в репозиторий Git в будущих модулях.

В Visual Studio Code перейдите в окно терминала, а затем в корневом каталоге проекта выполните следующую команду.

rm -rf CodeCoverage/