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

React Native Testing Libraryをマスターする

React Native Testing Libraryの設定、クエリ、モッキング、CIのTipsでアプリをテストする方法を学びましょう。コンポーネント、フック、ナビゲーションを含むユーザー中心のテストを確実に作成してください。

React Native Testing Library  アプリを正しくテストする方法

ユーザーが実機で「続行」をタップしても何も起こらないのに、テストスイートは緑色です。コンポーネントテストではボタンが見つかり、ハンドラーが呼び出され、期待どおりの画面がモックされたJavaScript環境で表示されました。ただし、ネイティブの許可ダイアログ、キーボードの動作、アニメーション、プラットフォーム API、または実際のナビゲーションスタックを検証することはしていませんでした。

チームはその間違いを信じてしまいます。 React Native テスト ライブラリ コンポーネントがどのようにレンダリングし、ユーザーがどのように反応するかをテストするのに適していますが、実機テストやパフォーマンス測定の代わりではありません。信頼できる戦略は、各レイヤーで暴露できるエラーを使用することです。

目次

ユーザー センター テストが何を変えるのか

Aテストの失敗は、テストが書かれる前に始まることがある。開発者はコンポーネントのプロパティを検査し、内部の状態にアクセスする、または比較的大きなスナップショットを比較するのは、簡単にアサートできるからだ。テストはパスし、リファクタリングがコンポーネントの構造を変更したが、エクスペリエンスを変更しなかった場合、スイートは破損する。さらに、テストはパスし続け、ユーザーに視覚的な不正が生じる可能性があるのは、ユーザーが必要とすることを説明するアサートが存在しないからだ。

React Native Testing Libraryはその逆のアプローチを取る。コンポーネントをレンダリングし、可視性のあるコントロールを介してそれにインタラクティブにし、ユーザーが観察できる結果をアサートする。 そのアプローチはReact Native Testing Libraryのユーザー中心の例

、そしてReact Nativeのテストガイドラインを遵守する

ユーザーが信頼している動作をテストする

ユーザー中心のテストの利点を示す図 disabled ユーザーが依存している動作をテストすることの利点を示す図。図には、ユーザー動作、耐性、信頼性、そして良好な慣行が含まれている。

2 番目のテストは、フォームがローカル ステート、レデューサー、カスタム ヒープ、または別のボタン実装を使用しているかどうかを気にしない。アプリが正しい結果を伝えることを気にしている。

実用的なルール: ユーザーが観察できないものは、コンポーネントの動作テストに含まれるべきではないかと疑問に思う。

アクセシビリティ ラベルとロールに基づくクエリも、より良い製品codeを強制する。意味のあるラベルを露出するスクリーンは、助け技術とテストで容易に使用できる。そうした接続は、より広いアプリのユーザー エクスペリエンスを評価する際に重要である。 アプリのユーザー エクスペリエンス、テスト性と使いやすさはよく一緒に改善されることが多い。

テストが通ったことを証明することの限界

ユーザー センターのコンポーネント テストは、JavaScript が期待どおりの branch をレンダリングし、シミュレートされたクリックに反応することを証明できる。ビометリック ポイントが正しく開くこと、ネイティブ カメラが使える結果を返すこと、またはプラットフォーム固有のライフサイクル ビヘイビアが流れの結果を変えることなど、テストが証明できないことを知る必要がある。

その境界は、ライブラリの弱点ではなく、テスト層を正直にする理由である。RNTL をコンポーネントの動作テストに使用し、ネイティブ統合、リアル ナビゲーション、パーミッション、認証、支払い、またはアプリのコア機能が結果を変える流れでは、デバイスベースのテストを予約する。

実際に機能するインストールと設定

モダンなセットアップは、スコープ パッケージから始まる。

@testing-library/react-native

古い react-native-testing-library npm パッケージ名は歴史的記念物として残っているが、現在のプロジェクトでは、テスト ライブラリファミリー内で管理されているスコープパッケージを使用することをお勧めします。 GitHub リポジトリ は、React Native のテスト慣行を奨励するユーティリティとして記述されています。また、リリース履歴は、React Native とともに変化し続けているライブラリであることを示しています。

既存の Jest 環境でライブラリをインストールします。Expo プロジェクトでは、Expo Jest プリセットを使用することが一般的ですが、bare React Native プロジェクトでは、React Native プリセットを使用することが推奨されます。

npm install --save-dev @testing-library/react-native jest

Expo の場合、プロジェクトがすでに使用しているプリセットを追加します。

{
  "scripts": {
    "test": "jest"
  },
  "jest": {
    "preset": "jest-expo"
  }
}

bare React Native アプリケーションでは、対応する React Native Jest 設定を使用します。フレームワークのバージョンとプリセットを同期することが重要です。RNTL 問題と見なされる多くの失敗は、React レンダラー、Babel トランスフォーム、または Jest プリセットの不一致によるものです。

セットアップファイルを明確にします。

共有環境設定をセットアップファイルに格納し、各テストで繰り返しモックを使用するのではなく、Jest から参照します。

// jest.setup.js
import '@testing-library/react-native/extend-expect';

アプリが React Navigation、Reanimated、ジェスチャーハンドリング、セーフエリアコンテキスト、またはストレージモジュールを使用している場合、テスト環境が必要とするモックのみを設定します。アプリケーションの動作を変更するグローバルモックは、すべてのテストを容易にし、スイートの信頼性を低下させる可能性があります。

{
  "jest": {
    "preset": "jest-expo",
    "setupFilesAfterEnv": ["<rootDir>/jest.setup.js"]
  }
}

TypeScript も同じ注意が必要です。Jest が変換し

そして .ts と .tsx ファイルをプリセットまたはBabelの構成ファイルを通じて、コンパイラにテストの種類を保持します。ローカルで実行されるテストですが、型チェックされていない場合、不正なクエリ名、無効なナビゲーションパラメータ、または安全でないモックの形状が隠れてしまいます。

リリースの時系列は、古いセットアップアドバイスを診断する際に役立ちます。プロジェクトのリスト 127のリリース, v14.0.1は2026-06-23にタグ付けされました, v12.9.0は2024-11-27にリリースされ、公式のReact Native 0.77とExpo 52のサポートを追加しました。. v14のアルファラインは2025年3月にUniversal Test Rendererからdeprecated React Test Rendererに移行し、React 19のみのサポートを準備しました。これらの詳細はRNTLのリリース履歴,

に表示されます。古いチュートリアルからレンダラー依存関係をコピーする際は、自分のアプリのバージョンを確認してください。 実践的なJestの基盤を確立するには、構成をこのJestの単体テストガイドと比較してください。、すると、ナビゲーションとネイティブモックを追加する前に、小さなコンポーネントテストを実行します。

React Native Testing Library プロジェクトの設定のための 5 つのステップのインフォグラフィック。

Core APIs Queries と Assertions の解説。

RNTL テストは、ユーザーが見る、見つける、操作できるものと一致するクエリを使用することで信頼性が高まります。API は小さくて簡単ですが、実装詳細を露出するセレクターを選択すると、パスするテストが誤解を招く可能性があります。

はじめに render:

const screen = render(<LoginForm />);

ユーザーにとって最も関連性の高いクエリを選択します。アクセシビリティ指向のクエリを優先してください。コンポーネントがアクセシビリティ指向のクエリを露出している場合、表示テキストを使用してテキストが動作する場合、または意味のあるユーザーフェイスのセレクターが必要ない場合や安定した統合ホックが必要な場合に予約します。 testID インフォグラフィック ピラミッド チャートで、ソフトウェア テスト オートメーションにおけるクエリの推奨優先順位を示します。

時期と意図に基づいてクエリを選択します。

各クエリファミリーには、独自の目的があります。

同期的存在:

  • 使用 Use getByRole, getByText、または getBy 要素がすでに存在する場合のクエリを指定します。要素が存在しない場合、テストは即座に失敗します。
  • 非同期表示: 使用 findByRole または findByText 表示の非同期更新時
  • 存在しない可能性のある要素の検証: 使用 queryByText または queryByTestId 存在しない可能性のある要素の検証:
  • 代替セレクター: 使用 getByTestId 意図的に。複雑なコントロールに持続可能なハンドルを与えるが、全体的なアプリのラベルを置き換えるべきではない。

フォーカスされたイベントテストの場合、 fireEvent.press 直接的なものは:

fireEvent.press(screen.getByRole('button', { name: 'Save' }));

使用 userEvent インストールされているバージョンがより現実的なインタラクションシーケンスをサポートする場合、またはどちらかを使用してください。どちらの場合も、結果のUIを確認してください:

expect(await screen.findByText('Saved')).toBeTruthy();

ハンドラのアサーションは、パブリック契約であるイベントコールバックを持つコンポーネントに適合します。ただし、ユーザージャーニーが機能することを証明するだけの弱い証拠です。

スナップショットよりも具体的なアサーションを優先してください。

良いアサーションは画面を説明します:

expect(screen.getByText('Account created')).toBeTruthy();
expect(screen.getByRole('button', { name: 'Continue' })).toBeEnabled();

また、可用性状態、選択、表示される検証フィードバックを検証することもできます。内部のワイヤリングを確認するのを避けてください:

expect(screen.getByTestId('submit-button').props.onPress).toBeDefined();

そのアサーションはプロパティが存在することを証明するだけであり、機能が機能することを証明するものではありません。小規模で意図的にスナップショットを使用すると、構造的な変更をキャッチできますが、大規模なナビゲーションまたは画面のスナップショットは、ノイズの多いレビューを作成し、説明のない更新を容易に承認する可能性があります。

テスト ライブラリ パッケージは、より広い testing-library npm 組織に属します。アクティブなパッケージには @testing-library/react-nativeバージョン 2026年に13.3.3が公開されました。プロジェクトの リポジトリ情報によると共通のクエリ規約はプラットフォームを横断するのに役立ちますが、製品の動作を表すアサーションを決定することはありません。

Jestコンポーネントテストの実践のより広範な比較については、以下のユニットテストガイドを参照してください。 ReactRNTLはJavaScriptレンダリングされたコンポーネントの境界で止まります。ネイティブのパーミッション、リアルなナビゲーションスタック、デバイスのキーボード、フレームタイミング、メモリの動作は、E2Eまたはパフォーマンスツールを使用する必要があります。コンポーネントのモックよりも。

以下のビデオは、クエリとアサーションのワークフローを実際に示しています。

コンポーネント、フック、ナビゲーションの実践的なパターン

有効なテストスイートは、実際のアプリケーションの形をとります。プレゼンテーショナルコンポーネントには直接の動作テストが必要です。フックには制御された入出力が必要です。ナビゲーションには、現実的なほどのプロバイダーが必要です。ネイティブモジュールには、実際のデバイスの検証と比較できるように、モックが必要です。

モダンなノートパソコンと木の机の上に表示されたReact Native codeとモバイルアプリのモックアップ。

プレゼンテーショナル コンポーネント

コンポーネント テストをパブリック コントラクトに近づける

const onSelect = jest.fn();

render(
  <PlanCard
    title="Team"
    description="Shared workspace"
    onSelect={onSelect}
  />
);

fireEvent.press(screen.getByRole('button', { name: 'Choose Team' }));

expect(onSelect).toHaveBeenCalled();

UI の正確なラベルを使用する。重要なのは、ユーザーまたはアクセシビリティ サービスがコントロールを検出して、確認する必要がある可視またはコールバックの結果です。デフォルトでは、すべての子コンポーネントをモックしないでください。モックするのは、テスト対象の動作を隠すだけのコストの高いまたは無関係な境界のみです。

カスタム ホックの場合、使用する renderHook インストールされている RNTL のバージョンが提供する場合:

const { result } = renderHook(() => useSearch());

await act(async () => {
  await result.current.submit('query');
});

expect(result.current.status).toBe('success');

ホックのテストは、ネットワークまたはリポジトリの境界を制御する必要がありますが、全体のアプリケーションを再現する必要はありません。スクリーンを別々にテストすることで、ホックの状態が有用な UI になるかどうかを確認できます。

ナビゲーション動作の場合、実際の NavigationContainer と小さなテスト ナビゲータをレンダリングすることが、すべてのナビゲーション メソッドをモックすることよりも価値があります。表示されるコントロールを押して、目的地のコンテンツを待ち、assert する新しいスクリーンの出力を確認します。小さなボタンの場合、直接 useNavigation モックはまだ適切ですが、ルートの登録、パラメータ、またはネストされたナビゲータの動作を検証することはできません。

非同期データには同じ規則を適用してください。API またはリポジトリのレスポンスをモックするか、スクリーンをレンダリングし、ロード中の状態を確認し、リクエストを解決し、成功またはエラーの出力を確認します。 findBy 期待される最終的な要素のためのクエリを使用し、拒否されたリクエストを明確にし、テストがパスするのは、コンポーネントが意図した branch に到達しなかったからであることを確認することなく、テストを実行してください。

ネイティブモジュールのモック

AsyncStorage、パーミッション、カメラ、バイオメトリクス、プラットフォームAPIのモックは、決定論的JavaScriptテストに役立ちます。 しかし、ネイティブ機能が機能することを証明するものではありません。 モックの動作をモジュール契約に近づけ、テスト間で呼び出しをリセットし、成功パスをモデル化するのではなく、失敗応答を含めましょう。

シナリオ RNTLと組み合わせることが最も適しています。 E2E検証が必要です。
フォームのバリデーションと表示されるエラー はい 通常ではありません。
モックされたリポジトリからロード、成功、エラーのUI はい 重要な生産フロー
登録済みの画面間のナビゲーション Yes、テストナビゲーターとともに Yes、ジェスチャー、深いリンク、またはプラットフォームの動作が重要な場合
AsyncStorageの状態の決定 Yes、制御されたモックとともに Yes、起動とパERSISTENCEがネイティブのライフサイクルと相互作用する場合
カメラ、バイオメトリクス、パーミッション、またはプラットフォームのAPI JSのフォールバックとbranchingロジック Yes、実際のデバイスまたは代表的なデバイスで
レイアウト、レンダリングパフォーマンス、そしてネイティブのcode No Yes、デバイスまたは専門ツールとともに

境界は実用的です:依存性をモックしてJavaScriptの決定をテストし、次に実際の依存性の動作を確認するためにデバイステストを実行してください

テストの不具合を解決するCIとパフォーマンスのチェック

不具合のあるテストは、制御されていない時間、共有状態、またはUIと競合するアサーションを示します。タイムアウトを上げる前に、どの条件が存在するかを特定する必要があります。タイムアウトを長くすると、スケジューリングの問題を隠し、スイートを遅くすることになります。

使用 findBy 更新後に現れる要素の場合に使用します。 waitFor 状態条件またはモックコールの場合に使用します。偽のタイマーが有効になっている場合、インタラクションが必要なポイントでタイマーを進め、実際のタイマーをその後復元する必要があります。 act 警告は、Reactが予想外のインタラクション境界外で更新を観察したことを示しています。警告を抑制するのではなく、欠落しているユーザーインタラクション、またはタイマーフラッシュを修正する必要があります。 awaitCIの失敗を再現する

信頼できるCIジョブは、ロックファイルからインストールし、ローカルで使用しているJestコマンドを実行し、モック状態を分離します。テスト間でモックコールをクリアし、モジュールのモジュールレベルの状態が動作に影響する場合にモジュールをリセットし、実行順序に依存しないように依存関係を削除します。Jestキャッシングはフィードバックを速めるものの、依存関係または構成変更が適切なキャッシュ無効化を必要とする場合があります。

CIのみで失敗するテストには、コンポーネントのリライト前に環境の比較が必要です。Node、パッケージマネージャー、Jestワーカー設定、タイマー設定、環境変数を確認し、可能な限りローカルで同じコマンドを実行し、失敗するテストを最小限のインタラクションに減らして、差異を露呈するものにします。

オブザーバビリティは別のギャップをカバーします。React Native用のツールとして

Sentry を使用します。 モックされたコンポーネントのテストでは、実機とネイティブ統合に関連するエラーを再現できないため、生産エラーのコンテキストを提供します。

セキュリティ感覚のジャーニーには、2番目の境界が必要です。コンポーネントテストを使用して検証と状態の移行を実行し、次にデバイスレベルのカバレッジを追加してハンドオフとネイティブの動作をテストします。1回限りのcodeフローについては、 パフォーマンスを測定と主張と区別する integrationが旅の部分を形成する場合。

パフォーマンステストのドキュメント

CIやプルリクビューのための適切なレポートもカバーしています。 パフォーマンステストドキュメント 測定ルール:

機能テストは、動作が正しいかどうかを答えます。パフォーマンスツールは、測定されたシナリオが変化したかどうかを答えます。両方の質問を分離してください。

すべてを組み合わせて進めていきましょう 機能テストは、動作が正しいかどうかを確認します。パフォーマンスツールは、測定されたシナリオが変化したかどうかを確認します。両方の質問を分離してください。

すべてをまとめて進む

React Native Testing Libraryは、迅速なテスト戦略の幅広い層に属するものです。コンポーネントの動作、可視状態の変更、アクセシビリティの結果、検証、モックされたデータの状態、およびJavaScriptコンポーネント間の統合をカバーするべきです。ユーザーが観察できるテストに焦点を当て、失敗は特定の動作に指示するのではなく、大きなレンダリングツリーに指示するのではなく、テストを集中させます。

小さなデバイスベースの層は、モックが潜在的に存在するフローを保護するべきです。React Nativeの テストの概要 RNTLは完全なReact Nativeランタイムを提供せず、ネイティブ機能をテストできないことを示しています。同様のガイドラインは、認証、支払い、コアアプリの機能など、批判的なフローをカバーするために、コンポーネントテストをE2EツールであるDetoxと組み合わせることを推奨しています。

実践的な移行パス

既存のスイートを一度に書き直す必要はありません。

  1. 貴重なビジネステストを維持します。 純粋な状態とドメインロジックを、明確なフィードバックを提供する単位テストに移行します。
  2. 実装のアサーションを置き換えます。 プロパティと内部状態のチェックを、可視出力、アクセシビリティの状態、およびインタラクションの結果に変換します。
  3. スナップショットを縮小します。 レビュアーが理解し、維持できるスナップショットのみを保持します。
  4. ネイティブ境界カバレッジを追加する。 重要なモックされたモジュールごとに、まだ検証が必要なデバイスの動作を特定する。
  5. 重要なジャーニーを保護する。 認証、決済、コアナビゲーション、パーミッション、他にネイティブ動作が結果を変える可能性のあるフローで、E2Eカバレッジを追加する。
  6. 敏感な画面を個別に測定する。 リスト、フィード、費用の高いレンダリングパスで、Jestのdurationから推測するのではなく、繰り返しパフォーマンス比較を使用する。

リリースの信頼性を確保するには、スイートを接続してください。 正しい質問は、React Native Testing Libraryがあなたの全アプリをテストできるかどうかではない。実際にはできないし、公式の境界は役に立つ。正しい質問は、各重要なリスクが、リスクを露呈できる環境でテストが実行されているかどうかである。 Capgoは、CapacitorJSおよびElectronチーム向けに検証済みのJavaScriptおよびアセットの変更を制御された配信に接続し、ターゲットチャンネル、ロールアウトの可視性、ロールバック保護を提供する。Capgoを訪問する。

__CAPGO_KEEP_0__


Capgoは、CapacitorJSおよびElectronチーム向けに検証済みのJavaScriptおよびアセットの変更を制御された配信に接続し、ターゲットチャンネル、ロールアウトの可視性、ロールバック保護を提供します。 Capgo を確認するには、E2E、CIテストワークフローとともにコンポーネントに合わせてフィットさせる方法をご覧ください。

リアルタイム更新の Capacitor アプリ

ウェブ層のバグが生じた場合、Capgo を通じて修正を配信し、数日間待つ必要のないアプリストアの承認を待つ必要がなくなる。

マーティンから人間のサポートを受けます

スタートする

最新のブログ記事

Capgo は、プロフェッショナルなモバイルアプリを作成するために必要な最良の洞察を提供します。