__CAPGO_KEEP_0__ホーム

Unit Testing React: A Practical End-to-End Guide

Reactのユニットテストをマスターする。Jest、RTL、hooks、非同期code、モッキング、CI/CDのためのベストプラクティスを網羅するガイドです。

マーティン・ドナディュー

マーティン・ドナディュー

コンテンツマーケター

Unit Testing React: A Practical End-to-End Guide

昼食前、UIの小さな変更をプッシュします。見た目は無害です。ボタンのラベルが変更され、条件付きレンダリングが簡略化され、ヘルパーホックが新しいbranchを取得します。プルリクエストはクリーンで、レビューは速く、デプロイは正常に進みます。

1時間後、サポートは1つのプラットフォームでログインが機能しないことを報告します。Webは正常です。デスクトップシェルには古いレンダリングパスがあります。モバイルビルドは非同期状態の変更後異なる動作をします。誰も気づかなかったのは、codeがテストされていたからです。しかし、正しいテストは実行されていませんでした。テストの信頼性のあるシステムもありません。

Reactのプロダクションチームでのユニットテストの主な問題は何ですか。少数のテストを書くことは簡単ではありません。リファクタリング、リリーストレイン、ホットフィックス、クロスプラットフォームパッケージングを含む、まだ保護することができるテストスイートを構築することは難しいことです。 render()Reactアプリケーションは、チームが呼び出す方法を忘れたためではなく、テストが実装詳細に近づき、非同期動作が隠蔽され、CIがテストをチェックボックスとして扱うため、失敗します。

モダンなユニットテストのReactは、安全システムのように振舞うときに機能します。ローカルで迅速なフィードバック。CIで決定論的なチェック。単位テストとテストしないものの境界が明確です。そのことのほうが重要です。同じReactコードベースはブラウザ、Capacitor コンテナ、またはElectronシェルを通じて配信されます。

目次

React のユニットテストは、安全の網として機能する

code で、ユーザーが依存している動作が変化した場合、ユニットテストはそのミスをキャッチする

ユニットテストは、ユーザーが依存している動作が変化した場合にのみ、ミスをキャッチする __CAPGO_KEEP_0__ で、ユーザーが依存している動作が変化した場合、ユニットテストはそのミスをキャッチする__CAPGO_KEEP_0__ のテストは、内部構造に依存するテストではなく、ユーザーが見える動作に依存するテストに移行した React Native のテストガイドライン. That shift matters because React code gets rearranged constantly. Hooks move. components split. Context gets introduced. A test tied to internal structure breaks during healthy refactors. A test tied to visible behavior usually survives.

単位テストは何を保護するべきか

良いReact単位テストは、1 つの小さな契約を保護します:

  • レンダリングされた出力: ユーザーは正しいテキスト、ラベル、状態、またはフォールバックを見るか?
  • インタラクションの動作: クリック、入力、または切り替えがUIを正しく変更するか?
  • 境界の処理: コンポーネントは、予想される入力、欠落したデータ、またはエラーのパスを受け取ったときに正しく動作するか?

弱いテストは間違ったものを保護します:

  • コンポーネントの内部: 状態の形状、プライベートメソッド、実装専用のプロパティ
  • フレームワークのメカニズム: 内部では正確にどのようになりましたか?
  • 子要素の詳細: ここでは確認したくないネストされたコンポーネントが所有するマークアップ

実用的なルール: ユーザーが見たり行うことができるものの変更が必要ない場合、コンポーネントをリファクタリングするだけでテストも変更する必要がない

ユニットテストもより広いテストシステムの中に位置しています。全体のアプリケーションがエンドツーエンドで動作することを証明することを目的としたものではありません。ブラウザレベルテストやデバイスレベルバリデーションパスまで遅い層が負担を増やすのを防ぐために、速い層として機能します。 自動テストのための生産アプリケーションの任意の合理的なスタックの最初の防衛線.

Reactチームが頻繁にリリースする場合、信頼性は労働の分割によって得られます。ユニットテストはローカルなバグを迅速に検出します。統合テストはシームズを検証します。エンドツーエンドテストは重要なパスを確認します。ユニット層をスキップすると、すべての下流のスローダウン層が過度に負担を増やすことになります。

モダンなReactテスト環境の設定

フラッキーテストが生じる前に、単一のアサーションを書く前にテスト環境が脆弱であることは、多くの開発者が認識しています。Jest、jsdom、またはReactを非難するのは、CIとローカルマシン間で一貫した構成が欠如していることが原因です。対処法は、環境を面白くなくすることです。面白くないことはここでは良いことです。

A clean workspace featuring a computer monitor displaying React unit testing code in a code editor.

予測可能なランナーと環境から始めましょう

現代のReactアプリケーション、特にViteで作成されたものの基本的なセットアップには、以下が含まれるべきです。

  • テストランナー: Jestは、古いReactコードベースやエンタープライズCIスタックでよく使用されます。
  • ブラウザのような環境: jsdom コンポーネントテストでDOM出力をレンダリングすることができます。
  • テストライブラリのユーティリティ: @testing-library/react そして @testing-library/jest-dom
  • 単一のセットアップエントリポイント: マッチャーとグローバルモックを登録するファイル

Reactのテストガイドラインが強調する主なワークフローは単純です: jsdom-backed環境でコンポーネントをレンダリングし、 getByText または getByRole, インタラクションをトリガーし、DOMの変更を確認します。 React テストドキュメント. そのワークフローは、すべてのマシンが同じテスト環境を実行する場合にのみ信頼できます。

実用的な Jest セットアップは、以下のようになります:

// jest.config.js
module.exports = {
  testEnvironment: 'jsdom',
  setupFilesAfterEnv: ['<rootDir>/src/setupTests.js'],
  moduleNameMapper: {
    '\\.(css|less|scss)$': 'identity-obj-proxy',
    '^@/(.*)$': '<rootDir>/src/$1',
  },
  transform: {
    '^.+\\.(js|jsx|ts|tsx)$': 'babel-jest',
  },
};

あなたのチームが SWC を Babel の代わりに使用している場合、それでも問題ありません。トランスフォーマーではなく、consistency がポイントです。リポジトリで 1 つのパスを標準化し、望む場合、より広範な JavaScript テスト規則の参考資料として、Capgo の JavaScript のユニットテストガイド は、より広範な JavaScript テスト規則の参考資料として、チーム間のドキュメントとして役立ちます。

スイートが依存するセットアップファイルを追加します

適切な setupTests.js は、繰り返されるノイズを多く削減します:

import '@testing-library/jest-dom';

Object.defineProperty(window, 'matchMedia', {
  writable: true,
  value: jest.fn().mockImplementation(query => ({
    matches: false,
    media: query,
    onchange: null,
    addListener: jest.fn(),
    removeListener: jest.fn(),
    addEventListener: jest.fn(),
    removeEventListener: jest.fn(),
    dispatchEvent: jest.fn(),
  })),
});

このファイルは、テストファイル 20 個にわたって環境のギャップを解決するのではなく、1 回だけ解決します。API に依存する UI に対してモックを追加します、例えば、 matchMedia, ResizeObserver、または IntersectionObserver、もしコンポーネントライブラリがそれらを必要としている場合

開発者はグローバルを手動で修正するので、不一致のテストと追跡が困難なエラーが生じます。 一人の人のローカル実行はパッチが共有されていないため、CIは失敗します。

ローカルとCIの動作を同期させる

ローカルコマンドはCIコマンドとできる限り同じように動作するようにする。 開発者がwatchモードで緩い設定で実行している場合、CIは厳しい設定で実行されるため、merge後に驚く失敗が発生します。 スクリプトは明示的に記述する

{
  "scripts": {
    "test": "jest",
    "test:watch": "jest --watch",
    "test:ci": "jest --runInBand --coverage"
  }
}

新しいチームメンバーが同じ基準を早く取得するのに役立つ短いウォークスルー

最も影響力のある設定の選択は、デフォルトの規則を守ることです。 アリアスはconfigに記述し、環境モックは1つの設定ファイルに記述し、可能な限りUIテスト用に軽い環境を使用し、純粋なユーティリティ用に軽い環境を使用します。 各テストが必要とするカスタム動作が少ないほど、システムの信頼性が高まります。 jsdom 意味のあるコンポーネントテストの書き方

組織はテストを書くことができるのですが、6か月後にまだ意味があるテストを書くことができないのです。

Reactコンポーネントのユニットテストの標準パターンはまだ正しいです。

コンポーネントをレンダーし、ユーザー中心のセレクターでUIをクエリし、イベントをトリガーし、結果のDOMの変更をアサートする 実装詳細であるstateやpropsに依存しないようにする、Reactのテストガイド __CAPGO_KEEP_0__. パターンを適切に制限する鍵は何か。

ユーザーがアコーディオンを使用するようにテストしてください。

基本的なコンポーネントを使用してください。 それがボタンとタイトルをレンダリングします。 パネル コンテンツは非表示で始まります。 ボタンをクリックするとコンテンツが表示され、可視性の状態が更新されます。 Accordion それがいくつかの有用なテストのための十分な動作です:

初期レンダリングではタイトルが表示されますがコンテンツは表示されません。

  1. トリガーをクリックするとコンテンツが表示されます。
  2. クリックすると折りたたまれます。
  3. 可視性の属性は表示状態を反映しています。
  4. 最後の点はよく見落とされます。 コンポーネントが使用する場合、または役割に基づく構造、確認してください。 それは実装の詳細ではありません。 それはユーザー向けの契約の一部です。

最良のコンポーネント テストは、受けたいことのないバグ レポートのように読みます。 aria-expanded, aria-controls__CAPGO_KEEP_0__

__CAPGO_KEEP_0__

意図に基づいてクエリを選択する

React Testing Libraryでは、複数のクエリスタイルが提供されますが、互換性はありません。間違ったスタイルを選択すると、テストが雑になり、誤解を招くことになります。

クエリタイプ 要素が見つかった場合 要素が見つからない場合 使用例
getBy 要素が即座に返却される 即座にエラーを投げる ボタンやヘッダーがすでに画面上に表示されていることを確認する
queryBy 要素が即座に返却される 返却 null 非表示のコンテンツがインタラクション前に存在しないことを確認する
findBy Resolves when the element appears Rejects after waiting Assert async-loaded content appears after a fetch or delayed update

A simple mental model helps:

  • Use getBy for things that must already exist.
  • Use queryBy for things that must not exist yet.
  • Use findBy when the UI changes later.

If a test starts with findBy for everything, it usually means the author isn’t sure when the component updates. That uncertainty becomes flakiness later.

実用的なアコーディオンの例

ここには代表的なコンポーネントがあります:

function Accordion({ title, children }) {
  const [open, setOpen] = React.useState(false);

  return (
    <section>
      <button
        aria-expanded={open}
        aria-controls="accordion-panel"
        onClick={() => setOpen(prev => !prev)}
      >
        {title}
      </button>
      {open ? (
        <div id="accordion-panel">
          {children}
        </div>
      ) : null}
    </section>
  );
}

ここにはテストの形が残っています:

import { render, screen, fireEvent } from '@testing-library/react';

test('renders the accordion title and hides content initially', () => {
  render(<Accordion title="Shipping details">Delivery takes 3 days</Accordion>);

  expect(screen.getByRole('button', { name: /shipping details/i })).toBeInTheDocument();
  expect(screen.queryByText(/delivery takes 3 days/i)).not.toBeInTheDocument();
});

test('reveals content when the trigger is clicked', () => {
  render(<Accordion title="Shipping details">Delivery takes 3 days</Accordion>);

  fireEvent.click(screen.getByRole('button', { name: /shipping details/i }));

  expect(screen.getByText(/delivery takes 3 days/i)).toBeInTheDocument();
});

test('updates aria-expanded when opened', () => {
  render(<Accordion title="Shipping details">Delivery takes 3 days</Accordion>);

  const button = screen.getByRole('button', { name: /shipping details/i });
  expect(button).toHaveAttribute('aria-expanded', 'false');

  fireEvent.click(button);

  expect(button).toHaveAttribute('aria-expanded', 'true');
});

欠けているものも重要です。内部状態に対するアサーションがない。呼ばれたかどうかのチェックがない。レンダリングされた全体のスナップショットがない。そういったテストはメンテナンスを増やしますが、信頼性は増えない。 setOpen コンポーネントのテストを強くする習慣が数つかっている:

ロールベースのクエリを優先する:

  • ボタン、ヘッダー、ダイアログ、警告、入力欄は通常はロールで見つけるべきです。 各テストを狭くする:
  • ユーザーが見える動作ごとにテストを一つずつ行うことで、エラーが読みやすくなる。 テストの名前を結果に合わせる:
  • Name tests after outcomes: updates aria-expanded when opened

DOM経由でテストが困難なコンポーネントは、設計上の問題を示唆していることが多い。状態を間違った場所に隠しているかもしれない。意味のあるマークアップが不足しているかもしれない。良いテストは、チームをより良いコンポーネントに導くことが多い。

カスタムフックとアプリケーションロジックのテスト

Reactアプリは、コンポーネント外に重要な動作を隠している。状態の移行はフック内にあり、検証とフォーマットはヘルパー関数内にあり、データの形成はレンダリングされる前に発生することが多い。可視性のあるコンポーネントのみをテストすると、生産環境の動作を破壊する可能性のある大量のcodeを無視することになる。

フックはReactに対応したハーネスが必要

カスタムフックは、適切に実行するためにReactが必要なので、 renderHook 状態を変更する呼び出しをwrapする act().

小さな useToggle フックは、

import { useState, useCallback } from 'react';

export function useToggle(initialValue = false) {
  const [value, setValue] = useState(initialValue);
  const toggle = useCallback(() => setValue(current => !current), []);
  return { value, toggle };
}

そのテストは、

import { renderHook, act } from '@testing-library/react';
import { useToggle } from './useToggle';

test('returns the initial value', () => {
  const { result } = renderHook(() => useToggle(true));
  expect(result.current.value).toBe(true);
});

test('toggles the value', () => {
  const { result } = renderHook(() => useToggle(false));

  act(() => {
    result.current.toggle();
  });

  expect(result.current.value).toBe(true);
});

そのテストは有用である。フック自体が単位であるため、Reactの内部をテストするのではなく、フックの外部動作を検証している。

製品チームが再利用可能なUIまたは機能原子を構築している場合、このパターンは非常に重要である。フックはアプリ、デザインシステム、または内部ツール間で共有されるインターフェイスになることが多く、商用目的で再利用可能な動作を設計している場合、 フックのためのメーカーの製品のリソース は、フックを製品化された構築ブロックとしてではなく、実装の詳細として扱うのに役立ちます。

純粋な論理は、テストで純粋に残すべきです

すべてが、React、またはテスト ライブラリが必要ではない jsdom純粋な関数は、Node 環境で単純な Jest でテストする

例えば

export function formatDisplayName(firstName: string, lastName: string) {
  return `${firstName.trim()} ${lastName.trim()}`.trim();
}

そのテストは、非常に簡単でなければなりません

import { formatDisplayName } from './formatDisplayName';

test('joins and trims both names', () => {
  expect(formatDisplayName(' Ada ', ' Lovelace ')).toBe('Ada Lovelace');
});

test('handles a missing last name', () => {
  expect(formatDisplayName('Ada', '')).toBe('Ada');
});

ここでの勝ちは、速度と明確さです。関数がレンダリングされた木が必要ない場合、レンダリングされた木を与えないでください。 React のツールはオーバーヘッドを追加します。ビジネス ロジックのテストは、小さく、速く、関数を検証する近くに保ちましょう。

実用的には、以下の分割がうまくいきます

  • フック: 必要に応じて、 renderHook, act()とラッパー プロバイダーを使用します。
  • ユーティリティ: Jestを使用し、DOMを使用しない。
  • 状態を保持する横断的ロジック: コンポーネントテストがロジックのアサーションを多く含むようになると、テストを実行できるヘルパーにロジックを引き出すことができます。

チームは、ロジックのアサーションが下のレベルに属しているのに、コンポーネントテストに多く含まれていることがよくあります。ロジックを引き出すことで、2つの利点が得られます。コンポーネントテストが綺麗になり、ロジックテストが速くなります。

高度なテクニックをマスターする:モッキングと非同期

ほとんどのReactのテストスイートは、依存関係の境界と時間に関連する2つの場所で破損します。

これは、非同期テストとモッキングが、玩具のテストスイートと信頼できるリリース前のテストスイートの境界線であるという理由からです。 1つの分析では、46.5%のテストの不安定性が環境またはリソースに関連する問題であるとされています。たとえば、非同期タイミング このReactのユニットテスト分析 Reactアプリケーションでは、これは直接状態の遷移、遅延したレンダリング、ネットワークドライブのUI、そして待ち合わせるのではなく、決定的に待ち合わせるテストにマップされます。非同期テストとモッキングを特に、高度なReactテストテクニックの比較チャート

__CAPGO_KEEP_0__

境界を模倣せよ、すべての層ではない

ミスリーディングのテストを書く最速の方法は、半分のコンポーネントツリーをモックし、自分のモックが機能したことを確認することだ。

アカウントデータを取得するコンポーネントの場合、ネットワーククライアントまたはAPIモジュールをモックする。ホック、子要素コンポーネント、ローディングスピナー、3つのユーティリティ関数をモックしない。テストが実際に隔離が必要な場合は除く。

このルールセットを使用する:

  • 外部サービスをモックする: HTTPクライアント、アナリティクス、ブラウザのみAPI、ネイティブブリッジ
  • 不安定なプラットフォームAPIをモックする: matchMediaタイマー、Electronプレロードインターフェイス、Capacitorプラグイン(JavaScriptDOMで利用できない場合)
  • デフォルトでは自分の内部をモックしない: カスタムホック、シンプルな子要素、ローカルユーティリティ

すべての難しい部分を偽物に置き換えたテストがパスした場合、リリースの信頼性が高まることはない。

ランナーAPIの例とパターンを提供したいチーム向けに、Capgoを参照する Jest カテゴリ __CAPGO_KEEP_0__は、特にReactを学んでいる開発者がテストメカニズムをまだ知らない場合に、実用的なリファレンスライブラリです。

タイミングが曖昧な場合、非同期テストは失敗します。

非同期テストの失敗は、通常、次の3つの間違いから来ます。

  1. テストが早すぎます。
  2. テストが任意のタイマーで待機しています。
  3. コンポーネントが更新し、テストが1つのトランジションのみをモデル化している場合。

安定した非同期テストは、通常、この形を持ちます。

test('shows user details after data loads', async () => {
  render(<UserProfile userId="42" />);
  expect(screen.getByText(/loading/i)).toBeInTheDocument();

  expect(await screen.findByText(/account owner/i)).toBeInTheDocument();
});

または、特定の条件を待つ必要がある場合。

await waitFor(() => {
  expect(screen.getByRole('alert')).toBeInTheDocument();
});

使用してください。 findBy 使用してください。 waitFor 避けるべきです。 setTimeout テストの場合、タイマーの動作を明示的にテストしていない限り、タイマーを偽装する必要があります。

Reactのテスト環境では、更新の意味合いを尊重することを期待されています。 act() Testing Libraryはこれらの問題の多くを解決しますが、状態を手動で操作したりタイマーを進めたりする場合は、更新がフラッシュするタイミングを考慮する必要があります。

どのモックツールを使用するかを知る

異なるモックツールは異なる問題を解決します:

ツール 最良の使用方法 一般的な誤用
jest.fn() スタンドアロンで偽装されたコールバックまたはインジェクションされた関数 単純なコールバックが十分である場合に、モジュール全体を置き換える
jest.spyOn() 実際のオブジェクトまたはモジュールの1つのメソッドを観察またはオーバーライドする 元の実装を復元することを忘れる
jest.mock() モジュール依存性をインポート境界で置き換える デフォルトで大規模モジュールをモックし、意味のある動作を失う

例は次のようになります:

  • 「__CAPGO_KEEP_0__」を使用する jest.fn() コンポーネントがプロパティを受け取る場合に使用します。 onSubmit 「__CAPGO_KEEP_0__」を使用する
  • ストレージ方法を検証する場合や、エクスポートされた__CAPGO_KEEP_0__コールを検証する場合に使用します。 jest.spyOn() 「__CAPGO_KEEP_0__」を使用する console.errorモジュールをインポートする場合にI/O、ネイティブAPI、またはユニット境界を超える動作が発生する場合に使用します。
  • エラー パス テストは、現代の React で多くのガイドが不足している一つの高度な領域です。エラー バウンダリー、遅延した状態の変更、非同期のフォールバック UI に対して、最初のクラス テストが必要です。子要素が例外を投げた場合、フォールバック UI をアサートします。要求が失敗した場合、表示される回復状態をアサートします。ロード中のボタンが無効になっている場合、も同様にアサートします。ユーザーが思い出すのはそのようなバグです。 jest.mock() code

__CAPGO_KEEP_0__

{

targetLanguage":"Japanese",

protectedTokens":["Cloudflare","Capacitor","GitHub","Capgo","code","API","SDK","CLI","npm","bun"]

,

texts":[

"Improving Test Quality and Strategy","","A lot of teams still chase coverage like it’s the same thing as confidence. It isn’t.",

"You can hit a coverage target and still miss the regressions that matter. A suite full of shallow assertions, broad snapshots, and mocked internals creates the appearance of safety while also increasing maintenance cost.",

"An infographic comparing the benefits of quality testing versus the maintenance overhead of high-quantity test suites.",

  • "Coverage is a map, not the goal"," "Coverage reports are useful when they answer one question: which critical paths have no protection yet?",
  • "They’re not useful when they push developers into testing trivial wrappers, static markup, or one-line pass-through files just to move a percentage. Treat coverage as a discovery tool. If authentication state, billing actions, feature flags, or update prompts have no tests, that’s a signal. If a presentational icon component has no tests, that usually isn’t.", "A healthy review question is simple: does this test reduce release risk?","","Yes:","It verifies user-visible behavior on a critical path.","Maybe:","It protects business logic that’s easy to break during refactor."}
  • No: __CAPGO_KEEP_0__

ユーザー体験が壊れるのにパスするテストケースを作らないようにする

Reactのユニットテストについて 多くのReactのガイドでは、省略について十分に時間を割いていない。 そのギャップは重要である。 これは、BrowserStackのReactのユニットテストについてのガイドで説明されているように、オーバーモッキングと実装詳細のテストが、ユーザー体験が壊れるのにパスするテストケースを作ることになる。.

これらのパターンをスキップまたは厳格に制限する:

  • 内部状態のアサーション: 直接テストしないようにする。 例えば、パネルが開いたかどうかをテストする。 isOpen フレームワークの動作:
  • Reactがエフェクトを呼び出したかどうかをテストしない。 そのエフェクトが何を変えるかをテストする。 第三者ライブラリの内部:
  • __CAPGO_KEEP_0__ 日付ピッカーまたはルーターと統合するには、ライブラリのレンダリングロジックではなくテストする必要があります。
  • 過度に分割されたユニット: すべての子やヘルパーをモックした場合、意味のある動作をテストできなくなります。

テストが機能しないまま、リファクタリングをブロックし、実行時エラーを検出できなくなるテストは、欠陥のあるテストです。

境界の所有権という便利なヒューリスティックを使用すると役立ちます。codeが所有するものをテストし、React、ブラウザ、または成熟したライブラリが既に所有しているものは、統合層が契約を変更しない限りテストしないでください。

スナップショットの役割と欠点

スナップショットは無駄ではありません。ただし、簡単に誤用される可能性があります。

構造的な差分が意味をなす、安定したシンプルな出力を持つコンポーネントでは、スナップショットをsparingly使用してください。インタラクティブなコンポーネントや高度に動的なコンポーネントでは、ノイズになります。開発者は読みにくくなり、自動的に更新するようになります。

代替案がよくあります:

  • 条件付きレンダリングの場合、指定されたキーテキストの存在または非存在を確認してください。
  • 視覚的な状態の変更の場合、重要な役割、ラベル、または属性を確認してください。
  • エラーとフォールバックの場合、実際のメッセージまたは警告領域を確認してください。

If your team needs a broader quality process beyond unit tests, a solid companion is an アプリの品質保証ワークフロー that treats tests, release checks, and rollback planning as one system. That’s the mindset shift that improves test quality fastest. Stop asking how many tests you have. Start asking which failures could still reach users.

クロスプラットフォームCI/CD Pipeliningにおけるテストの統合

A test suite that only runs on a developer laptop is a suggestion, not a control.

テストスイートは、開発者用のノートパソコン上で実行される場合、提案であり、制御ではありません。

The suite becomes operational when every pull request runs the same checks in a clean environment and blocks merges when those checks fail. That sounds obvious, but many teams still leave critical gaps. Tests run manually. Coverage reports are optional. Packaging and release jobs start before test jobs have finished. That’s how small UI regressions slip into bigger release failures.

CI/CD開発パイプラインにReact自動テストを統合するプロセスの5ステップのフローチャート

A pull request should trigger the same gate every time

  • Reactの単体テストを安全なネットとして機能させるには、CIにはいくつかの基本的な要素が必要です:
  • Pull Requestごとに実行
  • ロックファイルから依存関係をインストールすること
  • テスト失敗時速い
  • テストが通るまでアーティファクトを公開しない

これは アプリチーム向けのリリース前に信頼を築く、ではなくリリース後に

多くのチームにとって、シンプルなGitHub Actions ワークフローが十分です:

name: test

on:
  pull_request:
  push:
    branches:
      - main

jobs:
  react-tests:
    runs-on: ubuntu-latest

    steps:
      - name: Check out code
        uses: actions/checkout@v4

      - name: Set up Node
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm

      - name: Install dependencies
        run: npm ci

      - name: Run unit tests
        run: npm run test:ci

これは、凝ったものではないことを意図しています。最も強力なパイプラインは、通常、最も驚くことのないものです。

これがCapacitorとElectronにとってより重要な理由

クロスプラットフォームのReactアプリは、ブラウザのみのアプリよりもリリースリスクが高い。同じUIcodeは、異なるコンテナに異なる実行環境の仮定で配信されることが多い。

いくつかの例は、パイプラインがどのように役立つかを示しています。

  • Capacitorアプリ: Webcodeはローカルで通るかもしれませんが、プラグインブリッジ、オフライン状態、またはアプリライフサイクルエッジケースがパッケージング後に動作を変更すると失敗します。
  • Electronアプリ: レンダラー コンポーネントは、プレロード API、ウィンドウ メッセージング、またはデスクトップ専用の状態に依存する可能性があります。これらは、意図的にモックされていない場合、平凡なブラウザ テストでは存在しません。
  • 共有リリーストレイン: 1 つの不正なバンドルが、デプロイメント プロセスが厳密にパブリケーションをゲートしていない場合、複数のターゲットに影響を与える可能性があります。

したがって、パッケージング ジョブが実行される前に、ユニット テストが実行されるべきであり、パッケージング ジョブが実行される前に、ディストリビューション ジョブが実行されるべきです。各ステージはリスクを縮小します。ユニット テストはローカルなバグを迅速に検出します。プラットフォーム パッケージングは環境の仮定を検証します。最終リリースの信頼性は、手動の承認またはステージド ロールアウトで管理されます。

実践的なGitHub Actions ワークフロー

より成熟したパイプラインは、責任を分割します。

  1. テストジョブ: 迅速なユニット テストとハック テスト
  2. ビルドジョブ: テストが成功した後のみ、プロダクション ビルド
  3. パッケージングジョブ: Capacitor 同期、Electron パッケージング、またはアーティファクト バンドリング
  4. リリースジョブ: 承認されたブランチまたはタグのみから公開

チームがリアルタイムで更新を Capacitor または Electron アプリを配信する場合、リリースツールはここで重要になります。ワークフローにおける 1 つのオプションは、 Capgo,

がCapacitorJSとElectronアプリの署名Webバンドルを公開し、ロールバックサポートとチャンネルベースのロールアウト制御を提供します。実際には、Reactテストジョブは、Webバンドルがステージングまたはプロダクション配信に進む前に最初のハードゲートとして機能します。

運用ルールは簡単です。リリースインフラが弱いテストを補うのを許すな。信頼できるテストがすでに悪い変更をフィルタリングした後、リリースインフラを使用する。信頼できるテストシステムはチームの行動を変える。エンジニアはマージに少しあまり気を付ける。レビュアーはエッジケースに焦点を当てるのではなく、基本的なものを手動で再実行するのではなく。リリースマネージャは、毎回のデプロイを賭けのように扱うのをやめる。そうでなければ、Reactを単位テストでよく行うことの結果である。


チームがReactを Capacitor または Electronで配信する場合、リリースの安全性はグリーンなローカルテストだけに依存しない。 Capgo ,

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

Capgo を使用して、ウェブ層のバグが生じた場合、修正をアプリストアの承認待ちの日数を待たずに配信する。ユーザーはバックグラウンドで更新を受け取り、ネイティブの変更は通常のレビュー経路で残る。

スタートする

ブログの最新記事

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