mocha.parallel という Mocha のテストを並列実行できる npm モジュールがあったので試してみました。
インストール
$ npm install -g mocha
$ npm install -D mocha.parallel
並列じゃない例
まずは並列じゃない例を。
// test/a-test.js
const assert = require('assert');
describe('a', () => {
before(() => { console.log('before'); });
beforeEach(() => { console.log('before each'); });
afterEach(() => { console.log('after each'); });
after(() => { console.log('after'); });
it('0', () => {
assert.strictEqual(0, 0);
});
it('1', (done) => {
setTimeout(() => {
assert.strictEqual(1, 1);
done();
}, 1000);
});
it('2', (done) => {
setTimeout(() => {
assert.strictEqual(2, 2);
done();
}, 2000);
});
it('3', (done) => {
setTimeout(() => {
assert.strictEqual(3, 3);
done();
}, 3000);
});
});
これを実行すると前のテストの実行が終ってから次が実行されているのがわかります。
$ mocha test --timeout=5000
a
before
before each
✓ 0
after each
before each
✓ 1 (1006ms)
after each
before each
✓ 2 (2003ms)
after each
before each
✓ 3 (3001ms)
after each
after
4 passing (6s)
並列にする
mocha.parallel
を使って並列化してみます。
// test/a-test.js
const assert = require('assert');
const parallel = require('mocha.parallel');
parallel('a', () => {
before(() => { console.log('before'); });
beforeEach(() => { console.log('before each'); });
afterEach(() => { console.log('after each'); });
after(() => { console.log('after'); });
it('0', () => {
assert.strictEqual(0, 0);
});
it('1', (done) => {
setTimeout(() => {
assert.strictEqual(1, 1);
done();
}, 1000);
});
it('2', (done) => {
setTimeout(() => {
assert.strictEqual(2, 2);
done();
}, 2000);
});
it('3', (done) => {
setTimeout(() => {
assert.strictEqual(3, 3);
done();
}, 3000);
});
});
describe
のかわりに parallel
を使っています。
これを実行してみます。
$ mocha test --timeout=5000
a
before
before each
before each
before each
before each
after each
✓ 0
after each
✓ 1 (1003ms)
after each
✓ 2 (1000ms)
after each
✓ 3 (997ms)
after
4 passing (3s)
beforeEach
がはじめにまとめて実行されています。テストがすべて並列で実行されているのがわかります。
テストにかかった時間は前のテストが終ってから計測されるみたいです。上の例の 2
と 3
の順番を入れ替えると表示される時間もかわります。
// 略
it('3', (done) => {
setTimeout(() => {
assert.strictEqual(3, 3);
done();
}, 3000);
});
it('2', (done) => {
setTimeout(() => {
assert.strictEqual(2, 2);
done();
}, 2000);
});
// 略
$ mocha test --timeout=5000
a
before
before each
before each
before each
before each
after each
✓ 0
after each
✓ 1 (1002ms)
after each
after each
✓ 3 (1995ms)
✓ 2
after
4 passing (3s)
2
のテストが一瞬で終わっています。
まとめ
少し書き換えるだけで簡単に導入できるのはいいと感じました。
テストに時間がかかると辛いので、こういうツールは積極敵に使っていきたいです。
ただし、DBやファイル書き込みなどの副作用がある場合は単純には並列化できないので気をつけないといけません。副作用をうまく切り出しておくとよさそうです。