2か月くらい前から書こう書こうと思ったままほったらかしてた内容です。AppVeyorという.NETに特化したビルドサービスとCodecovというカバレッジサービスを利用してGitHubのC#のコードカバレッジを計測します。

利用するサービスとか


サービスなど役割
GitHubリポジトリ
MSTest単体テスト
OpenCover単体テストのカバレッジレポート出力
AppVeyorコードのビルド
単体テストの実施
カバレッジレポートをCodecovに送信
Codecovカバレッジレポートの表示

MSTestでやってますがxUnitでも可能です。xUnitでやっている方はいらっしゃいました。というか、C#でOSSのコードカバレッジ計測してる記事は日本語ではこの方のしか見つかりませんでした。

また、COVERALLSというサービスもありますがこっちはドキュメントがさっぱりだった(のと見た目がイマイチ)なのでCodecovを利用することにしました。前述の方はCOVERALLSでもやってらっしゃるので、COVERALLS使いたい方はそちらを参考にするとよいと思います。

順序


大まかには下記の流れになります。

  1. GitHubにPush
  2. GitHubからAppVeyorに通知
  3. AppVeyorが単体テスト実行 & OpenCoverを利用してカバレッジのレポート出力
  4. AppVeyorからCodecovへレポートの送信

準備


MSTestで既に単体テストのコードを記述しているものとします。

OpenCoverのインストール

NuGetからOpenCoverをインストールします。OpenCoverについてはこれだけ。

各サービス連携

GitHubとAppVeyor、GitHubとCodecovをそれぞれ連携します。特に書くことないので省略。

AppVeyorの設定

リポジトリのルートディレクトリ直下にappveyor.ymlを作成します。appveyor.ymlには最低限以下を記述する必要があります。

  • ビルド前にNuGet復元する設定
  • テスト後にOpencoverを実行するコマンド
  • OpenCoverで出力したレポートをCodecovに送信するコマンド

なお、AppVeyor.ymlの書き方はここに載っています。また、appveyor.ymlの記述が正しいかどうかはログイン後に下記の「Validate YAML」というページでチェックできます。

まず、NuGetの復元から。

下記のように記述し、ソリューションを指定します。なお、 1リポジトリで1つのソリューションしか指定できないっぽいです。 (複数指定するとエラーが出る)

1
2
before_build: 
 - nuget restore ソリューション名.sln

次に、OpencoverとCodecovの送信コマンド。
OpenCoverの場所とかディレクトリのパスとかは実際のプロジェクトに応じて変更してください。

1
2
3
4
5
6
7
after_test:
#OpenCoverのコマンド
- .\packages\OpenCover.4.6.519\tools\OpenCover.Console.exe -register:user -target:"C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\MSTest.exe" -targetargs:"/noisolation /testcontainer:""テストアセンブリ.dll" -targetdir:"テストアセンブリのディレクトリ" -excludebyattribute:*.ExcludeFromCodeCoverage* -hideskipped:All -output:出力レポート名.xml
#Codecovへの送信コマンド
- "SET PATH=C:\\Python34;C:\\Python34\\Scripts;%PATH%"
- pip install codecov
- codecov -f "出力レポート名.xml"

OpenCoverのコマンドオプションが多いので横に長くなってます。1行目がOpenCoverのコマンドで2~4行目がCodecov関連のコマンドです。

なお、複数のテストプロジェクトがある場合は以前書いた記事のように複数のレポートをまとめて出力するか、個別のレポートをそれぞれ送信します。

レポートをまとめる場合は以下のように記述します。

1
2
3
4
5
6
7
8
9
10
11
12
13
after_test:
#1つ目のレポート
- .\packages\OpenCover.4.6.519\tools\OpenCover.Console.exe -register:user -target:"C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\MSTest.exe" -targetargs:"/noisolation /testcontainer:""MyTest.dll" -targetdir:".\Test\bin\Release" -excludebyattribute:*.ExcludeFromCodeCoverage* -hideskipped:All -output:出力レポート名.xml

#2つ目レポート
- .\packages\OpenCover.4.6.519\tools\OpenCover.Console.exe -register:user -target:"C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\MSTest.exe" -targetargs:"/noisolation /testcontainer:""MyTest2.dll" -targetdir:".\Test\bin\Release" -excludebyattribute:*.ExcludeFromCodeCoverage* -hideskipped:All -mergeoutput -output:出力レポート名.xml

#以下テストプロジェクトの数だけ記述...

#Codecovへの送信コマンド
- "SET PATH=C:\\Python34;C:\\Python34\\Scripts;%PATH%"
- pip install codecov
- codecov -f "出力レポート名.xml"

レポートをまとめないケースは- codecov -fの後にそれぞれのレポートをつらつら書けばよいです。
具体的には下記のような感じ。

1
2
3
4
5
6
7
8
9
10
11
12
13
after_test:
#1つ目のレポート
- .\packages\OpenCover.4.6.519\tools\OpenCover.Console.exe -register:user -target:"C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\MSTest.exe" -targetargs:"/noisolation /testcontainer:""MyTest.dll" -targetdir:".\Test\bin\Release" -excludebyattribute:*.ExcludeFromCodeCoverage* -hideskipped:All -output:出力レポート1.xml

#2つ目レポート
- .\packages\OpenCover.4.6.519\tools\OpenCover.Console.exe -register:user -target:"C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\MSTest.exe" -targetargs:"/noisolation /testcontainer:""MyTest2.dll" -targetdir:".\Test\bin\Release" -excludebyattribute:*.ExcludeFromCodeCoverage* -hideskipped:All -output:出力レポート2.xml

#以下テストプロジェクトの数だけ記述...

#Codecovへの送信コマンド
- "SET PATH=C:\\Python34;C:\\Python34\\Scripts;%PATH%"
- pip install codecov
- codecov -f "出力レポート1.xml" "出力レポート2.xml" ...

ちなみに私が書いてるappveyor.ymlはこんな感じ。

実行


Codecov側は特にやることはないので、後はGitHubにPushするだけです。Pushすると、AppVeyor側でテストが走って、Codecovにレポートが送信されます。このリポジトリこのようにビルドされて、最後にこのように表示されます。

AppVeyorのログ

Codecovのコンソール




PullRequestしたとき

プルリクしたときは下記のような感じでレポート表示してくれます。

わからないとき


公式のドキュメントとかサンプルを頑張って読みましょう。

CodecovのサンプルとかOpenCoverのサンプルとか…後は英語で検索するとか…。残念ながら日本語の情報はほとんどないです。(OpenCoverも少ないし、C#でのカバレッジサービスついては前述の方の記事くらいしかない。)

あと、OpenCoverで詰まった場合は、一旦ローカルで正しくレポートが出力されるかどうか試すとPushする手間が省けます。(最初Pushしまくってたマンです。)

その他


静的解析とかについても書きたかったけど、疲れたのでここまで。