rider.お品書きサクッと書いて公開して、後でちまちま修正する事がママあります。なんじゃこりゃ?と思ったら、数日してから見て貰えると嬉しいです。「スクラムの実践方法を分かりやすくマンガも交えて解説。2013の21日目の記事です。マイナーなネタと思われます。私自身はJenkinsの管理者ではない(ド素人)ので、外した事を書いているかもしれません。誰かの役に立つかなぁ?困っている人は居そうですが...能書きは良いので、ツールを使いたいって人は、CodePlexで公開しているのでどうぞ。2013でカバレッジ測定します。それだけであればVSで完結してしまうのですが、カバレッジ測定をJenkinsで行って、結果をEmmaプラグインで表示したい、というネタです。経緯:とある開発プロジェクトが開始され、私がプロジェクトに参加した時点で、以下の事が決まっていました。プロジェクト管理はALMinium、CIはJenkins、ソース管理はSubversionで行う。クライアント側はWindows、サーバー側はJavaで開発する。・・・いや、Java側は多分快適なんでしょうが、Windows側は色々苦しいんですよ、それだと(ちなみに私はWindows側のアーキテクトとして作業する予定で参加)。言っても、決まってしまっているので、Java側主導でWindows側が放置っぽくなってしまわないようにしないとなぁ...と思いました。全部Windowsなら、間違いなくTFSでサクッとやるところなんですが。Studioの環境をちまちまと整えなければならないなど、早くもメンドクサイ感が(名誉のために補足:環境構築してくれた方は前向きに取り組んでいます)。MSTestでのテスト実行もOKとなったので、次の段階としてカバレッジ測定結果を表示させようとしたのです。この辺りとか:[hudson]hudsonでMSTestのテスト結果とカバレッジをレポートする設定をしてみた。結果とコードカバレッジを表示する方法うを、またしてもメンドクサイ事態に。専任でもない人にこういうのを頼み続けると、本当に必要な時に動いてくれなくなってしまうので、私の方で何とかしようと。(その代わり、業務時間外でやることで、この部分は自分のネタにさせてもらいました)Jenkinsの知識ほぼ0であったので、カバレッジデータの変換プロセスを把握する事から開始。上のブログ記事によると、MSTestで出力されるカバレッジデータ(*.coverage)はバイナリーの独自形式で、これをMSBuildのカスタムタスクでXML形式(内容不明)に変換、その後XMLスタイルシートでEmma形式に変換させる。Emma形式になれば、Emmaプラグインで表示する事が出来る、という流れを把握。ようするに、これを自動化して、単一のツールにしてしまえば扱いが大幅に楽になる。別のJenkins環境への展開も容易になるはずだ。task」は、VS2008に対応したコードだ。Studioのバージョン毎に違っている。おまけに、VS2010からは大幅に仕様が変更されており、ファイルが全く認識されない。Studioのバージョンを使って解析しないと、結果が怪しいか又はエラーが発生するということだ。プラグインの配布ファイルには、何故かカバレッジ測定結果を変換するライブラリ「Microsoft.VisualStudio.Coverage.Analysis.dll」が添付されている。Studioに添付されているものであり、含まれていないのが筋だ。MSが配布しているのだから、ライセンス的には問題ない(?)のだろうが、何れにしてもこれはVS2008向けだ。他のバージョンでは使用しないほうが良い。Studioがビルド環境にインストールされているはずだ。初めからそれを使えばいいのだ。task」のソースコードを見ると、ライブラリを呼び出してバイナリデータをXMLに変換している。何のことは無い、バイナリデータがDataSet(インメモリのテーブルコレクション)に変換されるので、DataSet.WriteXmlでデータセット形式のXMLで書き出しているだけだ。このXMLをjenkins.orgで配布されているXMLスタイルシートを使って、Emma形式に変換する。Utilityには頼らない。変換は全てインメモリでやれば、テンポラリファイルにまつわる問題を排除できるし、XMLスタイルシートもEXE内に埋め込めば、ファイルが読めなくて刺さるとかいう問題もなくなるので、この辺りはツールとしてシンプルに磨き上げる。次に、VS2010以降のライブラリとの互換性の問題。そもそも変換ライブラリのクラスがちょっと違ってる。ILSpyを使ってごにょごにょし、ちょっとテストコードを書いて、使用方法を把握。Studioを切り替えられるようにしたかったため、共通のインターフェイスを独立したDLLに定義し、それぞれのバージョンに対応するライブラリとして、プラグインのような形で動的にロードするように実装。これで、バージョン指定で呼び換えが可能になった。異なるバージョンの、同一の名称を持つDLLの読み込みを可能にするため、サイドバイサイドアセンブリ構成という機能を使う。VS2010と言った具合に)、その中にインストール済みのカバレッジ変換DLLを手動コピーして配置してもらう。この部分が導入で面倒なところだ。最後にツールの体裁を整え、CodePlexにサインアップして公開した。合わせて、この時点のソースコードをCodePlexにチェックインした。このツールを客先で使ってもらった。Jenkinsへの登録は、コマンドラインツールとして起動するだけだ。引数も出来るだけ省略可能にしてあるし、ファイルを明示的に指定しなくて、フォルダ指定だけで勝手に探索して変換してくれる。おまけに並列実行させているので、大量のカバレッジファイルがあっても高速に処理できる。めでたしめでたし...バージョン2:何かがおかしい数日間、カバレッジの結果をJenkins上で眺めていたが、どうも変だ。ブロック数や行数など、想定よりも少なすぎる。Studio上でのカバレッジブラウザと結果を見比べているうちに、何となく原因が見えてきた。これはEmmaプラグインの問題だ。いうと怒られるので、見解の相違といったところか(+XMLスタイルシートの問題でもある)。Emmaプラグインの入力となるXMLファイルは、「Javaのカバレッジ測定結果」が前提なのだ。CLSの型システムは似ている所は多いが、根本的に思想が異なるので、無理やり同一視すると今回のような問題が発生する。Javaでは、パッケージと物理的なソースコードの配置は1対1で対応させることが求められる(多分?)。そのためか、Emmaの解析階層構造は、「パッケージ」「ソースファイル」「クラス」「メソッド」の順で並ぶ(実際にはパッケージが固められたjarが、暗黙に先頭に存在する)。CLSはパッケージに対応する「名前空間」と、ソースファイルの物理的な対応付けは存在しない。それどころか、jarに対応する「アセンブリ(DLL)」は、名前空間と直接対応しない。とある名前空間が別々のアセンブリに同居していても何ら問題はない。名前空間とは、構造を定義しない単なる名前でしかない。CLS型システムの利点なのだ。Javaでは、一つのクラスは一つのソースコードに対応する。そのため、Emmaの階層構造で「ソースファイル」が「クラス」の前に存在しても問題はない。classが存在する。classは、単一のクラスに含まれるメンバを、複数のソースコードに記述する事が出来る機能だ。そのため、Emmaの階層構造では順序を逆にしないと、正しく構造を反映した事にならない。従って、Emmaの階層構造をそのまま当てはめるには無理がある。XMLスタイルシートで変換されたXMLを眺めると、同一のパッケージ配下に、同じソースファイルのエレメントが複数存在したり、同じクラスのエレメントが複数存在したりしている。その結果、Emma側ではどれか一つだけが読み取られて表示されているようだ。XMLスタイルシートの集計が十分に賢ければ、このようなエレメントを同一とみなして、それっぽく集計できたのかもしれない。原因が分かった当初、このスタイルシートを修正しようと思ったのだが、あまりに複雑で理解不能であったため、早々に放棄。自分で一から集計コードを書く事にした。自分で集計するなら、もうXMLに頼る必要もない。DataSetから直接値を取得して集計すればいい。いうわけで、いったんXMLをMemoryStreamに書いていたコードもバッサリと切り捨て、コードをシンプルにすることが出来た。集計計算を行う部分は、「Javaがこうだから.NETではこうなって...」みたいな事を考えるたびに混乱し、正しい集計アルゴリズムに落ち着くまでが苦痛だった。こんな作業が待っていることがはじめから分かっていたら、作ってなかったかもしれない...最後に、懸念事項であった、インストールされているカバレッジ変換DLLを手動コピーしなければならない作業を排除した。Studioがインストールされているか、どこにインストールされているかは、レジストリを見ればわかる。レジストリを見て、自動的にDLLのパスを把握し、自力でそこからロードするようにした。DLLを動的に読み込むため、サイドバイサイドアセンブリ構成は不要になったので削除。各DLLのクラスをリフレクションで参照するようにして、DLLの依存関係も排除。これで、ツールをダウンロードしたらzipファイルから展開して、すぐに使う事が出来るようになった。converter」はリリースされ、晴れて正しいカバレッジ集計をJenkinsで確認できるようになりました。「パッケージ」にマッピングする方法で解決したのですが、閲覧者が求めている集計とちょっと違う気がします。「アセンブリ(DLL)」を「パッケージ」にマッピングするように集計すべきだったかもしれない、あるいはオプションで切り替えれるようにした方が良かったかもしれない、という気がしています。あとは、物好きな人が改良して下さい。WordPress%d人のブロガーが「いいね」をつけました。