Visual Studio Community Edition でカバレッジ計測
概要
Visual Studioでカバレッジを計測できるかと思ったら、結構大変だったのでメモ。
環境
- OS
- Windows7 SP1 64bit
- IDE
- Microsoft Visual Studio Community 2015 ver14.0.23107
プロダクト作成
プロジェクト作成
今回はプロジェクト名をSampleとする。
プロダクトコード作成
今回はCartクラスを作成する。
using System.Collections.Generic; namespace Sample { public class Cart { public List<Item> Items { get; } public Cart() { Items = new List<Item>(); } public int Count { get { return Items.Count; } } public Item Get(int index) { return Items[index]; } public void Add(Item item) { Items.Add(item); } } }
ついでにカートの中に突っ込むItemクラスを作ってみる。
namespace Sample { public class Item { public int price { get; set; } public string name { get; set; } } }
テスト用プロジェクト作成
今回はテスト対象のテストがSampleなので、プロジェクト名を Sample.Test とする。
プロダクト参照をテストプロジェクトに設定
テストコード作成
今回はCartクラスに対してのみテストするため、名前をCartTestとする。なお、テストフレームワークは Visual Studio 標準。
using System; using Microsoft.VisualStudio.TestTools.UnitTesting; using Sample; namespace SampleTest { [TestClass] public class CartTest { Cart target; [TestInitialize] public void カート作成() { target = new Cart(); } [TestMethod] public void 商品は空であること() { Assert.AreEqual(0, target.Items.Count); } [TestMethod] public void 商品が追加できること() { Item item = new Item(); target.Add(item); Assert.AreEqual(1, target.Count); Assert.AreSame(item, target.Items[0]); } } }
カバレッジ用のバッチを作成する
OpenCover を使ってコードカバレッジを計測したメモ - present
基本的に上記を参考に作成。しかし、私の環境では、OpenCoverやReportGeneratorが上記と異なるところにある。NuGetで取得したから?
以下のバッチファイルを、今回はテストプロジェクトのルートに置いておく。
また、今回自動でレポートを開くようにするため、以下を参考にした。
参考:バッチファイルからURLをブラウザで開く - Qiita
REM ###### Settings ###### SET PROJECT_NAME=Sample SET MS_TEST=C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\MSTest.exe SET REPORT_NAME=result.xml SET OUTPUT_DIR=.\html SET OPEN_COVER=.\packages\OpenCover.4.6.519\tools\OpenCover.Console.exe SET REPORT_GEN=.\packages\ReportGenerator.2.5.8\tools\ReportGenerator.exe SET TEST=.\%PROJECT_NAME%.Test\bin\Debug\%PROJECT_NAME%.Test.dll SET COVERAGE_DIR=.\%PROJECT_NAME%\bin\Debug\ SET FILTERS=+[%PROJECT_NAME%]* REM ####################### call :EXECUTE "%TEST%" start "" %OUTPUT_DIR%\index.htm exit :EXECUTE %OPEN_COVER% -register:user -target:"%MS_TEST%" -targetargs:"/noisolation /testcontainer:\"%~f1\"" -targetdir:%COVERAGE_DIR% -filter:"%FILTERS%" -output:%REPORT_NAME% -mergebyhash %REPORT_GEN% "%REPORT_NAME%" %OUTPUT_DIR% exit /b
設定項目は環境に合わせて変更する。
- PROJECT_NAME
- プロダクトのプロジェクト名。
- MS_TEST
- Microsoftの提供するテストアプリケーションの場所。バージョンやOSのビットによって変化するかも。
- REPORT_NAME
- デフォルトで特に動作に支障なし。レポート(xml)の出力先を指定する。
- OUTPUT_DIR
- デフォルトで特に動作に支障なし。レポート(htm)の出力先を指定する。
- OPEN_COVER
- OpenCoverのバージョンによって変わるかも。
- TEST
- テスト用dllのパス。デフォルト設定のDebugで生成されるパスを指定してある。異なる場所にあるなら変更。
- COVERAGE_DIR
- カバレッジを計るdllがあるディレクトリパス。デフォルト設定のDebugで生成されるパスを指定してある。異なる場所にあるなら変更。
- FILTERS
- カバレッジを計測するdllの条件を記載。
なお、Visual Studio で保存すると、なぜかBOM付きで保存されるので、テキストエディタでBOMを取らないと動かない。
上記は、UTF-8 BOMなし形式で動作確認している。
バッチ仕様
このバッチは、XXXがプロダクトのプロジェクト名だとすると、XXX.Testをテストプロジェクトとするように定めている。
参照dllはプロダクト・テストともDebugで出力されるものを使用する。
使い方
プロジェクトのビルド
最終的にdllを見ることになるので、両プロジェクトをビルドしておく。
パッケージマネージャー コンソールで以下のバッチコマンドを実行する
PS> .\Sample.Test\coverage.bat
以下のようなレポートが表示されれば成功。
NUnitの場合
NUnit.Console を NuGetから取得して、
バッチの2行を変更する。
# 4行目 SET MS_TEST=C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\MSTest.exe # 25行目 %OPEN_COVER% -register:user -target:"%MS_TEST%" -targetargs:"/noisolation /testcontainer:\"%~f1\"" -targetdir:%COVERAGE_DIR% -filter:"%FILTERS%" -output:%REPORT_NAME% -mergebyhash
↓
# 4行目 SET NUNIT=.\packages\NUnit.ConsoleRunner.3.6.1\tools\nunit3-console.exe # 25行目 %OPEN_COVER% -register:user -target:"%NUNIT%" -targetargs:"\"%~f1\"" -targetdir:%COVERAGE_DIR% -filter:"%FILTERS%" -output:%REPORT_NAME% -mergebyhash
これだと Visual Studio のインストール場所が依存しなくなるかも?
課題
事前にビルドしないとソースコードと異なる結果が出て勘違いするかもしれないので、ビルドしてから実行させる方がいい。
現状では、カバレッジに失敗してもエラー処理がないので、カバレッジ情報失敗しても最後まで処理が走ってしまう。
最後に
正直、色々なところで躓いた。まず、文献がそれほどないこと。
Visual Studio Ultimate 以上なら使えるらしいが、そうすると Professional に比べて値段がおよそ3倍以上になること。
OpenCoverをGUIで動作させることができるという拡張プラグイン(OpenCover UI)が動作しなかったこと。
バッチファイルの書き方がよく分からなかったり、Visual Studioでのバッチ起動がよく分からなかったり。
(パッケージマネージャーコンソールからの実行で本当にいいのか?^^;)
などなど。ただ、いい勉強にはなりました!