Mocha を使うときは assert.strictEqual を使ったほうがいいな?という話
こんにちは、@armorik83 です。タイムリーな話題で、ついさっきの@Jxck_さんのつぶやきが気になったので調べてみました。
<blockquote class="twitter-tweet" lang="en"><p lang="ja" dir="ltr">あれ?久しぶりに power-assert じゃない普通の assert 使ったら、表示が改善してる。こんなにわかりやすかったっけ?</p>— Jxck (@Jxck_) <a href="https://twitter.com/Jxck_/status/597987303387111424">May 12, 2015</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
Mocha 2.2.3 から賢くなっていた
どうもこれを見るに、reporter/base
という箇所に手が入ったようで、これによってassert
の出力が賢くなっていました。
比較してみよう
ソース
var assert = require('assert');
it('test1 strictEqual', function() {
var a = 'abcde';
var b = 'abcdf';
assert.strictEqual(a, b);
});
it('test1 eqeqeq', function() {
var a = 'abcde';
var b = 'abcdf';
assert(a === b);
});
it('test2', function() {
var a = {
hoge: 12
};
var b = {
hoge: 13,
fuga: 56
};
assert.deepEqual(a, b);
});
assert + Mocha 2.2.1
npm i mocha@2.2.1 && $(npm bin)/mocha spec.js
1) test1 strictEqual
2) test1 eqeqeq
3) test2
0 passing (15ms)
3 failing
1) test1 strictEqual:
AssertionError: 'abcde' === 'abcdf'
at Context.<anonymous> (/Users/armorik83/Desktop/mochasandbox/spec.js:6:10)
at callFn (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runnable.js:266:21)
at Test.Runnable.run (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runnable.js:259:7)
at Runner.runTest (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:387:10)
at /Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:470:12
at next (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:312:14)
at /Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:322:7
at next (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:257:23)
at Immediate._onImmediate (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:289:5)
at processImmediate [as _immediateCallback] (timers.js:357:17)
2) test1 eqeqeq:
AssertionError: false == true
at Context.<anonymous> (/Users/armorik83/Desktop/mochasandbox/spec.js:12:3)
at callFn (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runnable.js:266:21)
at Test.Runnable.run (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runnable.js:259:7)
at Runner.runTest (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:387:10)
at /Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:470:12
at next (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:312:14)
at /Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:322:7
at next (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:257:23)
at Immediate._onImmediate (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:289:5)
at processImmediate [as _immediateCallback] (timers.js:357:17)
3) test2:
AssertionError: { hoge: 12 } deepEqual { hoge: 13, fuga: 56 }
at Context.<anonymous> (/Users/armorik83/Desktop/mochasandbox/spec.js:23:10)
at callFn (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runnable.js:266:21)
at Test.Runnable.run (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runnable.js:259:7)
at Runner.runTest (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:387:10)
at /Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:470:12
at next (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:312:14)
at /Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:322:7
at next (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:257:23)
at Immediate._onImmediate (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:289:5)
at processImmediate [as _immediateCallback] (timers.js:357:17)
よく見る感じのやつです。なお、2.2.2 は欠番です。
assert + Mocha 2.2.3
npm i mocha@2.2.3 && $(npm bin)/mocha spec.js
1) test1 strictEqual
2) test1 eqeqeq
3) test2
0 passing (19ms)
3 failing
1) test1 strictEqual:
AssertionError: 'abcde' === 'abcdf'
+ expected - actual
+"abcdf"
-"abcde"
at Context.<anonymous> (spec.js:6:10)
2) test1 eqeqeq:
AssertionError: false == true
+ expected - actual
+true
-false
at Context.<anonymous> (spec.js:12:3)
3) test2:
AssertionError: { hoge: 12 } deepEqual { hoge: 13, fuga: 56 }
+ expected - actual
{
+ "fuga": 56
+ "hoge": 13
- "hoge": 12
}
at Context.<anonymous> (spec.js:23:10)
おおおっ!? assert(a === b)
よりassert.strictEqual(a, b)
の方が情報量が多いことが分かります。個人的にはタイプ量の好みでassert()
を使っていたんですが、Mocha と標準 assert の組み合わせではstrictEqual()
がよさ気なことに気付けました。
power-assert + Mocha 2.2.3
power-assertとも比較しておきます。1 行目のみ書き換えます。
var assert = require('power-assert');
npm i power-assert espower-cli mocha@2.2.3
$(npm bin)/espower spec.js > spec-esp.js && $(npm bin)/mocha spec-esp.js
1) test1 strictEqual
2) test1 eqeqeq
3) test2
0 passing (49ms)
3 failing
1) test1 strictEqual:
AssertionError: # spec.js:6
assert.strictEqual(a, b)
| |
| "abcdf"
"abcde"
+ expected - actual
+"abcdf"
-"abcde"
at Context.<anonymous> (spec-esp.js:5:12)
2) test1 eqeqeq:
AssertionError: # spec.js:12
assert(a === b)
| | |
| | "abcdf"
| false
"abcde"
--- [string] b
+++ [string] a
@@ -1,5 +1,5 @@
abcd
-f
+e
+ expected - actual
+true
-false
at Context.<anonymous> (spec-esp.js:18:5)
3) test2:
AssertionError: # spec.js:23
assert.deepEqual(a, b)
| |
| Object{hoge:13,fuga:56}
Object{hoge:12}
+ expected - actual
{
+ "fuga": 56
+ "hoge": 13
- "hoge": 12
}
at Context.<anonymous> (spec-esp.js:30:12)
power-assert では、assert(a === b)
使用時の情報量の方が豊富ですので、何を使うかはテスト対象や好みによります。標準の assert ログが強力になるのは嬉しい事ですね!
補足 Chai + Mocha 2.2.1
@t_wada さんからChai等の Assertion ユーティリティについて補足を頂きました。Chai は使ったことがないので、この際検証してみます。
var chai = require('chai');
var expect = chai.expect;
var assert = chai.assert;
it('test1 chai should', function() {
chai.should();
var a = 'abcde';
var b = 'abcdf';
a.should.be.a(a, b);
});
it('test1 chai expect', function() {
var a = 'abcde';
var b = 'abcdf';
expect(a).to.equal(b);
});
it('test1 chai assert', function() {
var a = 'abcde';
var b = 'abcdf';
assert.equal(a, b);
});
it('test2', function() {
var a = {
hoge: 12
};
var b = {
hoge: 13,
fuga: 56
};
assert.deepEqual(a, b);
});
npm i chai mocha@2.2.1 && $(npm bin)/mocha spec-chai.js
1) test1 chai should
2) test1 chai expect
3) test1 chai assert
4) test2
0 passing (17ms)
4 failing
1) test1 chai should:
AssertionError: abcdf: expected 'abcde' to be an abcde
at Context.<anonymous> (/Users/armorik83/Desktop/mochasandbox/spec-chai.js:9:15)
at callFn (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runnable.js:266:21)
at Test.Runnable.run (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runnable.js:259:7)
at Runner.runTest (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:387:10)
at /Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:470:12
at next (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:312:14)
at /Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:322:7
at next (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:257:23)
at Immediate._onImmediate (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:289:5)
at processImmediate [as _immediateCallback] (timers.js:357:17)
2) test1 chai expect:
AssertionError: expected 'abcde' to equal 'abcdf'
+ expected - actual
+abcdf
-abcde
at Context.<anonymous> (/Users/armorik83/Desktop/mochasandbox/spec-chai.js:15:16)
at callFn (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runnable.js:266:21)
at Test.Runnable.run (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runnable.js:259:7)
at Runner.runTest (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:387:10)
at /Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:470:12
at next (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:312:14)
at /Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:322:7
at next (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:257:23)
at Immediate._onImmediate (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:289:5)
at processImmediate [as _immediateCallback] (timers.js:357:17)
3) test1 chai assert:
AssertionError: expected 'abcde' to equal 'abcdf'
at Context.<anonymous> (/Users/armorik83/Desktop/mochasandbox/spec-chai.js:21:10)
at callFn (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runnable.js:266:21)
at Test.Runnable.run (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runnable.js:259:7)
at Runner.runTest (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:387:10)
at /Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:470:12
at next (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:312:14)
at /Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:322:7
at next (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:257:23)
at Immediate._onImmediate (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:289:5)
at processImmediate [as _immediateCallback] (timers.js:357:17)
4) test2:
AssertionError: expected { hoge: 12 } to deeply equal { hoge: 13, fuga: 56 }
+ expected - actual
{
+ "fuga": 56
+ "hoge": 13
- "hoge": 12
}
at Function.assert.deepEqual (/Users/armorik83/Desktop/mochasandbox/node_modules/chai/lib/chai/interface/assert.js:205:32)
at Context.<anonymous> (/Users/armorik83/Desktop/mochasandbox/spec-chai.js:32:10)
at callFn (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runnable.js:266:21)
at Test.Runnable.run (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runnable.js:259:7)
at Runner.runTest (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:387:10)
at /Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:470:12
at next (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:312:14)
at /Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:322:7
at next (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:257:23)
at Immediate._onImmediate (/Users/armorik83/Desktop/mochasandbox/node_modules/mocha/lib/runner.js:289:5)
at processImmediate [as _immediateCallback] (timers.js:357:17)
Stack trace が長いものの、Mocha 2.2.1 時点で優秀ですね! 知りませんでした。
補足 Chai + Mocha 2.2.3
npm i chai mocha@2.2.3 && $(npm bin)/mocha spec-chai.js
1) test1 chai should
2) test1 chai expect
3) test1 chai assert
4) test2
0 passing (24ms)
4 failing
1) test1 chai should:
AssertionError: abcdf: expected 'abcde' to be an abcde
at Context.<anonymous> (spec-chai.js:9:15)
2) test1 chai expect:
AssertionError: expected 'abcde' to equal 'abcdf'
+ expected - actual
+"abcdf"
-"abcde"
at Context.<anonymous> (spec-chai.js:15:16)
3) test1 chai assert:
AssertionError: expected 'abcde' to equal 'abcdf'
at Context.<anonymous> (spec-chai.js:21:10)
4) test2:
AssertionError: expected { hoge: 12 } to deeply equal { hoge: 13, fuga: 56 }
+ expected - actual
{
+ "fuga": 56
+ "hoge": 13
- "hoge": 12
}
at Context.<anonymous> (spec-chai.js:32:10)
なるほど、Chai を使うならexpect(a).to.equal(b)
が一番情報量が豊富な結果となりました。かつて使い慣れたテストフレームワークがあったり、タイプ量、読みやすさ等、好みかと思います。
Chai 以外は割愛します。
期せずして Assertion ユーティリティの比較記事となりました。色々ありますね! タイトルは若干モニョってますが、もう最初のままで。
以上です。
Discussion