bouzuya.hatenablog.com

ぼうずやのにっき

eater : EAsy Test runnER をためした

yosuke-furukawa/eater を試した。

yosuke-furukawa/eater は EAsy Test runnER の名前のとおり、簡単に使える test runner だ。

"test runner" という区分がいまひとつ分からない。動きから見ると eater は file ごとに child process を動かす。file 内の test() で assert を group 化し、その単位で実行結果を report してくれる。動作は Node.js を想定し web browser を想定していない。そして assert の機能を持っていない。

"test runner" と言うと karma-runner/karmatestem/testem (2014-04-16) を想像する。karma や testem は headless browser を含めて制御する。mocha や jasmine のような test framework で書かれた test を browser で動かすから test runner だ。 headless browser の制御という意味なら casperjs/casperjs も近いかもしれない。CasperJS ariya/phantomjslaurentj/slimerjs の wrapper のような感覚だけど……。

脱線した。 eater を test runner として見るなら Node.js 限定の test runner だ。 child_process などを使っているので、おそらく web browser 動かないだろう (試したわけではない) 。

さて test framework (mocha/AVA) との違いを見る。

まず、ぼくの test framework 歴は次のとおりだ。

mochajs/mocha -> avajs/ava -> yosuke-furukawa/eater

AngularJS 時代に Jasmine を使っていた気もするけど、blog に記述がないので気のせいということにする。そして上記の test runner や test framework という表現には触れないでおく。

eater はここ数日の間につくった bouzuya/rfc6570-expand で軽く試した。また source code をひととおり読んだ。次の記事はここ数日のものだ。

  • 2016-06-01 bouzuya/rfc6570-expand を RFC 6570 URI Template level 4 に仮対応させた
  • 2016-06-03 bouzuya/rfc6570-expand をつくった && TDD の良さを再認識した

上記の経験を踏まえて書く。あくまで軽く試した上での比較・感想だ。

mochajs/mocha には assert の機能を持っていない点で似ている。mocha の describe /it で global を汚染する点は大きな欠点だ。 eater は test() に閉じているのでこの点は問題ない。mocha は before() との context 共有に this を使う点が () => {} にあっていない。 eater にはそもそも before() がない。mocha は test の定義と実行を切り離している印象を受ける (実装がどうかは知らない) が、eater の test は区別なく実行している印象を受ける。mocha の it は callback に done: (error?: Error) => void; を指定すると非同期になる謎挙動だ。eater の test(s, f)new Promise(f)f を流用しているため (resolve, reject) => {} だ。引数や挙動は明快だ。ただ、毎回 resolve を呼ばされるのは eater の良くない点だ。あと mocha は web browser で動くが、eater は動かない。これも良くない。

avajs/ava には child process を使って高速化する点や describe / it で global を汚染しない点、web browser で動かない点で似ている。ava の非同期への support は手厚い。AVA は戻り値で Promise / Generator / async / Observable などを返すと待ってくれる。eater はどれも対応していない。resolve を呼べ。それだけだ。AVA はやりすぎだ。eater もまたやりすぎだ。ただ AVA よりは eater のほうがましだ。これについては後述する。

ざっと書いた。漏れ等ありそうだけど、とりあえず思いつくままに書いた。

ぼくの AVA -> eater の理由を書く。

2016-03-11 にぼくは AVA のことを書いた。mochajs/mocha から avajs/ava への乗り換えを検討していたからだ。これは上位互換ではない。mocha は web browser で動くが AVA は web browser で動かない。そこは妥協した。web browser の互換性の test をしたいわけではないからだ。AVA はそこを抜きにすればそこそこ期待通りに動く。しかし、AVA には大きな問題がある……大きいことだ。

AVA は大きい。power-assert や babel を含んでいる。これは将来を見越している。Promise / Generator / async / Observable 。これらに対応するため、いろいろなものを含んでいる。だから巨大だ。batteries included な考え方だろうか。環境構築の手間は省けるのだけど、複雑で巨大すぎたと感じる。ぼくの感じただけでも Observable support が壊れたり (2016-03-25) 、.d.ts まで手が回らなかったり (2016-03-26) した。不安を感じた。依存関係もかなり多いので npm i するためにいらいらする。

そこで eater だ。

eater は小さい。ぼくに言わせれば eater は easy というより simple だ。assert を持たない。before / after も Promise support さえ持たない。それにそこまでの不満は感じない。何より小さい。source code を読んでから使いはじめられる。source code は数えるほどしかない。機能は少ない。しかし、小さいので不安も小さい。

eater の示した方向に大きな不満はない。mocha のように assert を切り離して小さくなっているが、 mocha のように describe / it で global を汚染したり、--watch を持ち込んだりしない。AVA のように高速だし、power-assert を初期で持つような余計な依存関係を持たない。……それでも小さな不満はある。

たとえば reporter が弱い。見づらい。Error は流れてしまうし、非同期処理のせいか、success と failure が混ざる。件数も分からない。件数が分かる reporter を使うと詳細が一切表示されない。せっかくなので自作してみることにした。

bouzuya/eater-b-reporter (npm:eater-b-reporter) だ。

もともとこの reporter について書こうと思ったが、長くなってしまったので日を改める。

追記: eater は test() を使わないことを想定している。たとえば example の script をそのまま動かすような場面だ。その前提に立つと、README の構成や stderr まわりの挙動に納得できる。

追記: Speaker Deck で資料を見つけたので掲載。

eater // Speaker Deck