mochaとchaiでJavaScriptをテスト

2013-03-05T00:00:00+00:00 JavaScript Node.js

http://visionmedia.github.com/mocha

http://chaijs.com

を使ってnode.jsでもbrowserでテストランナーなHTMLを読み込んでもテスト出来るテストフレームワークな感じ(正式的にはどういうスタンスなのか個人的に不明)。使ってみるとする

で上記の公式ドキュメント(正確にはgithubのwiki)にもあるように、mochaで使うアサーション的な所はnodejsとかだとassertがあるからいいけどブラウザとかでも実行できる方向で書いていくので、今回はchaiを使う。should.jsっていうのもあるけど、これブラウザ向けなやつが提供されてない模様(っていうそこら辺不明)

インストール

mochaとchaiを導入する

npm install -g mocha
npm install -g chai

辺りで良いんじゃないかなーっと。で

  • $NODE_PATH/mocha/mocha.js
  • $NODE_PATH/mocha/mocha.css
  • $NODE_PATH/chai/chai.js

をコピってくる。これはあくまでブラウザで実行する際に使うだけ

※追記部を参照

テストを書く

var timerCallback = function(cb) {
  setTimeout(
    function() {
      cb(100);
    },
    2500
  );
};

describe("describe1", function() {

  beforeEach(function() {
    console.log("beforeEach");
  });

  before(function() {
    console.log("before");
  });

  afterEach(function() {
    console.log("afterEach");
  });

  after(function() {
    console.log("after");
  });

  it("should 1+1 = 2", function() {
    expect(1 + 1).to.equal(2);
  });

  it("should 2*2 = 4", function(done) {
    setTimeout(
      function() {
        expect(2 * 2).to.equal(4);

        done();
      },
      1000
    );
  });

  it("timerCallbackを実行してみる", function(done) {
    this.timeout(3000); // 非同期テストの際のタイムアウト値を設定。設定しない場合にはデフォルトで2000msな模様

    timerCallback(function(x) {
      expect(x).to.equal(100);

      done();
    });
  });

  it("XMLHttpRequestしてみる", function(done) {
    var xhr = new XMLHttpRequest();
    xhr.open("GET", "http://localhost:5000/", true);
    xhr.onload = function() {
      expect(this.status).to.equal(200);

      done();
    };
    xhr.send(null);
  });

  it("後で");

  it("適当なオブジェクトのテスト", function() {
    var o = { "name": "hoge" };

    expect(o).to.be.a("object");
    expect(o).to.have.property("name");
    expect(o.name).to.have.length(4);
    expect(o.name).to.equal("hoge");
  });
});

特に何かをテストする訳じゃなくてあくまで使い方的な所なので(ry

まぁbeforeとbeforeEachとかの違いはRSpecなあれと同じなんじゃないかなと

実行

mochaのディレクトリ構造的にはtestっていうディレクトリにjsなテストおけば

mocha

ってだけでテストを実行出来る。でこれ実行するとコケると思います。mochaはいいけどchaiがロードされてませんのでexpectとかそういう辺りでコケる(あとnode.jsにはXMLHttpRequestは無い。node-XMLHttpRequestを使うので)

でそういう場合は

// require("should");

var chai = require("chai");
chai.should();

global.expect = chai.expect;
global.XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;

な感じでtest_helper.jsを作っておいて

mocha --require test_helper.js

的な感じで実行する。でオプションとか設定するのめんどいっすよねっていう事でtestディレクトリ内にmocha.optsを作ってオプション定義を指定する事が出来るので

--reporter spec
--require test_helper.js

な感じで指定すれば、あとはmochaコマンドを実行するだけでオプションが認識してくれる模様。オプション的なのは

  • --reporter(-R)でレポート方式を指定出来る。--reportersで一覧が見れる
  • --watch(-w)でカレントディレクトリなファイルを監視してテストを自動実行してくれる模様
  • --timeoutでtimeout値を設定出来る。これはテスト側でも設定可能
  • --growlでgrowl(もしくはnotify-send?)で通知をしてくれる模様

的なのがある模様。でまぁここまで来れば普通にmochaコマンドでテストしても問題なく実行出来るはずと

ブラウザでテストを実行する場合

上記でmocha.js/mocha.css/chai.jsをコピーしたと思うので

<html>
  <head>
    <meta charset="utf-8" />
    <link rel="stylesheet" type="text/css" href="mocha.css" />
    <script type="text/javascript" src="mocha.js"></script>
    <script type="text/javascript" src="chai.js"></script>
    <script type="text/javascript">
      chai.should();

      var expect = chai.expect;
      mocha.setup("bdd");
    </script>
  </head>
  <body style="background: #aaa">
    <script type="text/javascript" src="test/test1.js"></script>
    <div id="mocha"></div>
    <script type="text/javascript">
(function() {
  mocha.run();
})();
    </script>
  </body>
</html>

な感じで書いてブラウザで見ると

んまぁそんな感じでnode.jsでテストしてもブラウザでテストしても出来なくもない模様で。結構良い感じなのではとは個人的には思います

追記

mocha init .

みたいな事をすると指定したディレクトリ内にmocha.cssとmocha.js及びそれを実行するランナーなhtmlが出力される模様

superagentでリダイレクトをフォローしない mocha-phantomjs