Angular2 Unit Testing - カバレッジ編

Angular2の実装の方法は記事をよく目にする機会が増えたので、テストについての自分が困らないように調べてみたシリーズ。

今回はカバレッジ編。

(注意)Angular 2.0.0-beta.9 をベースに話しています。
E2Eテストはprotractorがそのまま利用できると思うので、ここでのテストはユニットテストの話です。

Angular2 Unit Testing

  1. 準備
  2. 基本
  3. Mock, Spyの基本(TBD)
  4. DOMのテスト
  5. XHRのテスト
  6. Componentのテスト(TBD)
  7. Serviceのテスト(TBD)
  8. Pipeのテスト
  9. Directiveのテスト(TBD)
  10. カバレッジ

カバレッジ編

コード網羅率(コードもうらりつ、英: Code coverage )コードカバレッジは、ソフトウェアテストで用いられる尺度の1つである。プログラムのソースコードがテストされた割合を意味する。
コード網羅率 - Wikipedia

カバレッジを取得することのメリットは、コードの危ない部分に対して効果的にテストができているか客観的に評価できることです。。
特にHTML形式のレポートは、コードとテストを実行した部分を重ねて表示することができ、結果を視覚的に見やすくしてくれます。

最近のJavaScriptのテストではカバレッジ取得のための環境が整ってきたこともあり、積極的に活用していくべきです。

karma-coverageでカバレッジを測定する

Karmaでカバレッジを取得するためには、プラグインの1つであるkarma-coverageを利用します。
早速、リポジトリのdevDependencyに追加します。

1
npm install karma karma-coverage --save-dev

続いてkarma.conf.jsの設定を変更します。

karma.conf.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
'use strict';
// Karma configuration

let baseLibs = [...];

module.exports = function (config) {
config.set({

// ...省略

// (1)
// (*.spec.js, *.mock.js)以外のJavaScriptファイルをカバレッジ測定の対象とします
preprocessors: {
"app/**/!(*spec|*mock).js": ['coverage']
},

// (2)
// テスト完了時のreporterにカバレッジ用reporterを設定します
reporters: ['mocha', 'coverage'],

// (3)
// カバレッジ用reporterの出力先, フォーマットを指定します
// see https://github.com/karma-runner/karma-coverage/blob/master/docs/configuration.md
coverageReporter: {
dir : 'report/coverage/',
reporters: [{
type: 'html'
}]
}

// ...省略

})
}

テストを実行するとreport/coverageの直下にHTML形式のカバレッジレポートが出力されます。

karma-coverage内部では、JavaScriptのカバレッジ測定ツールとして有名なistanbulを利用しています。
HTMLレポートでは、ディレクトリやファイルごとにカバレッジを知ることができます。これを見ながらカバレッジの低い部分などに追加のテストを書いていきます。

コードとテスト実行した部分を重ねあわせて表示することで、テストが不足している部分を容易に発見できます。

ところがこのままでは、レポートのコードがtsファイルをトランスパイルしたJavaScriptファイルとなっているため、実際に作成したtsファイル上のどの部分に該当するかが非常に分かりにくいです。

remap-istanbulでtsファイルとリンクさせる

先ほどのカバレッジレポートを改良してトランスパイル前のtsファイルをリンクさせます。リンクさせるにはremap-istanbulを利用します。

remap-istanbulとは、tsファイルをトランスパイルした際に生成されるSouceMap(ここではinline SouceMap)を元に、カバレッジレポートをオリジナルのtsファイルにリンクさせるツールです。
早速、リポジトリのdevDependencyに追加します。

1
npm install karma remap-istanbul --save-dev

続いてkarma.conf.jsの設定を変更します。カバレッジレポートのフォーマットをhtmlではなくjsonに変更します。

karma.conf.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
'use strict';
// Karma configuration

let baseLibs = [...];

module.exports = function (config) {
config.set({

// ...省略

// (1)
// (*.spec.js, *.mock.js)以外のJavaScriptファイルをカバレッジ測定の対象とします
preprocessors: {
"app/**/!(*spec|*mock).js": ['coverage']
},

// (2)
// テスト完了時のreporterにカバレッジ用reporterを設定します
reporters: ['mocha', 'coverage'],

// (3)
// カバレッジ用reporterの出力先, フォーマットを指定します
// see https://github.com/karma-runner/karma-coverage/blob/master/docs/configuration.md
coverageReporter: {
dir : 'report/coverage/',
reporters: [{
type: 'json',
subdir : '.',
file : 'coverage-final.json',
}]
}

// ...省略

})
}

テストを実行するとreport/coverage/coverage-final.jsonにJSON形式のカバレッジレポートが出力されます。
これをremap-istanbulでHTML形式のレポートに仕立てて行きます。

1
node_modules/.bin/remap-istanbul -i report/coverage/coverage-final.json -o report/coverage/ -t html

コマンドを実行するとreport/coverageの直下にHTML形式のカバレッジレポートが出力されます。

今度はtsファイルとカバレッジレポートがリンクするようになりました。
めでたし。めでたし。

まとめ

カバレッジの取り方とレポートの表示についてでした。
HTMLレポートの出力方法は他にもあると思いますので、いろいろ試してみるといいでしょう。
カバレッジレポートを取得することで、テストが十分でない箇所を明らかにすることができ、つまらないテストにゲーム的な要素が加わってテストを書くことが楽しくなります。

PR

こちらに初学者のためのMinimum starter kitを作成しましたので、ぜひ利用してください。
(もちろんカバレッジも取得できます!!)

mitsuruog/angular2-minimum-starter: Minimum starter kit for angular2 https://github.com/mitsuruog/angular2-minimum-starter