メインコンテンツにジャンプします

JavaScriptのユニットテスト: 2026年の徹底ガイド

Unit test javascript をマスターする 2026 年のガイド。 Jest、Mocha、セットアップ、モッキング、CI、および Capacitor & Electron アプリ向けのTipsをカバーします。

JavaScriptのユニットテスト: 2026年版の徹底ガイド

あなたは現在、2つの状況のいずれかにいるかもしれません。JavaScriptプロジェクトがほとんどテストがなく、リファクタリングがリスキーな感じがする、またはすでにテストがあって半分以上が遅い、脆弱で、信頼できないように感じるものです。

それが Capacitor Electron Electron 良いユニットテストは、巧妙なマッチャーシyntaxで始まるのではなく、規則正しい境界から始まります。純粋な論理を直接テストし、副作用を分離し、内部関数をリネームするとテストが崩れるのを避けます。

__CAPGO_KEEP_0__

目次

JavaScript テストフレームワークを選択する

プロフェッショナルな JavaScript プロジェクトには、実際のテスト ランナーが必要です。アドホック スクリプトとマニュアルコンソール チェックは、複数のエンジニアが同じコードベースにアクセスする場合にスケールしないことがよくあります。テストの自動検出、断言、非同期処理、モック、CI とローカル開発で一貫して実行できる方法が必要です。

現在のガイドラインは、主流のオプションに収束しています。 Jest、Mocha、Jasmine は、主なフレームワークとして繰り返し強調されています。 Jest は、単一のパッケージ内にテスト構造、断言、モック、非同期サポートを備えていることがよくあります。 この.

Pluralsight JavaScript テスト ラボ

人気のある JavaScript テスト フレームワークの比較表、Jest、Mocha、Cypress、Playwright を含む。

フレームワークは必須です。なぜか?

フレームワークは共通言語を提供します:

  • テスト構造 と describe または test アサーション it
  • 読みやすいマッチャーと フック
  • Hooks 非同期サポート
  • プロミスとタイマーに対して モッキングツール
  • テスト構造 外部依存関係のための

あなたのチームがユニットレベルのテスト自動化の範囲を超えたテスト自動化のより広い視点が必要な場合、Capgoは便利な概要を提供しています。 アプリ配信ワークフローの自動テスト.

JestとMochaの比較

JestとMochaは異なる哲学を表しています。

Jest Jestは、チームが最初の日から必要なほとんどのものを含んでいます。
Mocha Mochaはモジュラーです。ランナーを提供し、残りのスタックを組み立てることを期待しています。

機能 Jest Mocha
セットアップの複雑さ ほとんどのチームでは低い 通常、アサーションやモッキングライブラリを追加するため、複雑
アサーション 組み込まれている 通常、別のライブラリと組み合わせる
モッキング 組み込まれている 通常、別のライブラリと組み合わせる
非同期テスト 組み込まれているし、直感的 サポートされているが、周囲のセットアップに依存する
カバレッジワークフロー 一般的に同じツールチェーンに統合される しばしば組み立てられる
ベストフィット 新規プロジェクト、統一性を求めるチーム 新しいプロジェクト、統一性を求めるチーム

古いスタック、モジュラー制御を求めるチーム 実用的なルール:

チームがアサーションライブラリとモッキングライブラリを組み合わせる必要がある場合、Jestを使用することをお勧めします。

私が推奨するのはほとんどのチーム Jest Jestを使用することをお勧めします。Mochaに既存の理由がある場合、コードベースがMochaにすでに強い理由がある場合、Jestを使用することをお勧めします。アプリケーションが含まれている場合、強く推奨されます。 Capacitor または Electronテストツールの多さは、既存のプロジェクトに混乱を招く。テストツールのスプラウルを削減すると、すぐに効果が現れる。

Capgoのコンサルティングサービスページです。ロール:セクションサブタイトルまたはタグライン。見つける場所:ページconsulting.astro。Capgoの製品/ブランド名と開発者用語をそのままにします。メッセージキー`consulting_faq_subtitle` (Consulting FAQ Subtitle)。

Appflowの比較/移行マーケティングコピーです。ロール:短いUIラベルまたはナビゲーションアイテム。見つける場所:ページalternatives/ionic-appflow.astro、ページionic-enterprise-plugins.astro、ページsolutions/ionic-enterprise-plugins.astro。メッセージキー`appflow_plugins_or` (Appflow Plugins Or)。

Electron

Electron

Electron

Electron

Electron package.jsonElectronはすでに多くの動的要素を持っているプロジェクトでは、テストツールのスプレッドを削減することはすぐに効果を発揮します。

{
  "scripts": {
    "test": "jest"
  }
}

多くのプロジェクトでは十分です。モジュールシステム、トランスパイル、またはモノレポ構造が必要な場合は、後で追加できます。

If you’re building a Capacitor app locally and want your dev environment in order before adding tests around shared logic, Capgo’s guide to setting up a Capacitor local environment ローカル環境の設定

テストを書く前にcodeを実装する

テストを書く前に テストの書き方は、個人的な好みだけではありません。米国消費者金融保護局のJavaScriptガイドラインでは、テストを最初に書くことを明示的に推奨しています。テストを書く describe テストを itテストを expect(...) テストを と.

テストから始めることは、設計方法を変える。codeの機能は小さくなり、依存関係は明確になり、純粋なロジックに影響を与える副作用は止まる。

ここに最小限の例があります。

// math.js
function addTax(amount, rate) {
  return amount + amount * rate;
}

module.exports = { addTax };
// math.test.js
const { addTax } = require('./math');

describe('addTax', () => {
  it('returns the amount with the tax applied', () => {
    expect(addTax(100, 0.2)).toBe(120);
  });
});

使用するのは、Arrange Act Assertのパターン。

The 入力と必要なセットアップを準備する。 関数を呼び出す。

  1. 結果を確認する。 結果を確認する。
  2. 結果を確認する。 結果を確認する。
  3. 結果を確認する。 結果を確認する。

適用される検証ヘルパー:

function isSupportedPlatform(platform) {
  return ['ios', 'android', 'web', 'desktop'].includes(platform);
}

describe('isSupportedPlatform', () => {
  it('returns true for ios', () => {
    // Arrange
    const platform = 'ios';

    // Act
    const result = isSupportedPlatform(platform);

    // Assert
    expect(result).toBe(true);
  });
});

小さなテストは長く生きる。テストは通常、1 つの質問に答えるようにするべきであり、全体のワークフローを語るべきではない。

Electron プロジェクトや Capacitor の場合、 code の純粋な論理がネイティブまたはデスクトップ統合に近い場合、規則をテストできるようにすることが重要です。プラットフォームの実行時間を除外し、最初のテストが最後の有用なテストになるようにします。

モックと非同期 Code のマスター

アプリケーション code の多くのバグは、2 つの数字を加算することから来るのではなく、 code が外部に到達することから来る。ネットワーク要求、ファイル、プラグイン API、タイマー、IPC チャネル、ストレージ レイヤーなどです。

モッキングは、境界を制御することで、テストが code の決定を焦点に置くことができるため、役立ちます。

API、データ ストア、外部サービス、イベント ドリブン データ フローを示す白板図。

境界をモックする

テストの可維持性を強調するガイドラインは 単一の行動のカバレッジ そして 強力な 1 つのアサーションごとにテストJavaScriptのユニットテスト TestRailの記事「保守可能なユニットテスト」.

JavaScriptでは、モックを多用するとテストが脆弱になり、実装の詳細に依存するようになることを警告しています。この

モックを多用したテストの悪い目標:

  • ヘルパーAがヘルパーBを呼び出したかどうか
  • サービスCがシリアライザーDを呼び出したかどうか
  • 内部のプライベート関数が2回実行されたかどうか

良い目標:

  • 関数が何を返したか
  • 依存関係が失敗したときに正しく処理されたかどうか
  • データを期待どおりに変形したかどうか

CapacitorとElectronのcodeの良いパターン

In mobile and desktop apps, I prefer a wrapper layer around native or platform APIs. Then unit tests mock the wrapper, not the platform itself.

例の構造:

// cameraGateway.js
async function getPhoto(cameraPlugin) {
  return cameraPlugin.getPhoto();
}

module.exports = { getPhoto };
// profilePhotoService.js
async function loadProfilePhoto(cameraGateway) {
  const photo = await cameraGateway.getPhoto();
  return { path: photo.path, ready: true };
}

module.exports = { loadProfilePhoto };
// profilePhotoService.test.js
const { loadProfilePhoto } = require('./profilePhotoService');

test('returns mapped photo data', async () => {
  const fakeCameraGateway = {
    getPhoto: jest.fn().mockResolvedValue({ path: '/tmp/pic.jpg' })
  };

  const result = await loadProfilePhoto(fakeCameraGateway);

  expect(result).toEqual({ path: '/tmp/pic.jpg', ready: true });
});

Electron にもそのパターンは機能します。Wrap ipcRenderer, ファイルアクセス、またはシェル統合を薄いアダプターの後ろに。ユニットテストはサービス層に当たりますが、実行時には直接当たりません。

リリースロジックとアップデートパスをテストするために、Capacitor アプリを使用するチームには、Capgo が関連するガイドを提供しています。 テストのシナリオをモックすることで、Capacitor のOTAアップデートをテストする方法についてのガイド.

チームがまだ非同期テストスタイルを標準化していない場合、簡単なウォークスルーが役立ちます:

非同期フローをテストする際にフラッキネスを避ける

Use async/await テストの場合、テスト対象のcodeがPromiseを返す場合、より明確でコールバックが多くないパターンになり、デバッグも容易になります。

async function fetchProfile(api) {
  const response = await api.getUser();
  return response.name;
}

test('returns the user name from the API response', async () => {
  const api = {
    getUser: jest.fn().mockResolvedValue({ name: 'Ava' })
  };

  const result = await fetchProfile(api);

  expect(result).toBe('Ava');
});

両方のパスをテストしてください。生産環境では、失敗パスはユーザーが思い出すパスです。

test('throws when the API request fails', async () => {
  const api = {
    getUser: jest.fn().mockRejectedValue(new Error('network failed'))
  };

  await expect(fetchProfile(api)).rejects.toThrow('network failed');
});

__CAPGO_KEEP_0__

高度なテスト戦略

テストスイートは、code の変更後でも有効なままになることが重要です。そうは簡単ではありません。

テストの包括的なカバレッジと、保守可能なテストスイートを通じて、堅牢なソフトウェアを構築するための戦略を示す図。

テストの分割を予算として使用する

1 つの実用的なガイドでは、 70/20/10 単体、統合、エンドツーエンドのテストを 単体テストは最速のフィードバックと最安定なエラーを提供します。同様のガイドでは、完全な単体テストスイートは理想的には10 秒未満で完了する 、そして、コミット前にチェックするには5 秒未満で完了する 、このに従う OpenReplayのテストガイド.

私はそれを予算管理ツールとして扱いますが、宗教ではありません。主な努力がエンドツーエンドテストに費やされると、チームはフィードバックを得るのに長い時間待つことになります。すべてがユニットのみの場合、システムの実際の境界を逃します。

CapacitorまたはElectronアプリの場合、健康的なバランスは通常以下のようになります:

  • ユニットテスト 価格ロジック、許可ルール、シリアライズ、更新の有効性、機能フラグ、状態変換のテスト
  • 統合テスト ストレージアダプタ、プラグインラッパー、IPCコントラクトのテスト
  • エンドツーエンドテスト ログイン、購入フロー、同期、または更新の促進のいくつかの重要なジャーニーのテスト

カバレッジはフラッシュライト、ターゲットではありません

カバレッジレポートは、重要なロジックの未テストブランチを発見するのに役立ちますが、チームがカバレッジパーセントを追求するためにカバレッジを追求する場合、有害になります。

ログインバリデーターに思いやりのあるエッジケーステストを実行すると、重要なUIの検証負荷を強化するチームにとって、カバレッジが高いファイルに多くの無駄なアサーションを含むことよりも価値があります。特に、入力が多いcode、例えばフォーム、パーサー、日付ロジック、許可チェックの場合です。このガイドは フロントエンドフォーム検証のマスター はユニットレベルのテスト戦略の良い補完です。

行動ベースのテストはリファクタリングを乗り越えます

信頼できるスイートは、内部のリファクタリングを行うと、半分のテストを書き直すことなく、テストを書き直す必要がなくなります。そこに到達する最も簡単な方法は、実装の詳細ではなく、観察可能な行動を主張することです。 観察可能な行動 頑丈なユースケースは次のとおりです:

境界条件

  • 空の入力、nullのような値、無効なタイプ、オーバーサイズの文字列など ドメインの結果
  • 例えば「許可が欠如しているため拒否される」 状態の移行
  • protectedTokens 例えば、 "ダウンロードメタデータが検証された後、マークを保留状態にします" など

よく腐る用途としては:

  • 内部ヘルパー呼び出しを検査する
  • プライベートメソッドのシーケンスを主張する
  • 呼び出しチェーンのすべての層をモックする

Disciplinedリリースプロセスを構築しているアプリチームにとって、Capgoの記事 "アプリの品質保証" は便利です。 CI、__CAPGO_KEEP_0__、およびElectronアプリのためのテスト テストが1人の開発者のマシン上のみ実行される場合、それは安全ネットではありません。ローカルな習慣です。

CIテスト、Capacitor、およびElectronアプリのテスト

環境の漂白が微妙なエラーを引き起こすElectronプロジェクトや__CAPGO_KEEP_0__プロジェクトにとっては、均一性はもっと重要です。

CI turns unit tests JavaScript work into team infrastructure. Every push, pull request, or release branch can exercise the same commands with the same expectations. That consistency matters even more for Capacitor and Electron projects, where environment drift causes subtle failures.

CIをデフォルトの実行パスに設定する

CIは、依存関係のインストールと単体テストの実行を、変更セットごとに実行する必要があります。可能な限り、ローカル開発と同じコマンドを使用してください。

GitHub Actionsワークフローは、以下のように簡単に実装できます。

name: test

on: [push, pull_request]

jobs:
  unit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - run: npm ci
      - run: npm test

これだけでも、インポートのエラー、断片的なアサーション、意図しないプラットフォームの仮定をメインに到達する前にキャッチできます。

自動化されたパイプラインを通じてモバイルチームが配信する場合、CapgoはCapgoアプリのCI/CDの設定に関する実用的なガイドを提供しています。 Capacitor プラグイン間のテスト.

Testing Capacitor plugin interactions

The wrong way to unit test Capacitor code is to pull native plugins directly into every service. That couples your test suite to the platform bridge.

ベストプラクティスは、薄い抽象化です。

// deviceStorage.js
async function saveFile(filesystem, path, data) {
  return filesystem.writeFile({ path, data });
}

module.exports = { saveFile };
// draftService.js
async function persistDraft(storage, draft) {
  await storage.save('draft.json', JSON.stringify(draft));
  return { saved: true };
}

module.exports = { persistDraft };
// draftService.test.js
const { persistDraft } = require('./draftService');

test('persists a serialized draft', async () => {
  const storage = {
    save: jest.fn().mockResolvedValue(undefined)
  };

  const result = await persistDraft(storage, { title: 'Hello' });

  expect(result).toEqual({ saved: true });
});

__CAPGO_KEEP_0__

Testing Electron main renderer and IPC code

__CAPGO_KEEP_0__ code と レンダラープロセス code. テストではぼやけさせないようにしてください。

信頼できるセットアップは通常、以下を分離します。

  • レンダラー単体テスト ビュー モデル、状態、フォーマット、UI側のビジネス ロジック
  • メイン プロセス単体テスト メニュー、ファイル操作、アプリ ライフサイクル決定
  • IPC契約テスト メッセージの形状と期待される応答

例のIPCラッパー:

// ipcGateway.js
function sendSettings(ipcRenderer, payload) {
  ipcRenderer.send('settings:update', payload);
}

module.exports = { sendSettings };
// ipcGateway.test.js
const { sendSettings } = require('./ipcGateway');

test('sends settings update over ipc', () => {
  const ipcRenderer = { send: jest.fn() };

  sendSettings(ipcRenderer, { theme: 'dark' });

  expect(ipcRenderer.send).toHaveBeenCalledWith('settings:update', { theme: 'dark' });
});

内部実装を1つのヘルパーから別のヘルパーに変更した場合、このテストは依然として有効です。なぜなら、重要な動作を検証しているからです。デスクトップとモバイルの両方でこの標準を維持したいです。 code

JavaScript単体テストに関するよくある質問

単体テスト、統合テスト、E2Eテストの違い

A 単体テスト 単一の論理的小さな部分を孤立してチェックする。 単体テストはビジネスルールの迅速な信頼に使用します。統合テストは、ストレージ、プラグインラッパー、IPCなどのシームに使用します。E2Eテストは、壊れた場合に大きな影響を与えるワークフローに限り、慎重に使用します。 完全なカバレッジを目指すべきか いいえ。完全なカバレッジはチームを低価値のテストに導く可能性があります。 単体テスト

単体テストは、1つの小さなロジックを孤立してチェックします。

統合テスト

統合テストは、複数のコンポーネントやサービスが正しく動作するかどうかをチェックします。

カバレッジは、リスクのあるcodeを明らかにするときに役立ちます。誰もが実行していないところです。エンジニアがダッシュボードを満たすために浅いアサーションを追加するだけのときは役に立ちません。スイートが脆弱であれば、カバレッジが増えてもそれを救うことはできません。

既存のコードベースにテストを追加する方法はどれですか

変更がすでに発生しているところから始めましょう。チームを凍らせて、テスト戦略の大きなリライトを発表する必要はありません。

実践的なシーケンスは次のようになります。

  • アクティブなcodeを保護することから始めましょう 機能開発やバグ修正の際に触れるモジュールにテストを追加すること
  • 純粋なロジックを抽出すること ビジネスルールをフレームワークや実行時ノイズからテストできるようにする
  • ネイティブプラグイン、ネットワーククライアント、ファイルシステム呼び出し、Electron IPCにシームワッパーを追加すること 脆弱なパターンを拒否すること
  • ガイドラインは refuse JavaScript テストのベスト プラクティス 特に、過度のモッキングとその結果の脆弱なテストを強調することで、ここでは特に有用です。

目標は即時的な完全性ではなく、最もチームにコストがかかる場所での安定した改善です。


チームがリリースする場合 Capacitor or Electron Capacitor のライブ アップデートの代替オプションを比較するページです。 Capgo Capacitor のライブ アップデートの代替オプションを比較するページです。

Live updates for Capacitor apps

When a web-layer bug is live, ship the fix through Capgo instead of waiting days for app store approval. Users get the update in the background while native changes stay in the normal review path.

最新のブログ記事

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