メインコンテンツへスキップ

Jest 28: 軽量化と互換性向上 🫶

· 1分で読める
Simen Bekkhus
Simen Bekkhus
非公式ベータ版翻訳

このページは PageTurner AI で翻訳されました(ベータ版)。プロジェクト公式の承認はありません。 エラーを見つけましたか? 問題を報告 →

待望のJest 28がついにリリースされました!今回のリリースでは、テスト実行のシャーディングによる複数マシン分散実行、package exportsのサポート、フェイクタイマーの動作カスタマイズなど、長年要望のあった機能が追加されています。これらは個人的なハイライトの一部で、このブログ投稿ではさらに多くの新機能をご紹介します。

さらに、昨年Jest 27のブログ投稿でお知らせした通り、デフォルトで使用されなくなったパッケージを標準インストールから削除しました。その結果、インストールサイズが約1/3減少しています。

破壊的変更

破壊的変更のリストは長くなっています(完全なリストは変更履歴で確認可能)。ただし移行を支援するため、ガイドも用意しました。これによりアップグレードを可能な限りスムーズに行えるはずです!

移行に影響する主な破壊的変更は、Node 10と15のサポート終了(ただしNode 12はまだサポート継続。数日後にはEOLとなります)と、一部設定オプションの名称変更です。

削除されたモジュール(jest-environment-jsdomjest-jasmine2)はどちらも従来通りメンテナンスとテストが継続されている点にご注意ください。ここでの破壊的変更は、これらを明示的にインストールする必要が生じたことだけです。

ガイドにより移行は容易になるはずですが、jestコマンドを実行するだけでなくjest-workerpretty-formatなどJestを構成するパッケージを直接使用している場合は、変更履歴を確認して破壊的変更を確認する必要があります。

新機能

それでは、ずっとエキサイティングなJest 28の新機能についてご紹介しましょう!数多くの機能が追加されていますので、しっかりお聞きください。

テスト実行のシャーディング

Jestに新たに追加された--shard CLIオプション(Mario Neblによる貢献)により、テストを複数マシンに分散して実行できるようになりました。これはJestで最も長く要望されていた機能の一つです。

Jest自身のCIテストスイートは、Ubuntu環境で約10分から3分に、Windows環境では20分から7分に短縮されました。

package.jsonexports

Jest 27.3でexportsの最小限サポートを導入しましたが、当時はメインエントリーポイント(.)のみの対応で、かつpackage.jsonmainフィールドが存在しない場合のみの制限がありました。Jest 28ではついに完全サポートを実現しました!

関連して、Jest 27ではrequireimportのいずれかの条件を提供していましたが、Jest 28ではjest-environment-nodeが自動的にnodenode-addons条件を提供し、jest-environment-jsdombrowser条件を提供するようになりました。

これはJestの最大の互換性問題の一つでしたが、今回のアップデートで永久に解決されることを願っています。

フェイクタイマー

Jest 26で導入された「モダン」フェイクタイマー(内部で@sinonjs/fake-timersを使用)はJest 27でデフォルトになりました。Jest 28では、設定とランタイムAPIの両方を通じて基盤実装のさらなる部分を公開しています。この機能を貢献してくれたTom Mrazauskasに多大な感謝を!

これによりprocess.nextTickをモックアウトする必要がなくなり、フェイクPromiseとの互換性が向上します。また、advanceTimersを有効にするとタイマーが自動的に進むようになります。

詳細はfakeTimers設定をご覧ください。

GitHub Actions レポーター

JestがGitHub Actionsで使用するレポーターを新たに搭載しました。アノテーションを使用してテストエラーをインライン表示します。

GitHub Actions テストエラーのスクリーンショット

このレポーターはreporters設定オプションgithub-actionsを指定することで有効化できます。

Bernie Reiter氏と他のコントリビューターの皆様に心より感謝申し上げます。粘り強いご協力によりこの機能が実現しました。

インラインtestEnvironmentOptions

testEnvironmentOptionsをファイル内でインライン指定できるようになりました。テスト環境の設定と同様に、単一ファイル内でURLを変更したい場合などに便利です。

/**
* @jest-environment jsdom
* @jest-environment-options {"url": "https://jestjs.io/"}
*/

test('use jsdom and set the URL in this test file', () => {
expect(window.location.href).toBe('https://jestjs.io/');
});

すべてのNode.jsグローバル変数

Node v18の新しいfetch実装を使用している場合、この関数がJestで利用できないことに気づいたかもしれません。これまではテストグローバルに手動でグローバル変数をコピーする必要がありましたが、Jest 28ではJest自身が実行されているグローバル環境を検査し、テスト環境で不足しているグローバル変数を自動的にコピーするため、この問題は解消されました。

ECMAScriptモジュール(ESM)

Jest 27リリース以降、ネイティブESMサポートに大きな変化はありません。Nodeでの安定化が進行中で、早期改善を期待しています!

ただし、Jest 28ではいくつかの新機能を追加しました。

data: URL

Tommaso Bossi氏がdata URLサポートを実装しました。これによりevalを使わずに実行するJavaScriptをインライン定義できるようになります。

import.meta.jest

これまでJestではimport {jest} from '@jest/globals'jestにアクセスできましたが、CJSで利用可能な(一見グローバルに見える)jest変数よりも使い勝手が悪いとのフィードバックがありました。Jest 28ではより簡単にアクセスできるimport.meta.jestを導入しました。

その他の機能

これらは膨大な新機能の一部で、私の個人的なハイライトです。さらに多くの機能を簡潔にご紹介します:

非同期リゾルバ

Ian VanSchooten氏が非同期リゾルバサポートを実装し、ViteなどのツールがJestとより深く統合できるようになりました。

非同期セットアップファイル

setupFiles使用時に非同期処理が必要な場合、async functionをエクスポートできるようになりました。Jestはテスト読み込み前にこの関数を呼び出して完了を待機します。

この機能はCJSのみで利用可能です。ESMの場合はトップレベルawaitの使用を推奨します。

globalThisの使用

内部では、Jest は グローバル環境 を参照するために global を使用してきました。しかし、これは Node 環境では存在しますがブラウザ環境 (window) では存在しないため、Jest のモジュールを別の環境で使用しようとすると互換性の問題が生じていました。

Jest 28 では代わりに globalThis を使用します。これはすべての環境で動作します。

JSDOM 19

前述のとおり、Jest はデフォルトのインストールに jest-environment-jsdom を含めなくなりましたが、引き続き積極的にメンテナンスされています。その一環として、Jest 28 では jsdom@16 から jsdom@19 にアップグレードされました。

TypeScript

テスト内で、またはカスタムランナーなどのプラグインを作成する際に TypeScript で Jest を使用している場合、Jest 28 では型に関する大幅な改善が行われています。以下に、Jest 28 での変更点の一部を紹介します(すべてを網羅しているわけではありません)。

expect

expect の型(直接使用する場合、または import {expect} from '@jest/globals' を介して使用する場合)を使用する際に、ついにカスタムマッチャーを追加できるようになりました。具体的な方法については、サンプル を参照してください。

カスタムプラグイン

カスタムランナー、テストレポーター、リゾルバーなどを作成している場合、これらをより正確に型付けするのに役立つ型を追加でエクスポートするようになりました。これは進行中の作業ですので、Jest でプラグイン可能なコンポーネントを作成している方で、型が十分に役立たない場合はぜひ issue を登録してください!

jest-runner-tsd

jest-runner-tsd は、型テストを実行するためのカスタムランナーです。これは Jest 自身が型をテストするために使用しているもので、他の方にも利用していただけることを願っています!名前が示すように、tsd をベースとしていますが、内部ではフォーク版の tsd-lite を使用しています。


これらの改善と修正はすべて Tom Mrazauskas さんが貢献してくれました。Tom さん、本当にありがとうございます!👏

最後に、TypeScript の最低サポートバージョンが 4.3 になりました。

jest-light-runner

このブログ投稿で最後に紹介したいのは、Nicolò Ribaudo さんが作成した非常にクールな新しい Jest ランナー jest-light-runner です。これは、Jest が知られるほぼすべての開発者体験(DX)を維持しつつ、Node 上での抽象化レイヤーを最小化することで大幅に高速化しています。Babel のテストでは移行後にほぼ2倍の速度向上が見られました。注意点はありますが、このランナーの存在により、テスト対象の Node モジュールが小規模な開発者が Jest を選択しやすくなるはずです。Nicolò さん、ありがとう!

将来の計画

Jest 28 は Jest 27 からほぼ1年後にリリースされましたが、Jest 29 はもっと早く、おそらく数か月以内にリリースされる予定です。現時点の計画では、Node バージョンのサポート終了を除き、破壊的変更は1つだけです。それは snapshotFormat のデフォルトを {escapeString: false, printBasicPrototype: false} に設定することです。これにより、スナップショットがより読みやすく、よりコピー&ペーストしやすくなります。

変更したくない場合はもちろん上書きも可能ですが、待たずに今すぐこれらのオプションを使用することもできます!

謝辞

Jest 28には60人以上の方々が貢献しており、そのうち3分の2以上が初めてのコントリビューターです。古参も新参も、すべてのコントリビューターに心から感謝します。皆さんがいなければ、プロジェクトはここまで良くなっていませんでした!特にTom MrazauskasFeng Yuには、コードの提供、Issueのトリアージ、デバッグなど、Jest 28の実現に貢献していただき、感謝しています。ありがとうございます! 🙏

ご覧いただきありがとうございました。Happy Jesting! 🃏