社内で「node --test
って実際どうなの?」という議論がありました。その参考に、id:mizdra が node --test
最近を触って思ったことや、感想などを書いてみます。
結論だけ先に書いておくと、node --test
はミニマムなテスティングフレームワークです。テストする時に必要とされる機能は大体ありますが、Vitest と比較すると色々欠けてます。そして、Vitest と比べて何が足りないのか、実際に触ってみるまで意外と分からないです。とりあえず動けば OK という人は、Vitest 使ったら良いと思います。node --test
はミニマリスト向けです。
node --test
とは
まず node --test
って何という人のために書いておくと、Node.js 組み込みのテストランナーのことです。Node.js v16.17.0, v18.0.0 から導入されてます。
基本的な使い方は、以下の記事を見るとわかりやすいです。
一応ざっと要点を書いておくと、
node --test "src/**/*.js"
でテスト実行- "src/*/.js" は省略可能で、省略するとテストファイルっぽいものが自動で実行対象になる
- https://nodejs.org/api/test.html#running-tests-from-the-command-line
node:test
モジュールからテストのための utility が export されてるdescribe
,test
,mock
- Jest, Vitest とだいたい互換性のあるインターフェイス
- assertion だけは
node:assert
から export されてるnode:assert
はnode:test
より前からあった上に、テスト以外でも assertion が利用可能なので、別のモジュールになってる- インターフェイスも Jest, Vitest (BDD style) とは違う
- TypeScript でテストを書くには
--experimental-strip-types
が必要 *1node --test --experimental-strip-types "src/**/*.ts"
- スナップショットテスト もできる
--experimental-test-snapshots
が必要 *2- スナップショットの更新は
--test-update-snapshots
- テストファイル更新時に rerun するには
node --test --watch
id:mizdra は以下のリポジトリで使ってみています。
使ってみた感想
- 大体必要なものは揃ってる
- ちょろっとテスト書きたいだけなら事足りる
- デフォルトの reporter が素朴
- デフォルトは spec 形式:
$ npm t > @mizdra/node-next-image-loader@0.2.0 test > node --test --import ./src/index.js ✔ import (1.864875ms) ✔ require (1.852875ms) ℹ tests 2 ℹ suites 0 ℹ pass 2 ℹ fail 0 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0 ℹ duration_ms 94.315958
- GitHub Actions の Annotations に出す Reporter とかはない
- 一応カスタイマイズは可能らしいが
- デフォルトは spec 形式:
- assertion API が素朴
- node:assert と Vitest のドキュメントを比べると一目瞭然
- よく使うのだと
expect.arrayContaining
,toBeCloseTo
とかがない - リッチな API ほしければ3rd-party の assertion ライブラリ入れてくださいみたいな世界観
- スナップショットテストの機能が最低限
- Vitest にある Inline Snapshots はない
- File Snapshots もない
- Vitest は 画像のスナップショットも 3rd-party ライブラリを使えばできるが、それもない
- スナップショットを取る時に使われるシリアライザーをカスタイマイズする方法もない
- https://vitest.dev/guide/snapshot#custom-serializer
- まあこれは使う人そうそう居ないだろうけど
- 古い Node.js では動かないケースがある
- Node.js v18 にはスナップショットテストが実装されてない
- Web アプリケーション開発してるなら、Node.js のバージョン上げたら良いけど...
- ライブラリ開発者は古い Node.js もサポートするために、古い Node.js で CI 上でテスト実行してたりするので困る
- 古い Node.js にある機能だけどバグってて動かないというパターンもあるだろう
- Vitest なら古い Node.js でも動く
- 時間が解決してくれる問題ではある
- Node.js v18 にはスナップショットテストが実装されてない
- mock API はあるのは知ってるけど、触ったことないので何もわからないです!
- spy 的なものを作成する機能は当然ある
mock.module
というモジュールを mock するやつもあるけど、どれくらいちゃんと動くものなのかは不明- timer を mock するやつもある
- https://nodejs.org/api/test.html#class-mocktimers
- デフォルトでは
setInterval
,setTimeout
,setImmediate
,Date
が mock 対象とのこと - この辺は Vitest と同じっぽい: https://vitest.dev/api/vi.html#vi-usefaketimers
- VS Code に
node --test
を結合する Extension もある- https://marketplace.visualstudio.com/items?itemName=connor4312.nodejs-testing
- Vitest の https://marketplace.visualstudio.com/items?itemName=vitest.explorer みたいなやつ
- 使ったことないので、どれくらい出来が良いのかは知らないです!
- この辺みたらわかるかも: https://github.com/connor4312/nodejs-testing/issues
- feature branch で変更されたテストファイルのみ実行する、みたいな機能はない
- なんと Vitest にはある (すごい): https://vitest.dev/guide/cli#changed
- Vitest のやつは Git で変更されたファイルを検出する仕組み
- 仮にこれを Node.js に移植するとなると、Node.js が Git に依存することになるけど、それが Node.js のポリシー的に許可されるのか
- こういうの使いたくなる未来があるなら Vitest 使ったら良いと思う
- 他にも色々足りない機能あるはず
- TypeScript の型を assertion する機能とか: https://vitest.dev/guide/features.html#type-testing
- ブラウザモードとか: https://vitest.dev/guide/browser/
- ベンチマークとか: https://vitest.dev/guide/features.html#benchmarking
素朴だけど、それでも間に合うなら大丈夫という感じ。ミニマリストにはオススメです。
*1:ちなみにフラグなしでも TypeScript が利用できるような計画が進んでる: https://github.com/nodejs/typescript/issues/17
*2:最近安定化の PR がマージされたので、そのうち --test-snapshots でいけるようになるはず: https://github.com/nodejs/node/pull/55897