Ateam Brides Inc. Advent Calendar 2021の9日目は
株式会社エイチームブライズの@oekazumaが担当します。
はじめに
今回試すJavaScriptのテストフレームワークはJest、AVA、Mocha、tape、Jasmine、uvuです。
今回使用したコードはこちら
https://github.com/oekazuma/test-runner-compare
テストするコードは簡単な計算をするプログラムを用意しました。
exports.sum = (a, b) => a + b;
exports.div = (a, b) => a / b;
exports.mod = (a, b) => a % b;
Jest
インストール
$ npm install --save-dev jest
テストコード
const math = require('../math');
describe('sum', () => {
it('should be a function', () => {
expect(typeof math.sum).toBe('function');
});
it('should compute values correctly', () => {
expect(math.sum(1, 2)).toBe(3);
expect(math.sum(-1, -2)).toBe(-3);
expect(math.sum(-1, 1)).toBe(0);
});
});
describe('div', () => {
it('should be a function', () => {
expect(typeof math.div).toBe('function');
});
it('should compute values correctly', () => {
expect(math.div(1, 2)).toBe(0.5);
expect(math.div(-1, -2)).toBe(0.5);
expect(math.div(-1, 1)).toBe(-1);
});
});
describe('mod', () => {
it('should be a function', () => {
expect(typeof math.mod).toBe('function');
});
it('should compute values correctly', () => {
expect(math.mod(1, 2)).toBe(1);
expect(math.mod(-3, -2)).toBe(-1);
expect(math.mod(7, 4)).toBe(3);
});
});
実行結果
> jest
PASS ./index.spec.js
sum
✓ should be a function (1 ms)
✓ should compute values correctly
div
✓ should be a function
✓ should compute values correctly (1 ms)
mod
✓ should be a function
✓ should compute values correctly (1 ms)
Test Suites: 1 passed, 1 total
Tests: 6 passed, 6 total
Snapshots: 0 total
Time: 0.274 s, estimated 1 s
Ran all test suites.
AVA
インストール
$ npm install --save-dev ava
テストコード
const test = require('ava');
const math = require('../math');
test('sum', t => {
t.is(typeof math.sum, 'function');
t.is(math.sum(1, 2), 3);
t.is(math.sum(-1, -2), -3);
t.is(math.sum(-1, 1), 0);
});
test('div', t => {
t.is(typeof math.div, 'function');
t.is(math.div(1, 2), 0.5);
t.is(math.div(-1, -2), 0.5);
t.is(math.div(-1, 1), -1);
});
test('mod', t => {
t.is(typeof math.mod, 'function');
t.is(math.mod(1, 2), 1);
t.is(math.mod(-3, -2), -1);
t.is(math.mod(7, 4), 3);
});
実行結果
> ava
✔ sum
✔ div
✔ mod
─
3 tests passed
Mocha
インストール
$ npm install --save-dev mocha
テストコード
const assert = require('assert');
const math = require('../math');
describe('sum', () => {
it('should be a function', () => {
assert.equal(typeof math.sum, 'function');
});
it('should compute result correctly', () => {
assert.equal(math.sum(1, 2), 3);
assert.equal(math.sum(-1, -2), -3);
assert.equal(math.sum(-1, 1), 0);
});
});
describe('div', () => {
it('should be a function', () => {
assert.equal(typeof math.div, 'function');
});
it('should compute result correctly', () => {
assert.equal(math.div(1, 2), 0.5);
assert.equal(math.div(-1, -2), 0.5);
assert.equal(math.div(-1, 1), -1);
});
});
describe('mod', () => {
it('should be a function', () => {
assert.equal(typeof math.mod, 'function');
});
it('should compute result correctly', () => {
assert.equal(math.mod(1, 2), 1);
assert.equal(math.mod(-3, -2), -1);
assert.equal(math.mod(7, 4), 3);
});
});
実行結果
> mocha
sum
✔ should be a function
✔ should compute result correctly
div
✔ should be a function
✔ should compute result correctly
mod
✔ should be a function
✔ should compute result correctly
6 passing (7ms)
tape
インストール
$ npm install --save-dev tape
テストコード
const test = require('tape');
const math = require('../math');
test('sum', t => {
t.is(typeof math.sum, 'function');
t.is(math.sum(1, 2), 3);
t.is(math.sum(-1, -2), -3);
t.is(math.sum(-1, 1), 0);
t.end();
});
test('div', t => {
t.is(typeof math.div, 'function');
t.is(math.div(1, 2), 0.5);
t.is(math.div(-1, -2), 0.5);
t.is(math.div(-1, 1), -1);
t.end();
});
test('mod', t => {
t.is(typeof math.mod, 'function');
t.is(math.mod(1, 2), 1);
t.is(math.mod(-3, -2), -1);
t.is(math.mod(7, 4), 3);
t.end();
});
実行結果
> tape
TAP version 13
# sum
ok 1 should be strictly equal
ok 2 should be strictly equal
ok 3 should be strictly equal
ok 4 should be strictly equal
# div
ok 5 should be strictly equal
ok 6 should be strictly equal
ok 7 should be strictly equal
ok 8 should be strictly equal
# mod
ok 9 should be strictly equal
ok 10 should be strictly equal
ok 11 should be strictly equal
ok 12 should be strictly equal
1..12
# tests 12
# pass 12
# ok
Jasmine
インストール
$ npm install --save-dev jasmine
テストコード
const math = require('../math');
describe('sum', () => {
it('should be a function', () => {
expect(typeof math.sum).toBe('function');
});
it('should compute values correctly', () => {
expect(math.sum(1, 2)).toBe(3);
expect(math.sum(-1, -2)).toBe(-3);
expect(math.sum(-1, 1)).toBe(0);
});
});
describe('div', () => {
it('should be a function', () => {
expect(typeof math.div).toBe('function');
});
it('should compute values correctly', () => {
expect(math.div(1, 2)).toBe(0.5);
expect(math.div(-1, -2)).toBe(0.5);
expect(math.div(-1, 1)).toBe(-1);
});
});
describe('mod', () => {
it('should be a function', () => {
expect(typeof math.mod).toBe('function');
});
it('should compute values correctly', () => {
expect(math.mod(1, 2)).toBe(1);
expect(math.mod(-3, -2)).toBe(-1);
expect(math.mod(7, 4)).toBe(3);
});
});
実行結果
> jasmine
Randomized with seed 53426
Started
......
6 specs, 0 failures
Finished in 0.011 seconds
Randomized with seed 53426 (jasmine --random=true --seed=53426)
uvu
インストール
$ npm install --save-dev uvu
テストコード
const { test } = require('uvu');
const assert = require('uvu/assert');
const math = require('../math');
test('sum', () => {
assert.type(math.sum, 'function');
assert.is(math.sum(1, 2), 3);
assert.is(math.sum(-1, -2), -3);
assert.is(math.sum(-1, 1), 0);
});
test('div', () => {
assert.type(math.div, 'function');
assert.is(math.div(1, 2), 0.5);
assert.is(math.div(-1, -2), 0.5);
assert.is(math.div(-1, 1), -1);
});
test('mod', () => {
assert.type(math.mod, 'function');
assert.is(math.mod(1, 2), 1);
assert.is(math.mod(-3, -2), -1);
assert.is(math.mod(7, 4), 3);
});
test.run();
実行結果
> uvu
index.js
• • • (3 / 3)
Total: 3
Passed: 3
Skipped: 0
Duration: 1.01ms
ベンチマーク
~> "jest" 1.02s
~> "ava" 564ms
~> "mocha" 194ms
~> "tape" 118ms
~> "jasmine" 96ms
~> "uvu" 87ms
State of JavaScript
State of JavaScriptを見るとJestがダントツ人気で、次にMocha、Jasmine、AVAといったかんじですね。
やっぱりJestは強いです!
npm trends
ダウンロード数を半年で比較すると概ね、State of JacaScriptと同じような結果になりました。
JavaScriptフレームワーク
JavaScriptフレームワークの開発で使用されているテストフレームワークも調べてみました。
React
Jest
Vue
Jasmine
Angular
Jasmine
Svelte
Mocha
Next.js
Jest
Nuxt.js 2
Jest
Nuxt.js 3
Mocha
SvelteKit
uvu
おわりに
今回は主要なJavaScriptのテストフレームワークを6つ試してみました!
それぞれ書き方や、実行結果の表示の仕方や、速度に違いがあり、おもしろいなと思いました。
JavaScriptフレームワークの開発で使用されているテストフレームワークがそれぞれバラバラなのも興味深いです。
Jestはもちろんのこと、JasmineとMochaも使われてるケースがあり、一番後発であるSvelteKitはuvuが使われています。
uvuはベンチマークを見る限りでは一番早くて、軽量ですので今後注目です!
内包している機能が違うので単純比較できないかもしれませんが、Jestは実行速度が遅くなってしまう印象なので実行速度を早めたい場合はJest以外のテストフレームワークを使ってみるのもいいかもしれません。