IntelliJ IDEAでフロントエンドJavaScriptテスト環境を構築する

調べてみても情報が古かったりして細かいところでハマったので備忘録です。
「デバッグしながらテストを実行したい」、「テストを変更したときにリロードしたい」というごく単純な要求だったのですが、私の構成ではなかなかうまくいかず苦労しました。。
なお、mochaとかkarmaの使用方法の詳細については省略しています。

## 構成

* 開発環境
    * IntelliJ IDEA 15
    * Node.js、npmはインストール済み
    * Macを使用
* ソースコード
    * テスト対象は**power-assert + karma + mocha + browserify**で書いたフロントエンドjsモジュール
    * テストコードはDOMのテストを含む
* CI環境
    * ついでにGitHubにpushするとTravis CIでテストが実行されるようにしました

成果物はこちらです。https://github.com/kenji0x02/donut-indent
本題とは関係ないですが、モジュールの使い方などはこちらに書いてありますので、もしよければ参照ください。http://qiita.com/kenji0x02/items/8381050ddac3499d4eb7

ちなみに今回構築したテスト環境の`package.json`から`devDependencies`のみ抜粋するとこんな感じです。

```package.json
{
  "devDependencies": {
    "browserify": "^12.0.1",
    "espowerify": "^0.10.1",
    "gulp": "^3.9.0",
    "gulp-eslint": "^1.1.1",
    "gulp-header": "^1.7.1",
    "gulp-load-plugins": "^1.1.0",
    "gulp-sourcemaps": "^1.6.0",
    "gulp-uglify": "^1.5.1",
    "karma": "^0.13.19",
    "karma-browserifast": "^0.7.0",
    "karma-browserify": "^4.4.2",
    "karma-chrome-launcher": "^0.2.2",
    "karma-mocha": "^0.2.1",
    "karma-mocha-reporter": "^1.1.5",
    "mocha": "^2.3.4",
    "power-assert": "^1.2.0",
    "vinyl-buffer": "^1.0.0",
    "vinyl-source-stream": "^1.1.0"
  }
}
```

## まずは、プラグインのインストール

今まではScalaでしか使っていなかったので、JavaScript用のプラグインが何も入っていませんでした。
なのでまずは、Preferences-Pluginsから**NodeJS**というプラグインを検索してインストール。

インストール完了後、IDEAを再起動してPreferencesウィンドウを開くと、Languages & Frameworksに**Node.js and NPM**が追加されています。Node.js and NPMを選択すると、ウィンドウ右側に**Node interpreter**という項目があるので、入力されていない場合、または、変更したい場合はnode.jsの実行ファイルを指定。すると下のPackagesにパッケージ一覧が表示されます。
![スクリーンショット 2016-01-20 23.34.42.png](https://qiita-image-store.s3.amazonaws.com/0/36728/4a1eaee7-1ac9-818e-8ce8-3aa5262e3cf6.png)

(注意) ここでインストールした**NodeJS**はIntelliJ用のプラグインなので、本体とは別に入れないといけない。

## テストの実行

テストを実行する方法は何通りかあるかと思うのですが、いろいろ試した結果、package.jsonにscriptsを定義しておいて、npmで実行する方法を採用しました。まず、こんな感じでテスト用のscriptsを定義します。

```package.json
{
  "scripts": {
    "test": "./node_modules/karma/bin/karma start"
  }
}
```
IDEAから`npm test`を実行するために、**Edit Configurations**で+をクリックして、以下のようなnpmタスクを作ります。

* package.json: package.jsonのパス
* Command: run-scriptを選択
* Scripts: package.jsonで定義したテストコマンド(上の例だとtest)

次に、このタスクをRunします。すると、Karmaで指定したブラウザが起動して、テストの実行結果がRunタブに表示されます。めでたしめでたし。なのですが、npmタスクだとDebug実行ができません。そこで、もう一つデバッグ用のプロセスを起動します。

## デバッグプロセスの実行

まず、**Edit Configurations**で+をクリックして、**JavaScript Debug**を選択。URLにKarmaのデフォルトのデバッグURL(<http://localhost:9876/debug.html>)を入力。BrowserはKarmaのconfigで設定したChromeで。

次に、npmタスクを起動した状態で、上で作成したJavaScript Debugタスクをデバッグ実行します。ここで一つ注意が。デバッグ実行する前に必ず普段使っているChromeを起動しておいてください。あ、違う違うもっと前だ。npmタスクを実行する前に起動しておいてください！普段Safariな人も起動しておいてください！！じゃないと、毎回テスト用のブラウザが起動してしまい、この後インストールする機能拡張を毎回入れないといけなくなります。

![スクリーンショット 2016-01-21 1.09.56.png](https://qiita-image-store.s3.amazonaws.com/0/36728/f7481cec-a07d-bc9d-be09-0cd6d07a1f8e.png)

さてさて、Chromeが起動した状態でデバッグ実行すると、IDEAのDebugタブのDebuggerタグに、"Waiting for connection from JetBrains IDE Support extension for Chrome"と表示されます。

![スクリーンショット 2016-01-21 1.31.25.png](https://qiita-image-store.s3.amazonaws.com/0/36728/288deec9-702e-dd8c-cf04-cfe60329aac2.png)

青いリンクをクリックするとChromeの機能拡張(JetBrains IDE Support)に移動しますので、インストールしてください。すると"「JetBrains IDE Support」がこのブラウザをデバッグしています。"という表示が出てデバッグ開始するので、IDEAにブレークポイントをはってデバッグの開始です。

(注意) npmタスクで起動したChrome上で「DEBUG」というボタンがあります。これをクリックしてもdebug.htmlが起動しますが、IDEAのタスクから開きましょう。

## 変更検知

上の構成でテストを実行すると、`karma.conf.js`で`autoWatch: true`にしておけば、ファイルの変更を検知して自動でテストが実行されます。IDEAのRunタブには**Scroll to the end**というボタンがあるので、これをチェックしておけば常に最新の結果を見ることができます。これでようやくめでたしめでたし。

最終的な形としては、IDEAで編集して、テスト結果はIDEAのRunタブでみて、DOMが気になるときだけChromeの検証画面を使うという感じで使っています。

## 試行錯誤履歴

* `Karma`というIDEAのプラグインを入れるとEdit ConfigurationsからKarmaのテストを実行することができますが、これだとDebugできなくて、かつ、browserifyを使っている時に変更検知してくれないので使うのをやめました。
* `karma-mocha-debug`というプラグインを使うと、ブラウザにテスト結果をいい感じに表示してくれます。わかりやすいので最初は使っていましたが途中からやめました。理由は、①`karma-mocha-reporter`を使えば同じ内容をターミナルに出力してくれるし、②bodyを書き換えるようなテストが一つでもあるとレポート結果が消えちゃうので。
* DOMを確認しながらテストを書きたいときは、IDEAのデバッグじゃなくて、Chromeのデバッグ機能を使用します。というか、Chromeの検証画面に移行した時点で、IDEAからデバッグできなります。


## 最後に

今まで、JavaScriptやhtmlはVimで書いていたんですけども、Scala用にIDEAにお布施を納めたので折角なので使ってみようかなと思い、今回環境を構築してみました。確かに使いやすいのですが、重かったり、IdeaVIMの動きが微妙だったり(これはjsとか関係ないですが)、使い続けるか悩ましいところですな。。