みなさん JavaScript, Node.js でのテストには何を使っているでしょうか。たぶん Mocha & Chai, Jasmine, Jest あたりが有名かなと思います。
私は Jest を使ったことがないので省きますが、Jasmine って単体で使えるんですよね。
じゃあ Mocha と Chai は何で割といつもセットでいるんだ…? こいつら何が違うんだ…? と疑問に思ったのでこの記事では Mocha & Chai コンビについて調べていきます。
Mocha とは
Mocha - the fun, simple, flexible JavaScript test framework
Mocha は JavaScript の テストフレームワーク です。
ブラウザと Node.js で動作します。非同期のコードをテストすることも可能です。
describe
や it
、beforeEach
や after
などの関数を使うことができ、テストを実行するメインの機能を持っています。
テストコードは以下のように構成されます。
describe("大問", () => {
describe("小問", () => {
it("ここで行われるテストの説明", () => {
// テストコード
});
it("ここで行われるテストの説明", () => {
// テストコード
});
});
describe("小問", () => {
// ...
});
// ...
});
describe("大問", () => {
// ...
});
Chai とは
Chai は JavaScript の アサーションライブラリ です。
アサーションとは、表明、断言、主張などの意味を持つ英単語。プログラミングにおいて、あるコードが実行される時に満たされるべき条件を記述して実行時にチェックする仕組みをアサーションという。
アサーション(アサート / アサーションチェック)とは - 意味をわかりやすく - IT用語辞典 e-Words
Chai を Mocha を始めとしたテストフレームワークと組み合わせることで chai.should
, chai.expect
, chai.assert
のようなアサートを使えるようになります。
ブラウザと Node.js で動作します。
なぜ一緒に使うの?
テストの大枠である Mocha がなければ Chai は動作しません。
Chai があることで Mocha でアサーションを使うことができます。
文章だけではイメージが湧かないのでコードを見てみましょう。
Mocha 公式ドキュメント を参考にしました。
テスト対象のコードはこちらです。
function User (username) {
this.username = username;
}
User.prototype.save = (cb) => cb();
module.exports = User;
まずは Mocha だけのテストです。
const User = require("../script");
describe("User", () => {
before(() => {
console.log("before");
})
after(() => {
console.log("after");
})
beforeEach(() => {
console.log("beforeEach");
})
afterEach(() => {
console.log("afterEach");
})
describe("#save()", () => {
it('should save without error', function (done) {
var user = new User('Luna');
user.save(done);
});
});
});
Mocha のテストでは it 関数で必ず done
を呼び出す必要があります。テストは自動で終了しないので done
が呼び出されない場合は一定時間後にタイムアウトして失敗します。
この Mocha のテストは問題なく動作します。
しかし「期待値はこれで結果はこれで、比較して結果はこうです」という形になっていないんですよね。その部分、つまりアサーションを担ってくれるのが Chai です。
Chai のテストを見てみましょう。
const User = require("../script");
const { expect } = require("chai")
describe("User", () => {
describe("#save()", () => {
before(() => {
console.log("before");
})
after(() => {
console.log("after");
})
beforeEach(() => {
console.log("beforeEach");
})
afterEach(() => {
console.log("afterEach");
})
it('should save without error', function (done) {
var user = new User('Luna');
user.save(done);
});
it("should set username", () => {
const user = new User("Luna");
expect(user.username).to.equal("Luna")
});
});
});
1つ目の it 関数は Mocha, 2つ目の it 関数は Chai のものです。
Chai のテストは expect(user.username).to.equal("Luna")
= expect(実行結果).to.equal(期待値)
となっていますね。これがアサーションです。
Mocha 単体のテストよりも TDD(テスト書いて期待値設定 → 実際にコード書く → テスト実行して期待値と実行結果比べる) 的なテストを行うことができます。
まとめ
- Mocha はテストフレームワークであり、テストの大枠を作ってくれる
- Chai はテストフレームワークの中でないと動けない
- Chai はアサーションライブラリであり、「期待値はこれで結果はこれで、比較して結果はこうです」という形でテスト結果を教えてくれるため TDD 的なテストができる