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

Завершено

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

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

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

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

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

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

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

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

  • Результаты проверки объема протестированного кода записываются в 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
    

    Многие HTML-файлы будут отображаться в папке CodeCoverage в корне проекта.

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

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

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

    Снимок экрана: сводка отчета о охвате локального кода, показывающая охват линии на 7,7%.

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

    Снимок экрана сводного отчета по классам о локальном покрытии, показывающий статистику покрытия по классам, найденным в коде Tailspin.SpaceGame.Web.

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

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

    Снимок экрана с деталями покрытия локального класса и визуальным представлением покрытия модульного теста для двух методов C# — одного со всеми строками кода зелёными (покрытыми) и другого со всеми строками красными (непокрытыми).

    Это имеет смысл, так как 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 отображаемое имя; Описание
    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. Когда сборка завершится, вернитесь на страницу сводки и выберите вкладку "Покрытие кода ".

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

    Снимок экрана: Azure Pipelines, на котором показана вкладка

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

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

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

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

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

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

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

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

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

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

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

  8. Перейдите на Обзор>панели мониторинга.

  9. Выберите "Изменить".

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

    Снимок экрана: Visual Studio Marketplace с карточкой мини-приложения

  11. Перетащите Code Coverage на рабочую область.

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

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

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

  15. Выберите "Готовое редактирование".

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

    Снимок экрана виджета покрытия кода Azure DevOps, показывающего 8 процентов покрытия в демонстрационном проекте.

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

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

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

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

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

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

rm -rf CodeCoverage/