My External Storage

Jul 25, 2017 - 5 minute read - Comments - dot-net c-sharp DevOps

.NET Standard1.6プロジェクトのCI環境を構築する。

TL;DR

.NET Standard1.6ベースでNugetパッケージを作っています。開発で利用しているCI環境の構築方法です。実際に利用しているリポジトリは以下になります。

Build status codecov

https://github.com/budougumi0617/Testable

現状出来ているのは以下です。git tagで自動パッケージリリースなども追って対応していきたいなと思っています。

  • GitHubのリポジトリが更新されたとき、自動でビルドが実施される。
  • ビルド時にリポジトリに同梱されているテストプロジェクトが自動で実行される。
  • テストのカバレッジを計測し、Codecovで結果を可視化する。
  • バッジでビルド結果とカバレッジ率がわかる。

.NET Standard1.6(VS2017)環境で構築したプロジェクト向けの記事なので、その他の環境の場合はまず公式サイトなどを参考にしてください。

CodeCov Test Coverage Integration

AppVeyorとCodecovを使ってC#のコードカバレッジを計測する

構築手順

利用ツール/サービス

基本的に無料のツールで構築していきます。

用途 ツール名
IDE Visual Studio2017/Visual Studio for Mac
テスト XUnit/OpenCover
構成管理 GitHub
CI AppVeyor/Codecov

以降では、GitHubリポジトリに.NET1.6プロジェクトが入った状態のあとの説明です。

XUnitプロジェクトを作成する。

まず、以下の記事を参考に、テストプロジェクトを作成してください。

.NET StandardプロジェクトをxUnitでテストする方法

VS for Macの場合は、「新しいプロジェクトの追加」から、「xUnit Test Project」を選択することで同等のプロジェクトを作成することができます。.NET1.6プロジェクトを参照するテストプロジェクトを作成する場合は.NET Coreプロジェクトで作るのが無難です。

その後、カバレッジ計測に必要な、xunit.runner.consoleOpenCoverNugetからテストプロジェクトに追加しておいてください。全てを行うと、テストプロジェクトの.csprojファイルには以下のパッケージが追加されているはずです。

  <ItemGroup>
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
    <PackageReference Include="xunit" Version="2.2.0" />
    <PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
    <PackageReference Include="xunit.runner.console" Version="2.2.0" />
    <PackageReference Include="OpenCover" Version="4.6.519" />
  </ItemGroup>

テスト対象のプロジェクトにDebugType属性を追加する。

VS2017以降で作成した.NET Standardプロジェクトのカバレッジを、OpenCoverで測るためには、テスト対象のプロジェクトの.csprojファイルのPropertyGroup<DebugType>full</DebugType>を追加する必要があります。

  <PropertyGroup>
    <TargetFramework>netstandard1.6</TargetFramework>
    <DebugType>full</DebugType>
  </PropertyGroup>

詳細については、以下を参照してください。

OpenCoverでVS2017でビルドした.NETプロジェクトのカバレッジを測る

Codecovの設定ファイルの作成

Codecov

Codecovはカバレッジの結果を可視化してくれるオンラインサービスです。GitHubへの通知なども行えるので、例えば「PRのカバレッジが、コード変更前よりX%下がったとき失敗通知をGitHubへ送る」などと言った設定もできます。 リポジトリのルートディレクトリに.codecov.ymlを配置しておくことで、諸々のしきい値などを設定できます。私はいつもテンプレを使っています。

Testable/.codecov.yml

各パラメータの詳細は以下のWikiを参照してください。

Codecov Yaml

Appveyorの設定

Appveyor

AppveyorはWindowsコンテナで実行できるCIツールです。 リポジトリのルートディレクトリに、以下のappveyor.ymlファイルを配置します。

Testable/appveyor.yml

version: 0.0.{build}
pull_requests:
  do_not_increment_build_number: true
image: Visual Studio 2017
configuration: Debug
platform: Any CPU
before_build:
- cmd: >-
    git submodule init
    git submodule update --init --recursive
    dotnet restore Testable.sln    
build:
  project: Testable.sln
  verbosity: minimal

# Set OpenCover setting according to below URL
# https://github.com/OpenCover/opencover/wiki/Usage

test_script:
- ps: >-
    $opencover = (Resolve-Path "~\.nuget\packages\OpenCover\4.6.519\tools\OpenCover.Console.exe").ToString()

    $filter = "+[Testable*]* -[*.Tests*]*"

    regsvr32 x86\OpenCover.Profiler.dll

    regsvr32 x64\OpenCover.Profiler.dll

    & $opencover -target:"c:\Program Files\dotnet\dotnet.exe" `
    -targetargs:"test -f netcoreapp1.1 -c Debug Testable.Tests/Testable.Tests.csproj" `
    -mergeoutput `
    -hideskipped:File `
    -output:opencoverCoverage.xml `
    -oldStyle `
    -filter:$filter `
    -searchdirs:Testable.Tests/bin/Debug/netcoreapp1.1 `
    -register:user
    
    $env:Path = "C:\Python34;C:\Python34\Scripts;$env:Path"

    python -m pip install --upgrade pip

    pip install codecov

    &{codecov -f "opencoverCoverage.xml"}    

notifications:
- provider: GitHubPullRequest
  on_build_success: true
  on_build_failure: true
  on_build_status_changed: true

主要なところを解説しておきます。filterやプロジェクト名の置き換えはOpenCoverのWikiを参考に行ってください。

ymlの記載 解説
image: Visual Studio 2017 VS2017が入っているイメージコンテナを使います。
dotnet restore Testable.sln Nugetの復元はdotnetコマンドで出来ます。
- ps: >- ここから下がPowershellスクリプトです。 処理と処理の間に空行を入れないと正しく実行されないので注意してください。
$runner = "dotnet test" テストもdotnetコマンドで実行します。
pip install codecov おまじないです。Appveyor/Codecov連携の詳細はこの辺を参考に。

バッジを貼る

あとは各種サービスにログインして、リポジトリに対してサービスをONにしてください。バッジの貼り方など、このへんは既存のやり方と変わらないので省略します。以下の記事などを参考にどうぞ。

CodeCov Test Coverage Integration AppVeyorとCodecovを使ってC#のコードカバレッジを計測する

おしまい

以上で設定はおしまいです。エラーが出ていないのにカバレッジが取れないときは、

  • テスト対象のプロジェクトにDebugType属性をつけるのを忘れていないか
  • OpenCoverfilterの設定がおかしくなっていないか

などを確認してください。とくにDebugType属性が今までと違うところでハマりました。。。


ツールなどの選定についての補足

各サービス、フレームワークを選んだ(選べなかった)理由を解説しておきます。

Appveyor or Visual Studio Team Services/Teeam Foundation Server

VSTSGitHubに貼れるテストカバレッジのバッチを作る方法がなかったので、Appveyorとなりました。 .NET StandardなのでLinuxコンテナのCIサービスでもビルドは出来るのですが、dotnetコマンドなどが標準のコンテナで使えるAppveyorを使います。

MSTest or XUnit or NUnit

MSTestVisual Studio for Macでは使えません。なので選べません。NUnitの場合、.NET1.6プロジェクトで利用するにはNUnit3である必要があります。が、OpenCoverNUnit3をフルサポートしていないようなのでXUnitにしました。

Coveralls or Codedev

CoverallsですとC#向けにプラグインがあるので連携が簡単です。ただ、Codecovでも流用できるのと、UIが好みなのでCodecov使ってます。

関連記事