mocha / chai チートシート

## 概要
- Mocha = jsのユニットテストツール
    - minitestなどに近いかたちでTDD/BDDが実現できる
    - Rails関連のmochaは、minitestのスタブ作成のためのツールなので別もの

- Chai = アサーションツール
    - assert()系のメソッドを提供する
    - mochaはchaiを含む復数種のアサーションツールを選択して使える


## 導入

bower/npm/CDNなどからインストール可能。

```bash:bower
$ bower install mocha   #--save
$ bower install chai    #--save
```

```bash:npm
$ npm install mocha
$ npm install chai
```

```html:CDN
<script src="https://cdnjs.cloudflare.com/ajax/libs/mocha/2.2.5/mocha.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chai/3.0.0/chai.min.js"></script>
```

## 構築
コマンドラインあるいはブラウザベースで起動できる。


### ブラウザからの利用

- テスト用の画面に、mocha.jsおよびchai.jsを読み込む。
(環境により任意)


- `div#mocha`を、結果表示用の領域として準備する。

```html
<div id="mocha"></div>
```


- mochaを実行するためのjsコードを設定する


```js
// 1. 起動する(BDDスタイル指定)
mocha.setup('bdd');

// 2. テストケースを記述する。あるいは一旦<script>を切って外部のテストファイルを読む
// ...

// 3. テストを実行
mocha.checkLeaks();
mocha.run();
```

- テストケースを実装し、画面をブラウザ表示することで、テストを実行できる。



## mocha::テストケースの書き方

テストケースはBDD, TDD, EXPORTS, QUNITなどの復数のスタイルを選択して記述できる。
(`mocha.setup()`で指定する)


### BDD

ビヘイビア(= 振る舞い = 「xxはxxなときxxする(はず)」)単位でテストを記述する。

```js:BDDの例
// describe()でテストを階層的に分類
describe('User', function(){

    describe('attributes', function(){

        // id()でテストケースを定義
        it('has attribute name', function(){

            // 実際のアサーション処理はchaiなどを使う
            // ...
        });

    });

    describe('ajax', function(){

        it('can save', function(done){

            // 非同期処理をテストしたい場合は、it()の引数にとったdone() を呼ぶことでテスト完了を知らせる
            User.save(function(){
                done();
            }));
        });
    );

});
```


## chai::アサーションの書き方

Assertion, BDDの2種類の書き方ができる。
いずれも検証に失敗すると例外が発生し、結果としてmochaがテストの失敗を結果表示する。


### Assertion

旧来のアサート形式によって検査する。


```js:アサーションの例

// user.attrが{}であることを確認する
chai.assert.isObject(user.attr);

// user.attr.idの値が-1であることを確認する
chai.assert.propertyVal(user.attr, 'id', -1);

```


アサーションのはかなり多い。
まただいたいのメソッドには、その検証項目の否定形がある。
(`equal()`に対する`notEqual()`など)


```js:アサーションメソッド抜粋
isOk()              // true
deepEqual()         // 同値
isAbove()           // >
isAtLeast()         // >=
isBelow()           // <
isAtMost()          // <=
isTrue()            // == true
isFalse()           // == false
isNull()            // == null
isNaN()             // isNan()
isUndefined()       // === undefined
isFunction()        // instanceof Function
isObject()          // instanceof Object
isArray()           // instanceof Array
isString()          // instanceof String
isNumber()          // instanceof Number
isBoolean()         // instanceof Boolean
typeOf()            // typeof
instanceOf()        // instancef
include()           // ex. 'foobar' includes 'foo'
lengthOf()          // .length
match()             // RE
```

一覧は[公式のリファレンス](http://chaijs.com/api/assert/)を参照のこと。


### Except/Should
メソッドチェーンにより、英文のような形でBDD的な振る舞いを記述できる方法。


```js:Except/Shouldの例
var foo = 'bar';

// expectで書く
expect(foo).to.be.a('string');

// shouldで書く
foo.should.be.a('string');
```



## 参考
- [MOCHA](http://mochajs.org/)
    - [コマンドラインで起動する方法](http://mochajs.org/#getting-started)
    - [ブラウザベースで確認する方法](http://mochajs.org/#running-mocha-in-the-browser)
- [Chai Assertion Library](http://chaijs.com/)
- [Qiita - ユニットテストって何?って人向けのmochaとchaiの使い方](http://qiita.com/y_hokkey/items/f73ea6b3d5f6902396b6)
- [chikathreesix - Mochaとchaiを使ってJavaScriptのフロントエンドテスト環境の構築](http://chikathreesix.com/?p=71)