gitでPushする度にKarma-CoverageのCoverageの値をJenkinsで計測し、その増減をIdobataに投稿する


はじめに
====

単体テストをメンバーに楽しく書いてもらうために、テストコードに関する可視化は重要だと思います。
そういう機能では、

Coveralls: https://coveralls.io/

がとても有名です。しかし、CoverallsはGithub上にあるものしか対象にできません（たぶん）。
様々な事情でGithubにはPushできないGitリポジトリでもそういう可視化をしたいなぁ、と思うわけです。

というわけで、 「社内Gitlab＋Jenkins+Karma-Coverage+Idobata」という組み合わせでそれっぽいことをしてみます。

この記事でできること
------

誰かがGitリポジトリにPushする度に、Idobataに以下の投稿がされるようになります。

![Idobata.png](https://qiita-image-store.s3.amazonaws.com/0/11124/3f6d297a-fa4e-2f59-053b-8d85ee185b4f.png "Idobata.png")


設定手順
=====

gitのhookの設定
-----

push されたら JenkinsのJobをBuildするようにhookを設定しておきます。


Coverageの計測
--------

Karma-Coverageを使うケースについて説明します。

まず、普通にJenkinsでもカバレッジが収集できるように `cobertura` 形式で `clover.xml` というファイルを生成するように `karma.conf.js` に記述しておきます。以下の様な感じになります。

```javascript:karma.conf.js
    reporters: ['spec', 'coverage', 'junit'],

    coverageReporter: {
      dir: 'coverage/',
      reporters: [
        {
          type: 'html'
        },
        {
          type: 'cobertura',
          file: 'clover.xml'
        }
      ]
    },
```

Jenkinsの設定
---------

### ruby をInstallしておく

このタスクを実行するノードに **ruby** をInstallしておいてください。後述のスクリプト内で使用しています。

### 普通にテストを実行できるようにしておく

これはプロジェクト依存になるので割愛します。Jenkinsでテストが実行できるように設定しましょう。
npm や grunt 系は比較的簡単に設定できるのでそれほど悩まないでしょう。

### PluginのInstall


cobertura形式のカバレッジを読み込めるように以下のPluginをJenkinsにInstallしておきます。
https://wiki.jenkins-ci.org/display/JENKINS/Cobertura+Plugin


### カバレッジの収集の設定

Jenkinsの設定でビルド後の処理に `coverage/**/clover.xml` と書きます。

![uniqlo-ec-mobile-uk-test_Config__Jenkins_.png](https://qiita-image-store.s3.amazonaws.com/0/11124/586b17d6-29da-0cf5-ef1e-7f4d97c81d6c.png "uniqlo-ec-mobile-uk-test_Config__Jenkins_.png")

### 動作確認

ここまでの設定で、Jenkins上では カバレッジレポートが収集できているはずです。


Idobataの設定
----------

適当なRoomに「Generic Hook」を追加します。
その投稿用URLを仮に `https://idobata.io/hook/12345678-9abc-def0-1234-56789abcdef0` としておきます。

再びJenkins
-------

### ビルド手順の追加

「ビルド手順の追加」で、単体テストを実行後に「シェルの実行」を追加して、以下のスクリプトを書きます。

```sh:script2
export IDOBATA=https://idobata.io/hook/12345678-9abc-def0-1234-56789abcdef0
export CLOVER_XML=clover.xml
export COVERAGE_DIR=coverage

curl -s -L https://gist.githubusercontent.com/mokemokechicken/2c1b97febac5edacfa9b/raw/cobertura_idobata.sh | sh
```

3つほど変数を export していますが、意味は概ねわかるのではないかと思います。

### スクリプトの動作の説明

gist のスクリプトを呼び出して実行しています。そのスクリプトは以下の様な動作をします。
※ このシェルスクリプト汚いです m(__)m

* 基本的に、Jenkinsのワークスペース上に `clover.xml.<COMMIT_ID>` という名前でカバレッジレポートを保存します（約14日分程度）。CommitがPushされ、Jenkinsが起動する度に、増えることになります。
* カバレッジの増減は、「そのCommitの元となったCommitのカバレッジの値」を基準にします。これは単に `git log` で取得できます
* 但し、複数のCommitをまとめてpushされた場合は、その直前のCommitのカバレッジをJenkins上で実行していません。ので、git log では過去100件のCommitを遡ってJenkins上で実行されたCommitを(Jenkinsのワークスペース上のファイルを)探します。それを基準とするカバレッジにします。
* 後は単純に、「現在のカバレッジ」と「基準のカバレッジ」の差分を計算して、Idobataに投稿します(無い場合は諦める)。
* 今回は、「行数のカバレッジrate」を使っています。

Jenkins上の前回のBuildを基準とするということも考えられますが、複数ブランチで平行して開発していると実際に「誰がカバレッジを上げたのか/下げたのか」がわかりません（他のブランチのカバレッジが基準になってしまうので）。

特定のBranchのPushだけJenkinsが反応するようにしても良いですが、それだと「そのPushでどれだけカバレッジが変化したか」が後にならないとわからないですし、やはり「誰がカバレッジを上げたのか/下げたのか」が明確にならないので楽しくないです。

今回の方法ですと「自分がPushしたソースがカバレッジにどのような影響を与えたか」がわかるので、下げまくっていると少し気まずい思いをすることができるようになりますｗ


さいごに
====

ちょっと導入手順は多いですが、ポイントは最後のスクリプトの部分だけです。
一度やりかたがわかると、Karma−Coverage以外にも適用できると思います。