Visual Studioの外部ツール機能でOpenCoverを呼び出す方法(カバレッジ測定、.exe編)

### オープンソースのカバレッジ測定ツール(.NET)の簡単な使い方と、外部ツールに登録して利用する方法を解説します。

VisualStudioはEnterprise版であればカバレッジを測定できますが、料金が高く個人で利用できる値段ではありません。
代替策として、オープンソースで利用できる`OpenCover`と、レポート変換ツール`ReportGenerator`を利用し外部ツールから呼び出せるように設定します。

※下記の方法はexe形式のみを対象としています。Webアプリ(asp.net)を計測するにはIISExpressを使いますが、設定がややこしいので別記事で書きます。

### 利用ツール

* [OpenCover-https://github.com/OpenCover/opencover](https://github.com/OpenCover/opencover)
* [ReportGenerator-https://github.com/danielpalme/ReportGenerator](https://github.com/danielpalme/ReportGenerator)

## OpenCoverとReportGeneratorをインストールします

NuGetでインストールします

```
PM> Install-Package OpenCover
PM> Install-Package ReportGenerator
```

* Visual Studioで適当なプロジェックトを作り`ツール`メニューから`ソリューションのNuGetパッケージの管理`を選んでインストールしても大丈夫です(%USERPROFILE%\.nuget\packages\にインストールされます)

メニューからパッケージの管理画面を開きます。
![Nuget-pm.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276579/ba4cdce8-564a-fe3c-1a62-c5b757a7b38c.png)

パッケージ検索画面で検索して、両ツールを追加してください。
![NuGet-OpenCover.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276579/7d39353a-1943-ec11-219b-bf3dc583c306.png)

## 最低限必要なコマンドラインの説明

### OpenCover

| 引数 | 説明 | 例 |
|-----------|------------|:------------|
| -target:<ターゲットパス>  | カバレッジ計測対象のexeパス |-target:"C:\TestTarget\bin\Debug\TestTarget.exe" |
|-output:<出力ファイル(xml)>|計測結果を保存するパス(xml)|-output:"C:\TestTarget\bin\Debug\results.xml" |
|-register[:user]|プロファイラへの登録で利用するユーザを指定。管理者権限がない場合、userを指定すれば良いようです|-register:user|
|-mergeoutput|指定した場合、前回の出力結果にマージします|-mergeoutput|

### ReportGenerator

| 引数 | 説明 | 例 |
|-----------|------------|------------|
|-reports:<OpenCover出力ファイル(xml)>  | OpenCoverで出力した測定結果ファイル(xml) |-reports:"C:\TestTarget\bin\Debug\results.xml" |
|-reporttypes:<出力タイプ>|Html,HtmlInline,MarkdownSummaryなど選択できます|-reporttypes:HtmlInline; |
|-targetdir:<出力先>|レポートファイル出力先|-targetdir:C:\TestTarget\bin\Debug\|


## 外部ツールへの登録

Visual Studioの`ツール`⇒`外部ツール`で上記ツールを呼び出せるように登録します。

## OpenCover

![external-opencover.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276579/570acaec-9ec9-e98f-dec1-771743c0480e.png)

インストールしたOpenCoverのバージョンに合わせて変更してください。

| 引数 | 説明 | 
|-----------|------------|
| タイトル| OpenCover| 
| コマンド | %USERPROFILE%\.nuget\packages\opencover\4.7.1221\tools\OpenCover.Console.exe| 
| 引数 | -target:"\$(TargetPath)" -output:"\$(TargetDir)reports.xml" -register:user| 

## ReportGenerator

![external-reportgen.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276579/bc084cb6-542e-8c44-314e-857f07b3d42d.png)

インストールしたReportGeneratorのバージョンに合わせて変更してください。

| 引数 | 説明 | 
|-----------|------------|
| タイトル| ReportGenerator| 
| コマンド | %USERPROFILE%\.nuget\packages\\reportgenerator\4.8.10\tools\net47\ReportGenerator.exe| 
| 引数 | -reports:"\$(TargetDir)reports.xml" -reporttypes:HtmlInline; -targetdir:"\$(TargetDir)" |

## 実行方法と出力サンプル

1. ソリューションエクスプローラーから計測対象のプロジェクトファイルを開いて(\$(TargetDir)に影響)から、登録したツール(`OpenCover`)を実行します。
1. 手動でプログラムを動かします(単体テストのようなイメージで実行すると網羅率が上がります)
1. プログラムを終了させた後`ReportGenerator`を実行します。 
1. 処理完了後、出力先(-targetdir:)に`index.html`ができているので開きます。

### 出力サンプル

* テスト対象アプリ(四則演算のうち、×、÷のみを実行)

![test-taget.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276579/20851537-e858-160b-2d17-10c683be51df.png)


* サマリー
  * カバレッジ、複雑度のサマリが表示されます。
  * 掛け算、割り算を実行したことがわかります(割り算は通っていない分岐が残っている)。

![report-summary.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276579/f5a7c7e7-195f-0d39-1281-e28599cfa502.png)


* ソース(サマリをスクロールすると表示、キャプチャーの都合で分けています）

  * 割り算で0除算の分岐を通っていないことがわかります。

![report-coverage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276579/39158dcf-ea88-7797-d1ea-0d6bd47c2b06.png)