CircleCIとJest、CoverallsでJavaScriptアプリケーションのテストカバレッジを可視化する

こんにちは。突然ですが、テスト書いてますか。カバレッジは計測していますか？

今回はテストカバレッジの履歴の記録・閲覧ができる[Coveralls](https://coveralls.io/)というサービスを試したので、内容を共有したいと思います。

## 完成イメージ
本記事の説明どおりに設定を行うと、下記のようにCoveralls側でテストカバレッジを確認することが可能です。また、README.mdに貼るバッジも取得できます。

<img width="1278" alt="Screen_Shot_2018-09-08_at_17_17_06.png" src="https://qiita-image-store.s3.amazonaws.com/0/38478/d26633cc-3d10-bb79-a359-b01e9730bee8.png">

さらに、ビルドやファイルごとのカバレッジの閲覧も可能となっています。

<img width="1276" alt="Screen Shot 2018-09-08 at 17.27.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/38478/0c833f3a-8fce-eb2f-92d9-c49fa16f31a1.png">

## 前提条件
すでにテストが書かれていて、カバレッジ計測ツールでカバレッジが取得できる環境がすでにあることを前提に話を進めていきます。

* カバレッジ計測ツールの[nyc](https://github.com/istanbuljs/nyc)やテストフレームワークの[Jest](https://github.com/facebook/jest)などでカバレッジが計測できていること
* CircleCIの設定がすでに完了していること

今回はテストフレームワークのJestを使いますが、テストカバレッジの測定結果をlcov形式で出力できるツールであれば、他の環境でも応用が可能です。

## 設定

### CoverallsとGitHubリポジトリの連携を行う
[Coveralls](https://coveralls.io/)のページに移動し、「GET STARTED FOR FREE」をクリックします。

<img width="1277" alt="Screen Shot 2018-09-08 at 18.21.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/38478/456e732d-ed5c-05e2-1ba7-0a6378694216.png">

GitHubでアカウント登録を行います。

<img width="1277" alt="Screen Shot 2018-09-08 at 18.23.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/38478/b7a17b36-d863-2cc0-1938-e029a44bc45f.png">

[ADD REPOS](https://coveralls.io/repos/new)のページに移動し、連携させたいリポジトリを選択して、スイッチをオンにします。

スイッチをオンにすると、「DETAILS」ボタンが現れるので、クリックします。

<img width="1278" alt="Screen_Shot_2018-09-08_at_18_26_58.png" src="https://qiita-image-store.s3.amazonaws.com/0/38478/79c09905-5a69-f09f-fe11-4c1fdca8f22e.png">


Coverallsにカバレッジを記録する際に使用するトークンが`repo_token`に表示されるので、メモしておきます。

<img width="1275" alt="Screen_Shot_2018-09-08_at_18_28_25.png" src="https://qiita-image-store.s3.amazonaws.com/0/38478/fad5f9e7-ce72-7f6d-de0c-d490d1da0750.png">

### CircleCIに環境変数を設定する
CircleCIの設定ページに移動し、環境変数を設定します。すでにCircleCIとGitHubリポジトリの連携が完了している場合は下記URLでアクセスが可能です

`https://circleci.com/gh/<GitHubユーザー名>/<リポジトリ名>/edit#env-vars`

トークン値とビルドに使用するCIサービス名を環境変数に登録します。

* `COVERALLS_REPO_TOKEN` さきほどメモしたトークン値
* `COVERALLS_SERVICE_NAME` ビルドに使用しているCIサービス名 (今回は`circle-ci`)

<img width="1278" alt="Screen_Shot_2018-09-08_at_18_40_31.png" src="https://qiita-image-store.s3.amazonaws.com/0/38478/c7896a04-b003-8e82-7f94-b4579fc310b5.png">

### CoverallsパッケージのインストールとCircleCI設定ファイルを変更する
カバレッジをCoverallsに記録するために必要なパッケージをnpmからインストールします。

`package.json`が存在するディレクトリに移動してから、下記コマンドを実行してください。

```
$ npm install --save-dev coveralls
```

テストコマンドはlcovファイルが出力されるように変更します。Jestではコマンド実行時に`--coverage`オプションを与えることで、カバレッジがファイル出力されます。

```bash:テストコマンド
$ jest --coverage
```

実際にカバレッジをCoverallsに記録するときは下記のコマンドを実行します。`package.json`のnpm-scriptsに記載しても問題ないです。

行われている処理としては、カバレッジが記録されているファイルの内容を標準出力し、パイプラインで`coveralls`コマンドに渡して、Coveralls側に送信されています。

```bash:カバレッジをCoverallsに送信するコマンド
# <lcovファイルまでのパス> | <coverallsコマンドの実行パス>
$ cat ./coverage/lcov.info | ./node_modules/.bin/coveralls
```

CircleCIの設定ファイルにコマンドを追加する場合は以下のように行います。

```yaml:.circleci/config.yml
version: 2
jobs:
  build:
    working_directory: ~/workspace
    docker:
      - image: circleci/node:8.11.4
    steps:
      - checkout
      - restore_cache:
          key: dependency-cache-{{ checksum "package.json" }}
      - run:
          name: install packages
          command: npm install
      - save_cache:
          key: dependency-cache-{{ checksum "package.json" }}
          paths:
            - node_modules
      # テストコマンドではlcovファイルを出力するようにする
      - run:
          name: run test
          command: npm test
      # カバレッジをCoverallsに記録
      - run:
          name: post coverage
          command: cat ./coverage/lcov.info | ./node_modules/.bin/coveralls
      - run:
          name: run lint
          command: npm run lint
```

CircleCIの設定ファイルの準備が整ったら、リモートリポジトリにPushします。CircleCIがビルドを行い、カバレッジをCoverallsに送信します。

処理が成功すると、Coverallsを設定したリポジトリのページでカバレッジが確認できます。

<img width="1278" alt="Screen_Shot_2018-09-08_at_18_49_03.png" src="https://qiita-image-store.s3.amazonaws.com/0/38478/c41a2c2f-928e-80e8-158a-9b9f83ee12d2.png">

## 応用

### README.mdに貼るバッジを取得する
Coverallsを設定したリポジトリのページに移動し、BADGEという項目の右上のEMBEDボタンをクリックすると、バッジを貼るためのコードをコピーできます。

事前に、BRANCHの設定がカバレッジを表示したいブランチであるかを確認しておきましょう。

<img width="1279" alt="Screen_Shot_2018-09-08_at_18_55_37.png" src="https://qiita-image-store.s3.amazonaws.com/0/38478/f302c993-2dc1-2511-f390-2c5619d707fb.png">

### Pull Requestにカバレッジ計測結果をコメントする
Coverallsを設定したリポジトリページの左上のSettingsをクリックし、設定画面に移動します。

<img width="1278" alt="Screen_Shot_2018-09-08_at_18_49_03_08.png" src="https://qiita-image-store.s3.amazonaws.com/0/38478/cf51c0a5-e3f8-f128-a08e-a2995dcbbd81.png">

LEAVE COMMENTSを有効にします。FORMATを変更することで、コメントするときの書式が変わります。

<img width="1277" alt="Screen_Shot_2018-09-08_at_19_07_51.png" src="https://qiita-image-store.s3.amazonaws.com/0/38478/0308c79a-131e-17e6-51a8-6c2359344e90.png">

実際に以下のようにPull Requestにコメントが追加されます。

<img width="779" alt="Screen Shot 2018-09-08 at 19.09.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/38478/ba1d9884-d492-a0e1-67d6-58090a6f7d1c.png">

### Pull Request作成時に設定されたカバレッジのしきい値を確認して、CIをFailedにする
こちらはまだ試せていないのですが、設定されたカバレッジのしきい値を見て、CIをFailedにする機能があります。

機能追加時や修正時にテストが足りていないときに教えてくれます。さきほどのリポジトリの設定画面より、設定が可能です。

<img width="1279" alt="Screen_Shot_2018-09-08_at_19_15_57.png" src="https://qiita-image-store.s3.amazonaws.com/0/38478/c1583e07-2111-0ca5-7aec-e6bb84097f9f.png">