Jest 27:新たなデフォルト設定、2021年版 ⏩
このページは PageTurner AI で翻訳されました(ベータ版)。プロジェクト公式の承認はありません。 エラーを見つけましたか? 問題を報告 →
約1年前のJest 26ブログ記事でお伝えした通り、破壊的変更の少ない2つのメジャーリリースを経て、Jest 27では新規プロジェクトやスムーズに移行できるプロジェクト向けに、より優れたデフォルト設定を導入します。これによりJest 28では いくつかのパッケージをデフォルト配布から外し、代わりに個別インストール可能なプラグイン化モジュールとして提供できるようになります。新デフォルトを採用すればインストールサイズを削減でき、必要なパッケージは個別にインストール可能です。
画期的なバージョン15で導入された新デフォルト設定以来となる大規模なデフォルト変更を伴うJest 27が登場し、Jestを高速で軽量かつ将来的にも有用な状態に保ちます。この記事ではデフォルト設定の変更やその他の注目すべき破壊的変更を説明しますが、まずはエキサイティングな新機能から見ていきましょう!
機能アップデート
まず、スナップショットの失敗を確認・更新する際のインタラクティブモードが、失敗したテストを1つずつステップ実行するためにも使えるようになりました。この機能を実装した初めてのコントリビューター@NullDivisionにクレジットを!

スナップショットと言えば、ここ数年でリリースした特に注目すべき機能の1つがインラインスナップショットです。約3年前のJest 23マイナーリリースで導入されましたが、これを利用するプロジェクトはコードフォーマッターとしてPrettierを使用することが条件でした。Jestがスナップショットを書き込むファイルの適切なフォーマットを保つために必要だったからです。
そのため長年にわたり、この制限をなくしてPrettierなしでインラインスナップショットを使えるようにするプルリクエストが進行中でした。初めてのコントリビューター@mmkalが『Uglier Inline Snapshots』というユーモラスな作業名で提出したこのPRは、分岐して先にマージされたPRを考慮せずとも100件以上のコメントが集まり、途中でオーナーも変更されました。Prettierが近年驚異的に普及した今、この改良は2018年当時ほど必要ではないかもしれません。それでも、Prettierを使っていないプロジェクトに参加した途端にインラインスナップショットが使えなくなるあの感覚は皆さんもご存じでしょう。もう二度と!
この機能のマージに時間がかかった主な理由は、驚くべきことにビルドパイプラインのメモリ不足エラーでした。各テストファイルで構文解析、スナップショット挿入、出力処理を行う依存関係が、かなりの時間とメモリオーバーヘッドを招いていたのです。
そこでいくつかの工夫を施し、テストファイルごとの初期化をJest 26比で約70%高速化しました。ただし、プロジェクトでこれほどのパフォーマンス改善を実感する可能性はほぼありません。この改善を最も実感するには、大量のテストファイルがそれぞれ高速に実行される必要があり、JSDOM環境使用時のオーバーヘッドがこのような改善を上回るからです。
別のニュースとしては、ネイティブESMサポートが進展していますが、モック周りなど重大な複雑さが残っており、ESM移行はNodeや数多くの重要なツール・パッケージが全体として魅力的な体験を提供するために相互依存する巨大なエコシステム努力であると認識し続けています。
Jestへのモジュール接続向けのESMサポートはより進んでおり、カスタムランナー、レポーター、ウォッチプラグインなど多くのモジュールがESモジュールとして既に読み込めます。
また、Bazelユーザーから強く要望されていた、テストディレクトリにシンボリックリンクされたテストファイルを扱えるようにするプルリクエストをマージしました。
別のプルリクエストでは、transformを非同期処理可能にしました 。これはesbuild、Snowpack、Viteなどのツールによるトランスパイルを効果的にサポートするために必要な機能です。
デフォルト設定の変更
これまでデフォルト設定でJestを使用していた場合、おそらく気づかないうちに、テストフレームワーク関数(describe、it、beforeEachなど)を提供するテストランナーJasmine 2.0から数年前にフォークされたコードを実行していました。2017年、Aaron Abramovがエラーメッセージや保守性、拡張性を改善する目的でJasmineコードの代替となるjest-circusを最初に作成しました。
Facebookでの大規模な活用やJest自体での使用、最近のcreate-react-appでの採用を経て、jest-circusがjest-jasmine2と高い互換性を持ち、ほとんどの環境で最小限の移行作業で動作することが確認できました。実行順序や厳密さに若干の違いはあるものの、jasmine.getEnv()のようなJasmine固有のAPIに依存するコード以外では大きな 移行課題はないと予想しています。これらのAPIに依存している場合は、設定で"testRunner": "jest-jasmine2"と指定することでJasmineベースのテストランナーを継続利用できます。
JSDOM環境でのテスト実行は大幅なパフォーマンスオーバーヘッドを伴います。これまで特に設定しない限りこれがJestのデフォルト動作だったため、例えばNodeアプリ開発者が不要な高コストなDOM環境を提供されていることに気づかないケースがありました。
このためデフォルトのテスト環境を"jsdom"から"node"に変更します。DOM APIを使用しておりテスト環境を明示的に設定していない場合、documentへのアクセス時などにエラーが発生します。"testEnvironment": "jsdom"の設定やファイル単位の環境設定で対応可能です。
一部のテストでDOM環境が必要な混合プロジェクトでは、高速な"node"環境をデフォルトとし、DOMが必要なテストのみドックブロックで明示することを推奨します。
次期メジャーバージョンではjest-jasmine2とjest-environment-jsdomをJestの依存関係から削除し、明示的なインストールを必須とする予定です。これにより多くのユーザーが不要なものを含まない軽量なインストールを享受できます。
もう一つのデフォルト変更はフェイクタイマー(別名タイマーモック)に関 するものです。Jest 26で導入されたオプションの「モダン」実装は、DateやqueueMicrotaskなど包括的なモックを提供しつつ同じAPIで透過的に利用できました。
このモダンなフェイクタイマー実装が新デフォルトとなります。微妙な実装の差異により移行が困難な場合は、jest.useFakeTimers("legacy")で旧実装を利用可能です。設定でグローバルに有効化している場合は"timers": "legacy"を指定してください。
破壊的変更を伴う機能
意図せず発生しやすい操作を禁止することでミスを防ぐため、いくつかの小さな破壊的変更を導入しました:
-
同じ
doneテストコールバックを複数回呼び出せなくなりました -
doneの呼び出しとPromiseの返却を同時に使用できなくなりました -
describeブロックは何も返してはいけません
以下の設定オプションで使用されるモジュールは、他のコードと同様に変換されるようになりました。これらがそのままロードされることに依存していた場合、互換性の問題が発生する可能性があります:
-
testEnvironment -
runner -
testRunner -
snapshotResolver
その他の破壊的変更
長期間非推奨となっていた関数を削除しました:
-
jest.addMatchers(代わりにexpect.extendを使用してください) -
jest.resetModuleRegistry(代わりにjest.resetModulesを使用してください) -
jest.runTimersToTime(代わりにjest.advanceTimersByTimeを使用してください)
Jestの多くのパッケージがESMスタイルのエクスポートを使用するように移行されました(ただしCommonJSとして配布は継続)。例えばpretty-formatを直接使用している場合、インポートをdefaultインポートに調整する必要があるかもしれません
Node 13のサポートを終了しました。ただしJestは常に_Current_およびすべての_LTS_Nodeバージョンをサポートしており、Jest 27は最近までサポートされていたNode 10のサポートも継続しています
いつもの通り、完全な変更履歴と破壊的変更の一覧はこちらで確認できます
最後に、コミュニティがState of JS 2020調査でJestに96%という驚異的な満足度を再び授けてくださったことに感謝します!皆様のご安全をお祈りするとともに、これからもJestをお楽しみいただけますよう願っています! 🃏
