【初心者向け】フロントエンド開発環境へのテストの導入

この記事は[Gizumoエンジニア Advent Calendar 2015](http://www.adventar.org/calendars/919)の18日目の記事です

僕は**[株式会社Gizumo](http://www.gizumo-inc.jp)**という、設立してまだ半年ほどの会社でエンジニアをやっています。

エンジニアの経歴としてはどちらかというとゴリゴリの開発より第三者検証のテストを行っていることが多く、フロントエンド開発の経験自体は浅いですが、つい先日参加したとある勉強会で後述するESLintに関しての話題があったことがきっかけで、簡単にまとめておこうと思い書いてみます。


## はじめに
上記で軽く書いた**第三者検証のテスト**が何かというと、プロダクトが仕様通りに動くかどうかを実際に動作確認をしてプロダクトの品質を保証するもので、いわゆるブラックボックステストと言われるものに近しい感じです。
一方でこのエントリーで書くものは、実装されたコードに基づいて、「正しく書かれているか」とか「正しく動くか」などを網羅的に確認していく**ホワイトボックステスト**です。
そしてこの中でも「正しく書かれているか」というところにフォーカスを当てて書いていこうと思います。


## 今回使うもの
* [ESLint](http://eslint.org/)
  - コードの実行前にJavaScriptの文法はもちろん、綴りミスを見つけてくれたり、括弧や半角スペースとか悪い使い方を指摘してくれる便利なもの。


## 環境
今回は以下の環境で記事を書いていきます。

* OS / MacOS 10.11.2
* Node.js / v5.3.0

## 導入

ESLintをインストールするために**npm**というNode.jsのパッケージ管理ツールを使用するので、Node.jsをインストールしましょう。
Node.jsのインストールに関しては記事がたくさんあるので、今回は割愛します。
インストールができたら念のためバージョンを確認しておきましょう。

```:console
$ node -v // nodeのバージョンを確認する
v5.3.0
```

### ESLintの導入
---

インストールはコマンドを打ちましょう

```:console
$ npm install -g eslint

$ eslint -v // インストールが完了したらバージョンを確認してみましょう
v1.10.3
```

## 実際に使ってみよう

### 初期設定

適当なディレクトリを作成し、（今回はjs-testというディレクトリを作成しました)
そこで以下のコマンドを打ってください。

```:console
$ eslint --init
```

そうすると以下のようにいくつか質問が出てくるので答えていきましょう

![hoge.png](https://qiita-image-store.s3.amazonaws.com/0/81504/685e3e26-523b-2f8e-e546-a8573d492351.png)

実際は自分の好きなようにしてもらえば良いのですが、今回は以下の形で進めていきます。
(↑と↓のキーで選択、Enterキーで次の質問に進みます)

```:console
? How would you like to configure ESLint?
> Use a popular style guide

? Which style guide do you want to follow?
> Google

? What format do you want your config file to be in?
> JavaScript
```

そうしたら`.eslintrc.js`というファイルが生成されますが、
今は放っておいて大丈夫です。


#### JavaScriptファイルを作成する

次は実際にESLintを動かすJavaScriptのファイルを作りましょう。

```javascript:test.js
var name = 'Yamada',
    age = 25;
function aging (age) { // comment
    age++;
    console.log(age + "歳になりました");
}
function hello (name) {
    console.log("HELLO " + name)
}
hello(name);
aging(age);
```

例えばこういうコードがあるとします。
一見問題ないように見えますが、ESLintにコードレビューをしてもらいましょう。


### ESLintを動かす

使い方は簡単で、以下のように`eslint`のあとにファイル名を指定するだけです。

```:console
$ eslint test.js
  
   1:1   error    Split 'var' declarations into multiple statements       one-var
   2:5   error    Expected indentation of 2 space characters but found 4  indent
   3:1   warning  Missing JSDoc comment                                   require-jsdoc
   3:15  error    Unexpected space before function parentheses            space-before-function-paren
   3:24  error    Unexpected comment inline with code                     no-inline-comments
   4:5   error    Expected indentation of 2 space characters but found 4  indent
   5:5   error    Expected indentation of 2 space characters but found 4  indent
   5:23  error    Strings must use singlequote                            quotes
   7:1   warning  Missing JSDoc comment                                   require-jsdoc
   7:15  error    Unexpected space before function parentheses            space-before-function-paren
   8:5   error    Expected indentation of 2 space characters but found 4  indent
   8:17  error    Strings must use singlequote                            quotes
   8:33  error    Missing semicolon                                       semi
  11:2   error    Newline required at end of file but not found           eol-last

✖ 14 problems (12 errors, 2 warnings)
```

そうするとこのようにダメだったところを教えてくれます。
思った以上に多いですね。
このメッセージは以下のようになっています。

| 行番号:列番号 | 種類 | 内容 | ルール |
|:----------:|:----------:|:---------------:|:-------------:|
| 1:1 | error | Split 'var' declarations into multiple statements | one-var |

ルールというのは[こちら](http://eslint.org/docs/rules/)に記載のもので、どういった基準でエラーや警告を出すかといったものが明確に決められているものです。

早速上記のエラーと警告を解消してみましょう。

```javascript:test.js
var name = 'Yamada';
var age = 25;
var aging = function(age) {
  age++;
  console.log(age + '歳になりました');
};
var hello = function(name) {
  console.log('HELLO ' + name);
};
hello(name);
aging(age);
  
// 最終行に空白行を入れる
```

これで再度

```:console
$ eslint test.js
```
コマンドを実行するとエラーが出なくなったかと思います。
このようにESLintを使用して、コードの精度を高めていきます。


### ESLintの設定を変更する

ESLintの設定は`.eslintrc.js`というファイルで全て管理できます。
今回の場合、Googleのスタイルガイドを使用しているため、デフォルトでは以下のようになっています。

```javascript:.eslintrc.js
module.exports = {
    "extends": "google"
};
```

この中に`"rules"`というオブジェクトを作成し、以下のようにを入れてみましょう。

```javascript:.eslintrc.js
module.exports = {
    "extends": "google",
    "rules": {
        "indent": [ 2, 4 ],
        "semi": [ 0 ]
    }
};
```

これで再度

```javascript:test.js
var name = 'Yamada',
    age = 25;
function aging (age) { // comment
    age++;
    console.log(age + "歳になりました");
}
function hello (name) {
    console.log("HELLO " + name)
}
hello(name);
aging(age);
```

このコードに対してESLintをかけてみましょう。
以下のように最初に比べエラーが減ったかと思います。

```:console
  1:1   error    Split 'var' declarations into multiple statements  one-var
  3:1   warning  Missing JSDoc comment                              require-jsdoc
  3:15  error    Unexpected space before function parentheses       space-before-function-paren
  3:24  error    Unexpected comment inline with code                no-inline-comments
  5:23  error    Strings must use singlequote                       quotes
  7:1   warning  Missing JSDoc comment                              require-jsdoc
  7:15  error    Unexpected space before function parentheses       space-before-function-paren
  8:17  error    Strings must use singlequote                       quotes

✖ 8 problems (6 errors, 2 warnings)
```

これは何をしていたのかというと、今回は`.eslintrc.js`というファイルで`indent`と`semi`ルールに対して、エラーを出す基準を変えていました。

```javascript
"indent": [ 2, 4 ]
"semi": [ 0 ]
```

この部分です。
各ルールに対して、数字が設定できます。開始の`[`の直後の数字がそうです。

設定できる数字とその意味は以下の形です。

| 設定する数字 | 意味 |
|:----------:|:----------:|
| 0 | ルールを無視してエラーや警告を出さない |
| 1 | 警告を出す(warning) |
| 2 | エラーを出す(error) |

つまり今回のものは、
「indentに対してはルールを変更して、(デフォルトで2設定を) 4にする。semiに対してはエラーや警告を出さないようにする」という意味です。

このように`.eslintrc.js`にオリジナルのルールを設定することで、
個人やチーム内で統一されたコードにしていくことができます。

**[設定できるルール関して詳しくはこちら](http://eslint.org/docs/rules/)**


## 最後に
フロントエンドでのテストとして、Mocha(もしくはJasmine)とKarmaも入れたかったとこですが、
今度自分の中で整理ができたときに書こうと思います。
今後の自分のためにもESLintで負の遺産をなくして、快適なコーディングライフを送りましょう。



### 参考
* [ESLintについてのメモ](http://qiita.com/makotot/items/822f592ff8470408be18)
* [ESLint 1.0.0新ルールまとめ](http://qiita.com/armorik83/items/228b97bee25aa33c9850)
* [公式ルール](http://eslint.org/docs/rules/)