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

Jest 30:より高速、より軽量、より優れたテストフレームワーク

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

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

本日、Jest 30のリリースをお知らせできることを嬉しく思います。このリリースには、数多くの変更点、修正、改善が含まれています。Jest史上最大級のメジャーリリースの一つではありますが、メジャーリリースまでに3年もかかったことは確かに長すぎると認めます。今後は、より頻繁にメジャーリリースを行い、次の10年にわたってJestを優れたものにしていくことを目指します。

最新情報を飛ばしてすぐに始めたい場合は、npm install jest@^30.0.0を実行し、移行ガイド「Jest 29から30へのアップグレード」に従ってください。

新機能

Jest 30は、明らかに高速化され、メモリ使用量が削減され、数多くの新機能が追加されました。まずは破壊的変更点から見ていきましょう:

破壊的変更

  • Node 14、16、19、21のサポートを終了しました

  • jest-environment-jsdomがjsdom 21から26にアップグレードされました

  • TypeScriptの最低対応バージョンが5.4になりました

  • 様々なexpectエイリアスが削除されました。eslint-plugin-jestには自動修正機能があり、コードベースを自動的にアップグレードできます

  • 列挙不可のオブジェクトプロパティが、デフォルトでtoEqualなどのオブジェクトマッチャーから除外されるようになりました

  • Jestがデフォルトで.mtsおよび.ctsファイルをサポートするようになりました

  • --testPathPattern--testPathPatternsに名称変更されました

  • 最初にrejectされ、後でcatchされるPromiseを適切に処理するようになり、誤検知のテスト失敗を防げるようになりました

  • スナップショットの更新が必要になる可能性がある、スナップショット出力の様々な改善を行いました。Googleがスナップショットで使用していたgoo.glリンクを非推奨化しました。私たちもこの変更を好ましく思っていませんが、すべてのスナップショットを更新する必要があります

  • Jest本体がパッケージごとに単一ファイルにバンドルされるようになりました。これによりパフォーマンスが向上しますが、Jestの内部にアクセスするツールを構築している場合は問題が発生する可能性があります

これらはハイライトの一部です。破壊的変更の完全なリストは、CHANGELOGJest 30移行ガイドで確認できます。

パフォーマンスとメモリ改善

Jest 30は、特にモジュール解決、メモリ使用量、テスト分離に関連する多くの最適化により、実際のパフォーマンス向上を実現します。新しいunrs-resolverを採用したことで、Jestのモジュール解決は機能が豊富になり、標準に準拠し、高速になりました。移行を担当してくれた@JounQinに感謝します。プロジェクトによっては、テスト実行時間が大幅に短縮され、メモリ消費量が削減されるでしょう。例えば、クライアントとサーバーを持つ大規模TypeScriptアプリケーションでは、コードベースの一部でテスト実行速度が37%向上し、メモリ使用量が77%削減されました:

Jest 29Jest 30
Server tests~1350s / 7.8 GB max~850s / 1.8 GB max
Client tests~49s / 1.0 GB max~44s / 0.8 GB max

Jest自体は高速ですが、Jestのテスト分離の特性上、ユーザーコードの遅延がパフォーマンス問題を悪化させ、テスト実行を遅くすることがよくあります。テストが未完了のタイマーや他のサービスへの接続などのオープンハンドルを残すと、Jestがハングしたり遅くなったりすることがあります。Jest 30ではこれらの問題を検出・報告する機能が強化され、遅いテストや問題のあるテストを特定・修正しやすくなりました。例えばHappoでは、オープンハンドルをクリーンアップしJest 30にアップグレードすることで、テスト時間が14分から9分に50%短縮されました。

複数のモジュールのエクスポートを単一ファイルに集約する(いわゆる「バレルファイル」)を使用している場合、babel-jest-boostbabel-plugin-transform-barrelsno-barrel-fileなどのツールを利用することをお勧めします。これにより各テストファイルで大量のアプリケーションコードが読み込まれるのを防げ、最大100倍のパフォーマンス向上が期待できます。

テストファイル間のグローバル変数クリーンアップ

Jestはテストファイル間の分離を、各テストを個別のVMコンテキストで実行することで実現し、各ファイルに新鮮なグローバル環境を提供します。しかし各テストファイルの実行後にグローバル変数が適切にクリーンアップされない場合、Jest全体でメモリリークが発生し、テスト実行が遅くなる可能性があります。Jest 30では、テスト実行後に正しくクリーンアップされていないグローバル変数を通知する新機能が導入されました。

将来的にはJestは各テスト実行後に自動的にグローバル変数をクリーンアップします。Jest 30でクリーンアップされていないグローバル変数の警告が表示されない場合、今すぐグローバル変数クリーンアップモードを"on"に設定してこの機能を完全に有効化でき、大幅なメモリ節約とパフォーマンス向上の恩恵を受けられます:

export default {
testEnvironmentOptions: {
globalsCleanup: 'on',
},
};

Jestのデフォルト設定はglobalsCleanup: 'soft'です。この機能を無効にするにはoffに設定できます。共有ユーティリティやキャッシュなど、特定のグローバルオブジェクトをクリーンアップから保護する必要がある場合は、jest-utilを使用して保護対象としてマークできます:

import {protectProperties} from 'jest-util';

protectProperties(globalThis['my-property']);

この機能の実装を提供してくれた@eyalrothに感謝します!

新機能

強化されたECMAScriptモジュール & TypeScriptサポート

JestでのネイティブESM使用時import.meta.*file://のサポートが追加されました。さらにJest設定ファイルをTypeScriptで記述できるようになり、.mtsおよび.ctsファイルは追加設定なしでネイティブサポートされます。NodeのネイティブTypeScript型除去機能を使用している場合、型を除去するTypeScriptトランスフォーマーの読み込みが不要になり、テスト実行が高速化されます。

スパイとusingキーワード

JestのスパイでJavaScriptの新しい明示的リソース管理構文(usingが使用可能になりました。環境がサポートしている場合、using jest.spyOn(obj, 'method')と記述するとブロック終了時にスパイが自動的に復元されるため、手動でのクリーンアップが不要になります。

test('logs a warning', () => {
using spy = jest.spyOn(console, 'warn');
doSomeThingWarnWorthy();
expect(spy).toHaveBeenCalled();
});

ドキュメント

expect.arrayOf

Jest 30では新しい非対称マッチャーであるexpect.arrayOfが導入され、配列の全要素に対して条件や型の検証が可能になりました。例えばすべての要素が数値であることを保証する数値配列の検証ができます:

expect(someArray).toEqual(expect.arrayOf(expect.any(Number)));

ドキュメント

新しいtest.eachプレースホルダー: %$

データ駆動テストでtest.eachを使用する際、テストタイトルに特別なプレースホルダー%$を含めるとテストケースの番号を挿入できるようになりました。例:

test.each(cases)('Case %$ works as expected', () => {});

%$はテストのシーケンス番号に置き換えられます。

ドキュメント

jest.advanceTimersToNextFrame()

@sinonjs/fake-timersがv13にアップグレードされ、jest.advanceTimersToNextFrame()が追加されました。この新関数により保留中の全requestAnimationFrameコールバックを次のフレーム境界まで進められるようになり、ミリ秒単位の時間を推測せずにアニメーションやrequestAnimationFrameに依存するコードのテストが容易になります。

ドキュメント

設定可能なテスト再試行

Jest 30ではjest.retryTimes()が拡張され、再試行の処理方法を制御できる新オプションが追加されました。テストスイート全体が終了するまで待たずに、遅延を指定したり即座に失敗したテストを再試行したりできます:

// Retry failed tests up to 3 times, waiting 1 second between attempts:
jest.retryTimes(3, {waitBeforeRetry: 1000});

// Immediately retry without waiting for other tests to finish:
jest.retryTimes(3, {retryImmediately: true});

ドキュメント

jest.unstable_unmockModule()

Jest 30では実験的な新API jest.unstable_unmockModule() が追加され、モジュールのアンモック(特にネイティブESM使用時)をより細かく制御できるようになりました。

ドキュメント

jest.onGenerateMock(callback)

新しいonGenerateMockメソッドが追加されました。Jestがモジュールのモックを生成するたびに呼び出されるコールバック関数を登録し、モックがテスト環境に渡される前に変更できるようになります:

jest.onGenerateMock((modulePath, moduleMock) => {
if (modulePath.includes('Database')) {
moduleMock.connect = jest.fn().mockImplementation(() => {
console.log('Connected to mock DB');
});
}
return moduleMock;
});

ドキュメント

その他の改善点

カスタムオブジェクトのシリアライゼーション

Jestのマッチャーユーティリティがカスタムオブジェクトに静的なSERIALIZABLE_PROPERTIESを定義することをサポート。スナップショットやエラーメッセージに含めるプロパティを制御でき、出力をより焦点の絞られた関連性の高いものにできます。

ドキュメント

非同期セットアップのサポート

setupFilesAfterEnvにリストされたテストファイルがsetupFilesと同様、非同期関数のエクスポートやトップレベルawaitの使用に対応しました。

その他にも多数…

すべての変更点・改善点・新機能は完全なCHANGELOGでご確認ください。

既知の問題

jsdomが仕様準拠を強化する変更を行いました。特にテスト内でのwindow.locationモックなど一部のユースケースが影響を受ける可能性があります。Jestではjsdomベースのカスタムテスト環境構築を容易にする@jest/environment-jsdom-abstractを同梱。jsdomにパッチを適用したい場合はこのjsdomパッチをプロジェクトに適用できます。将来的にはテスト向けに最適化されたjsdomの代替手段を検討する予定です。

今後の展望

Jestは10年間で最も人気のあるJavaScriptテストフレームワークに成長し、数百万の開発者が小さなライブラリから世界最大級のコードベースまで幅広く利用しています。長期間にわたる実運用の中で技術的負債も蓄積し、少数しか利用しない機能のサポートや破壊的変更の最小化によりユーザー混乱を避けてきました。Jestで実現すべき機能のうちコアフレームワークに属さないもの、誤ったテスト手法を助長する可能性のある機能も存在します。チームメンバーの移動により進捗が鈍化した面もありますが、これらの課題を次のように解決していきます:

  • パフォーマンス/技術的負債: 大多数が使わない機能を削除し、Jestの本質的な価値に集中したより軽量で高速なコアへスリム化

  • 一貫したリリースサイクル: リリース間隔と非推奨ポリシーの一貫性向上

  • オープン性の強化: 計画の透明性確保と公開場での開発推進、コントリビューター増加の機会創出

  • 大胆に進めよう: Jestチームとして、もっと大胆になるべきです。Jestが本来の可能性を発揮するのを妨げている要因は数多くあります。今こそ行動を起こす時です。

素晴らしいことに、Jestは関心の分離が明確なモジュールシステムとしてフレームワークを構築した当初から、これらの原則を実現する準備が整っていました。今は実行の時です。これらについての詳細は近日中にお伝えします!

謝辞

このリリースは、私たちのコミュニティの皆様のご尽力なしには実現しませんでした。心より感謝申し上げます。

@SimenB, @mrazauskas, @Connormiha, @liuxingbaoyu, @k-rajat19, @G-Rath, @charpeni, @dubzzz, @stekycz, @yinm, @lencioni, @phawxby, @lukeapage, @robhogan, @fisker, @k-rajat19, @connectdotz, @alesmenzel, @rickhanlonii, @mbelsky, @brunocabral88, @brandon-leapyear, @nicolo-ribaudo, @dj-stormtrooper, @eryue0220

今回のリリースで初めてJestに貢献してくださった皆様に特に感謝します。皆様のおかげでJestはより良いものになりました!

@eyalroth, @KhaledElmorsy, @mohammednumaan, @bensternthal, @BondarenkoAlex, @phryneas, @jayvdb, @brandonchinn178, @latin-1, @rmartine-ias, @fa93hws, @Dunqing, @gustav0d, @noritaka1166, @andreibereczki, @Dreamsorcerer, @satanTime, @icholy, @ecraig12345, @cgm-16, @sebastiancarlos, @dancer1325, @loganrosen, @zakingslayerv22, @dev-intj, @tez3998, @anbnyc, @pengqiseven, @thypon, @co63oc, @danielrentz, @jonasongg, @andrew-the-drawer, @phryneas, @hyperupcall, @tonyd33, @madcapnmckay, @dongwa, @gagan-bhullar-tech, @ikonst, @ZuBB, @jzaefferer, @brandonnorsworthy, @henny1105, @DmitryMakhnev, @askoufis, @RahulARanger, @Jon-Biz, @fynsta, @KonnorRogers, @BondarenkoAlex, @mouadhbb, @kemuridama, @Avi-E-Koenig, @davidroeca, @akwodkiewicz, @mukul-turing, @dnicolson, @colinacassidy, @ofekm97, @haze, @Vadimchesh, @peterdenham, @ShuZhong, @manoraj, @nicolo-ribaudo, @georgekaran, @MathieuFedrigo, @hkdobrev, @Germandrummer92, @CheadleCheadle, @notaphplover, @danbeam, @arescrimson, @yepitschunked, @JimminiKin, @DerTimonius, @vkml, @ginabethrussell, @jeremiah-snee-openx, @WillianAgostini, @casey-lentz, @faizanu94, @someone635, @rafaelrabelos, @RayBrokeSomething, @DaniAcu, @mattkubej, @tr1ckydev, @shresthasurav, @the-ress, @Mutesa-Cedric, @nolddor, @alexreardon, @Peeja, @verycosy, @mknight-atl, @maro1993, @Eric-Tyrrell22

Jest 29: スナップショット形式の変更

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

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

Jest 29がリリースされました。Jest 28からわずか数ヶ月でのアップデートです。Jest 28のブログ記事で触れた通り、このバージョンではアップグレードをできるだけスムーズにするため、破壊的変更を最小限に抑えています。

JestがOpenJS Foundationに参加

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

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

Meta Open SourceとOpenJS Foundationのバナー画像

本日、JestがOpenJS Foundationに参加することをお知らせできることを嬉しく思います!

この変更により、プロジェクトの所有権がMetaからOpenJS Foundationを通じてImpact ProjectとしてJest Coreチームに移管されます。長年にわたるJestの作成とサポートを提供してくれたMetaに感謝するとともに、Jestコミュニティが所有するプロジェクトとしてのJestの未来を楽しみにしています!

詳細については、Meta EngineeringブログOpenJS Foundationブログの発表をご覧ください。

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

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

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

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

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

Jest 27:新たなデフォルト設定、2021年版 ⏩

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

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

約1年前のJest 26ブログ記事でお伝えした通り、破壊的変更の少ない2つのメジャーリリースを経て、Jest 27では新規プロジェクトやスムーズに移行できるプロジェクト向けに、より優れたデフォルト設定を導入します。これによりJest 28ではいくつかのパッケージをデフォルト配布から外し、代わりに個別インストール可能なプラグイン化モジュールとして提供できるようになります。新デフォルトを採用すればインストールサイズを削減でき、必要なパッケージは個別にインストール可能です。

画期的なバージョン15で導入された新デフォルト設定以来となる大規模なデフォルト変更を伴うJest 27が登場し、Jestを高速で軽量かつ将来的にも有用な状態に保ちます。この記事ではデフォルト設定の変更やその他の注目すべき破壊的変更を説明しますが、まずはエキサイティングな新機能から見ていきましょう!

Jestウェブサイトのアップグレード

· 1分で読める
Sébastien Lorber
Docusaurus maintainer
非公式ベータ版翻訳

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

新しくなったJestウェブサイトを発表できることを嬉しく思います!

Jestサイトは Docusaurus 1 から Docusaurus 2 へアップグレードされ、新しくリリースされたDocusaurus 2のi18nサポートの早期採用サイトとなりました。

具体的に何が新しくなったのでしょうか?

Jest 26: Tick Tock

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

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

Jestの再構築を開始した5年前、私たちの目標は「バッテリー内蔵」のゼロ設定テストランナーを提供することでした。初心者にも親しみやすく、ほぼすべてのテストユースケースで拡張可能で、大規模プロジェクトにも対応できるものにするためです。重要なリリースとなったJest 15は、すべてを統合し優れたデフォルト設定を提供したため、多くのユーザーが設定なしでJestを実行できるようになりました。しかしこのアプローチには大きな欠点があり、Jestがプロジェクトに不要な依存関係を多数インストールしてしまうことでした。

私たちはこの欠点に対処し始め、Jestのインストールサイズを縮小しながらも親しみやすさと拡張性を維持しています。Jest 26では以下の破壊的変更を実施しました:

Jest 25: 🚀 未来の基盤を築く

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

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

Jest 25は将来の大規模な変更に向けた基盤を整えています。破壊的変更は最小限に抑えましたが、内部アーキテクチャの変更によりアップグレード時に注意が必要な場合があります。主な変更点は、JSDOMのv11からv15へのアップグレード、テスト実行速度の10-15%向上、スナップショット更新時の新しい差分表示、Node 6サポートの終了です。

Jest 24.9以降、80人以上のコントリビューターによる200件以上のコミットが行われました。詳細な変更点は変更履歴でご確認ください。

Jest 24: 💅 刷新され、洗練され、TypeScriptに優しい

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

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

本日、Jestの新メジャーリリースとなるバージョン24を発表できることを嬉しく思います!前回のマイナーリリースから4ヶ月、Jest 23からは8ヶ月ぶりのアップグレードとなるため、全てのユーザーにとって重要なアップデートです!主なハイライトは、Jest内部をBabel 7にアップグレードしたことによるTypeScriptの組み込みサポート、コンソール出力が欠落する長年の問題の修正、大規模な差分計算時のパフォーマンス問題の解決、そして真新しいウェブサイトの公開です。✨

全ての変更点については変更履歴をご覧ください。

Jest オープンソースを支援する

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

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

Jest はオープンソース貢献者と Facebook 社員からなるコミュニティによってメンテナンスされています。

オープンソース貢献者はコミュニティのために新機能の開発、バグ修正、issue バックログの管理を行っています。Facebook 社員も同様の活動を行いつつ、Facebook の大規模環境特有の問題に注力し、公開前に提案されたすべてのリリースを Facebook の巨大なテストスイートで検証しています。

私たち全員が、テストを楽しい体験にするためにそれぞれの役割を果たしています。

Jest Summit で発表した Jest Open Collective は、オープンソース Jest コミュニティの取り組みを支援するための仕組みです。明確に申し上げます: Facebook 社員は Jest Open Collective の利益を受けることはできません。 このコレクティブの唯一の目的は Jest コミュニティのオープンソース側を支援することです。

本記事では Jest Open Collective の概要、構造、そして私たちの目標について説明します。