JSフロントエンド開発E2Eテスト 〜 CasperJSとZombie.jsを試してみた


最近はヘッドレスブラウザで気軽にE2Eテストをできる時代になったと聞くのでちょっと試してみた。

## CasperJSの場合

```bash
# CasperJS本体のインストール
npm install -g casperjs
```

テストファイルの作成
`vi spec/e2e/testing.casper.js`

```javascript
casper.test.begin('google search simple test', 4, function (test) {
  casper.start("https://www.google.co.jp/", function () {
    test.assertExists("title"); // titleタグがある
    test.assertTitle("Google", "title is Google"); // titleタグ内容はGoogleである
    test.assertEval(function () {
      // <meta name="description">のcontent属性は空ではない
      return __utils__.findOne("meta[name='description']").getAttribute("content") != "";
    });

    // フォームを埋めてsubmit実行
    // fill(String selector, Object values[, Boolean submit])
    this.fill('form[action="/search"]', { q: "casperjs"}, true);
  })

  casper.then(function () {
    //画面遷移後 titleタグにcasperjsの文字列が含まれる
    test.assertTitleMatch(/casperjs/, "title contains casperjs");
  });
  
  casper.run(function () {
    test.done(); 
  });
});
```

```bash
#実行
$ casperjs test spec/e2e/testing.casper.js

Test file: testing.casper.js                                                    
# google search simple test
PASS Find an element matching: title
PASS title is Google
PASS Evaluated function returns true
PASS title contains casperjs
```

##### 感想

- CasperJSさえインストールすれば、実行までフォローしている。
- Dom取得に__utils__.findOne() とかちょっと気持ち悪いし、evaluateの内側じゃないとつかえないので冗長な感じがする。
- なにかと独自仕様臭がするので、慣れるのに時間かかりそう。



## Zombie.jsの場合
```bash
# zombie.jsをインストール 
npm install -g zombie
# mochaをインストール
npm install -g mocha
```

テストファイルの作成
`vi spec/e2e/testing.zombie.js`

```javascript
var Zombie = require("zombie");
var assert = require("assert"); //node.jsの標準モジュール

//google検索だと上手く動かなかったのでnhkサイト内検索で試した
describe("nhk search simple test", function () {
  var promise;
  var browser;
  this.timeout(10000); //mochaのデフォルトタイムアウト値(2000)だと足りない

  before( function (done) {
    browser = new Zombie({debug: false});//debug:trueで通信など見れる。便利。
    promise = browser.visit("http://www.nhk.or.jp/");
    promise.then(done, done);
  });

  it('before search', function (done) {
    promise.then(function () {
      assert.ok(browser.success);
      assert.ok(browser.query("title")); // titleタグがある
      assert.ok(browser.query("meta[name='description']") != ""); 
      assert.equal(browser.text("title"), "NHKオンライン"); //titleタグ内容はNHKオンラインである
    })
    .then(function () {
      browser.fill("qt", "あまちゃん");
    })
    .then(function () {
      // 検索実行
      return browser.pressButton("#seek input[type='submit']");
    })
    .then(done, done);
  });

  it('after search', function (done) {
    promise.then(function () {
      //jQueryを使ってDOM取得も簡単
      $ = browser.window.$;
      assert.equal($("h2>span>strong").text(), "あまちゃん");
    })
    .then(done, done);
  });

});
```
```bash
# 実行
$ mocha spec/e2e/testing.zombie.js -R spec


  nhk search simple test
    ✓ before search (3625ms)
    ✓ after search 


  2 passing (8s)
```


##### 感想
- mochaを使ったことがなかったので学習コストが＋αだった。
- promiseが使いやすい。
- デフォルトのDOM取得もわかりやすいし、jQueyやUnderscoreなども導入しやすい。
- 基本的にどこかで見た書き方で直感的。慣れやすい。

本当に簡単なDOM操作と取得しか試してないので、底力的なものはまだなんとも言えないけれど、
肌に合うのはzombie.jsかなと思った。
これまでUnitTestをjasmineで書いていたのでMochaの良さがなんとなくわかったのも収穫だった。
Zombie.jsもっと試してみようと思います。