2016-06-04 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/karma や testem/testem (2014-04-16) を想像する。karma や testem は headless browser を含めて制御する。mocha や jasmine のような test framework で書かれた test を browser で動かすから test runner だ。 headless browser の制御という意味なら casperjs/casperjs も近いかもしれない。CasperJS ariya/phantomjs や laurentj/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 まわりの挙動に納得できる。
@bouzuya これも test() で書くのを主流としたら不要な哲学ですけどね。eater最初は単純なスクリプトランナーで、『exampleコードがそのままテストに使えればええやろ』位に雑に考えててその時にエラー出力に吐いたらfailって思想にしたんですよね。
— Yosuke FURUKAWA (@yosuke_furukawa) June 6, 2016
最近 (昨日?) まで勘違いしていたけど、eater は runner が必須ではなくて、単純に assert の書かれたスクリプトをそのまま実行するイメージなんだよね。だから stderr が fail を表すとすると都合が良いんだろうね (このへん詳しくないので適当
— bouzuya (@bouzuya) June 7, 2016
追記: Speaker Deck で資料を見つけたので掲載。