# Jest テスティングフレームワーク 業務運用マニュアル

## 目次

**【基本操作】**
1. [システム概要](#1-システム概要)
2. [セットアップ手順](#2-セットアップ手順)
3. [基本的なテスト実行](#3-基本的なテスト実行)

**【業務フローに沿った機能】**
4. [【STEP1】テストの作成（テストコードの記述）](#4-step1テストの作成テストコードの記述)
5. [【STEP2-3】テストの実行と検証（アサーション・モック）](#5-step2-3テストの実行と検証アサーションモック)
6. [【STEP3-4】スナップショットテスト（UI変更の追跡）](#6-step3-4スナップショットテストui変更の追跡)
7. [【STEP4-5】レポートとカバレッジ（品質管理）](#7-step4-5レポートとカバレッジ品質管理)

**【サポート機能】**
8. [ウォッチモード](#8-ウォッチモード)
9. [デバッグ機能](#9-デバッグ機能)
10. [設定のカスタマイズ](#10-設定のカスタマイズ)

**【運用ガイド】**
11. [日常業務の流れ](#11-日常業務の流れ)
12. [よくある質問と対処法](#12-よくある質問と対処法)
13. [トラブルシューティング](#13-トラブルシューティング)

---

## 1. システム概要

### 1.1 Jestとは

Jestは、Meta Platforms, Inc.が開発したJavaScript向けのテスティングフレームワークです。シンプルさに重点を置き、ほとんどのJavaScriptプロジェクトでゼロコンフィグ（設定不要）で動作します。

**主な特徴：**
- **ゼロコンフィグ**: ほとんどのプロジェクトで設定ファイルなしで動作
- **高速なフィードバック**: インタラクティブなウォッチモードで変更ファイルに関連するテストのみを実行
- **スナップショットテスト**: UIコンポーネントや大きなオブジェクトの変更を追跡
- **並列テスト実行**: ワーカープロセスで高速な並列実行
- **コードカバレッジ**: Istanbul統合によるカバレッジレポート生成

### 1.2 本システムで行う主要業務

本フレームワークは、主に以下の開発業務を支援します：

| 業務カテゴリ | 具体的な業務内容 |
|------------|----------------|
| **単体テスト** | 関数・モジュールの動作検証、境界値テスト、エラーケーステスト |
| **統合テスト** | 複数モジュールの連携検証、API統合テスト |
| **UIテスト** | Reactコンポーネントテスト、スナップショットテスト |
| **モックテスト** | 外部依存のモック、タイマーモック、APIモック |
| **カバレッジ計測** | テストカバレッジの測定、レポート生成 |

### 1.3 業務フロー概要

本フレームワークにおけるテスト業務は、以下の流れで進行します：

```
+-----------------------------------------------------------------------+
|                        テスト業務フロー                                 |
+-----------------------------------------------------------------------+
|                                                                       |
|  【STEP 1】開発者がテストコードを作成（*.test.js / *.spec.js）           |
|      |                                                                |
|  【STEP 2】アサーション（expect）でテスト条件を記述                      |
|      |                                                                |
|  【STEP 3】jestコマンドでテストを実行・結果を確認                        |
|      |                                                                |
|  【STEP 4】失敗したテストを修正、スナップショットを更新                   |
|      |                                                                |
|  【STEP 5】カバレッジレポートで品質を確認・CI/CDに統合                    |
|                                                                       |
+-----------------------------------------------------------------------+
```

**役割別の業務概要：**

| 役割 | 主な業務 |
|------|---------|
| **開発者** | テストコードの作成、テスト実行、失敗テストの修正、カバレッジ確認 |
| **レビュアー** | テストコードのレビュー、カバレッジ閾値の確認、スナップショット変更の確認 |
| **CI/CD担当** | テスト自動化設定、レポーター設定、カバレッジ閾値の設定 |

### 1.4 主な機能

| 機能 | 説明 | 業務フローでの位置 |
|------|------|------------------|
| テスト実行 | describe/test/itでテストスイートを定義・実行 | STEP 1-3 |
| アサーション | expect APIで期待値を検証 | STEP 2 |
| モック | jest.fn()/jest.mock()で依存をモック化 | STEP 2 |
| スナップショット | toMatchSnapshot()でUI変更を追跡 | STEP 3-4 |
| カバレッジ | --coverageでコードカバレッジを測定 | STEP 5 |
| ウォッチモード | --watchで変更を監視し自動テスト | 随時利用 |

### 1.5 ユーザー種別

| ユーザー種別 | 説明 |
|-------------|------|
| 開発者 | テストコードを書き、テストを実行する主要ユーザー |
| CI/CDシステム | 自動テストを実行し、結果をレポートするシステム |
| プロジェクトリーダー | カバレッジレポートを確認し、品質を管理 |

### 1.6 対応環境

**Node.jsバージョン：**
- Node.js ^18.14.0
- Node.js ^20.0.0（推奨）
- Node.js ^22.0.0
- Node.js >=24.0.0

**対応OS：**
- macOS
- Linux
- Windows

**パッケージマネージャー：**
- npm
- yarn
- pnpm

---

## 2. セットアップ手順

### 2.1 Jestのインストール

**npm を使用する場合：**

```bash
npm install --save-dev jest
```

**yarn を使用する場合：**

```bash
yarn add --dev jest
```

**pnpm を使用する場合：**

```bash
pnpm add --save-dev jest
```

### 2.2 package.json の設定

`package.json` に以下のスクリプトを追加します：

```json
{
  "scripts": {
    "test": "jest"
  }
}
```

### 2.3 最初のテストの作成

1. テスト対象のファイル `sum.js` を作成します：

```javascript
function sum(a, b) {
  return a + b;
}
module.exports = sum;
```

2. テストファイル `sum.test.js` を作成します：

```javascript
const sum = require('./sum');

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3);
});
```

3. テストを実行します：

```bash
npm test
```

### 2.4 設定ファイルの生成（オプション）

詳細な設定が必要な場合、設定ファイルを生成します：

```bash
npx jest --init
```

これにより `jest.config.js` が生成され、以下の設定が可能になります：
- テスト環境（Node.js / jsdom）
- カバレッジ設定
- モジュール解決設定

---

## 3. 基本的なテスト実行

### 3.1 テストの実行方法

**全テストを実行：**

```bash
npm test
```

または

```bash
npx jest
```

**特定のファイルをテスト：**

```bash
npx jest path/to/test.test.js
```

**パターンにマッチするテストを実行：**

```bash
npx jest --testPathPattern="user"
```

### 3.2 テスト結果の見方

テスト実行後、以下のような結果が表示されます：

```
 PASS  ./sum.test.js
  ✓ adds 1 + 2 to equal 3 (2 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.5 s
```

**表示の意味：**
- `PASS` / `FAIL`: テストスイートの合否
- `✓`: 成功したテストケース
- `✕`: 失敗したテストケース
- `Test Suites`: テストファイル数
- `Tests`: テストケース数
- `Snapshots`: スナップショットテスト数
- `Time`: 実行時間

---

## 4. 【STEP1】テストの作成（テストコードの記述）

> **業務フローでの位置**: 開発者がテストコードを作成し、テストスイートを構築するステップです。

### 4.1 テストファイルの命名規則

Jestは以下のパターンでテストファイルを自動検出します：

| パターン | 例 |
|---------|-----|
| `*.test.js` | `sum.test.js` |
| `*.spec.js` | `sum.spec.js` |
| `__tests__/*.js` | `__tests__/sum.js` |

**推奨**: テスト対象ファイルと同じディレクトリに `*.test.js` を配置

### 4.2 テストの基本構造

```javascript
describe('テストスイート名', () => {
  beforeAll(() => {
    // 全テスト前に1回実行
  });

  beforeEach(() => {
    // 各テスト前に実行
  });

  test('テストケース名', () => {
    // テストコード
    expect(result).toBe(expected);
  });

  it('別のテストケース', () => {
    // testと同じ意味
  });

  afterEach(() => {
    // 各テスト後に実行
  });

  afterAll(() => {
    // 全テスト後に1回実行
  });
});
```

### 4.3 非同期テストの書き方

**async/await を使用：**

```javascript
test('async operation', async () => {
  const data = await fetchData();
  expect(data).toBe('expected');
});
```

**Promiseを返す：**

```javascript
test('promise operation', () => {
  return fetchData().then(data => {
    expect(data).toBe('expected');
  });
});
```

**コールバックを使用：**

```javascript
test('callback operation', done => {
  fetchData(data => {
    expect(data).toBe('expected');
    done();
  });
});
```

### 4.4 パラメータ化テスト

同じロジックを複数の入力でテストする場合：

```javascript
test.each([
  [1, 1, 2],
  [1, 2, 3],
  [2, 2, 4],
])('adds %i + %i to equal %i', (a, b, expected) => {
  expect(sum(a, b)).toBe(expected);
});
```

---

## 5. 【STEP2-3】テストの実行と検証（アサーション・モック）

> **業務フローでの位置**: 開発者がアサーションで期待値を検証し、モックで依存を制御するステップです。

### 5.1 基本的なマッチャー

**等価性の検証：**

| マッチャー | 説明 | 使用例 |
|-----------|------|--------|
| `toBe(value)` | 厳密等価（===） | `expect(2 + 2).toBe(4)` |
| `toEqual(value)` | 深い等価性 | `expect(obj).toEqual({a: 1})` |
| `toStrictEqual(value)` | より厳密な等価性 | `expect(obj).toStrictEqual({a: 1})` |

**真偽値の検証：**

| マッチャー | 説明 |
|-----------|------|
| `toBeTruthy()` | 真と評価される値 |
| `toBeFalsy()` | 偽と評価される値 |
| `toBeNull()` | nullであること |
| `toBeUndefined()` | undefinedであること |
| `toBeDefined()` | undefinedでないこと |

**数値の検証：**

| マッチャー | 説明 |
|-----------|------|
| `toBeGreaterThan(n)` | nより大きい |
| `toBeLessThan(n)` | nより小さい |
| `toBeCloseTo(n, digits)` | 浮動小数点の近似比較 |

**文字列の検証：**

| マッチャー | 説明 |
|-----------|------|
| `toMatch(regexp)` | 正規表現にマッチ |
| `toContain(item)` | 配列/文字列に含まれる |

**例外の検証：**

```javascript
test('throws an error', () => {
  expect(() => {
    throw new Error('wrong');
  }).toThrow('wrong');
});
```

### 5.2 モック関数の作成

**基本的なモック関数：**

```javascript
const mockFn = jest.fn();
mockFn('arg1', 'arg2');

expect(mockFn).toHaveBeenCalled();
expect(mockFn).toHaveBeenCalledWith('arg1', 'arg2');
expect(mockFn).toHaveBeenCalledTimes(1);
```

**戻り値の設定：**

```javascript
const mockFn = jest.fn()
  .mockReturnValue('default')
  .mockReturnValueOnce('first call')
  .mockReturnValueOnce('second call');

console.log(mockFn()); // 'first call'
console.log(mockFn()); // 'second call'
console.log(mockFn()); // 'default'
```

**Promiseを返すモック：**

```javascript
const asyncMock = jest.fn()
  .mockResolvedValue('success')
  .mockRejectedValueOnce(new Error('fail'));
```

### 5.3 モジュールのモック

**自動モック：**

```javascript
jest.mock('./module');
const module = require('./module');

module.someMethod.mockReturnValue('mocked');
```

**手動モック：**

```javascript
jest.mock('./module', () => ({
  someMethod: jest.fn(() => 'mocked'),
}));
```

### 5.4 スパイの使用

既存のメソッドを監視しながら、元の実装を保持：

```javascript
const spy = jest.spyOn(object, 'method');
object.method();

expect(spy).toHaveBeenCalled();
spy.mockRestore(); // 元の実装に戻す
```

---

## 6. 【STEP3-4】スナップショットテスト（UI変更の追跡）

> **業務フローでの位置**: UIコンポーネントや複雑なオブジェクトの出力を記録し、変更を追跡するステップです。

### 6.1 スナップショットテストの基本

```javascript
test('renders correctly', () => {
  const tree = render(<MyComponent />);
  expect(tree).toMatchSnapshot();
});
```

初回実行時、Jestは `__snapshots__` ディレクトリにスナップショットファイルを生成します。

### 6.2 スナップショットの更新

コンポーネントの変更が意図的な場合、スナップショットを更新します：

```bash
npx jest --updateSnapshot
```

または短縮形：

```bash
npx jest -u
```

### 6.3 インラインスナップショット

テストファイル内にスナップショットを埋め込む：

```javascript
test('renders correctly', () => {
  expect({ name: 'Jest' }).toMatchInlineSnapshot(`
    Object {
      "name": "Jest",
    }
  `);
});
```

### 6.4 スナップショットのベストプラクティス

1. **スナップショットは小さく保つ**: 大きすぎるスナップショットはレビューが困難
2. **変更時は慎重に確認**: `git diff` でスナップショットの変更を確認
3. **CI/CDでの自動更新は禁止**: 本番環境では `--updateSnapshot` を使用しない

---

## 7. 【STEP4-5】レポートとカバレッジ（品質管理）

> **業務フローでの位置**: テスト結果をレポート化し、コードカバレッジで品質を測定・管理するステップです。

### 7.1 カバレッジの測定

```bash
npx jest --coverage
```

実行後、以下のレポートが生成されます：
- ターミナルにサマリー表示
- `coverage/` ディレクトリにHTML/LCOVレポート

### 7.2 カバレッジレポートの見方

```
----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files |   85.71 |      100 |   66.67 |   85.71 |
 sum.js   |     100 |      100 |     100 |     100 |
 user.js  |   71.43 |      100 |      50 |   71.43 | 8-10
----------|---------|----------|---------|---------|-------------------
```

**カバレッジ指標：**
- **Stmts (Statements)**: 文のカバレッジ
- **Branch**: 分岐のカバレッジ（if/else等）
- **Funcs (Functions)**: 関数のカバレッジ
- **Lines**: 行のカバレッジ
- **Uncovered Line #s**: カバーされていない行番号

### 7.3 カバレッジ閾値の設定

`jest.config.js` で閾値を設定：

```javascript
module.exports = {
  coverageThreshold: {
    global: {
      branches: 80,
      functions: 80,
      lines: 80,
      statements: 80,
    },
  },
};
```

閾値を下回るとテストが失敗します。

### 7.4 CI/CDでのレポート出力

**JSON形式で出力：**

```bash
npx jest --json --outputFile=results.json
```

**JUnitレポーター（GitHub Actions等向け）：**

```javascript
// jest.config.js
module.exports = {
  reporters: [
    'default',
    ['jest-junit', { outputDirectory: 'reports' }],
  ],
};
```

---

## 8. ウォッチモード

### 8.1 ウォッチモードの起動

**変更されたファイルに関連するテストのみ実行：**

```bash
npx jest --watch
```

**全テストを監視：**

```bash
npx jest --watchAll
```

### 8.2 インタラクティブコマンド

ウォッチモード中に以下のキーで操作できます：

| キー | 動作 |
|------|------|
| `a` | 全テストを実行 |
| `f` | 失敗したテストのみ実行 |
| `o` | 変更されたファイルに関連するテストのみ実行 |
| `p` | ファイル名でフィルタ |
| `t` | テスト名でフィルタ |
| `q` | ウォッチモードを終了 |
| `Enter` | テストを再実行 |

### 8.3 ウォッチモードのベストプラクティス

1. **開発中は常にウォッチモードを使用**: 即座にフィードバックを得られる
2. **`o` モードを活用**: 変更に関連するテストだけを実行し、高速化
3. **`f` モードでデバッグ**: 失敗したテストに集中

---

## 9. デバッグ機能

### 9.1 VS Codeでのデバッグ

`.vscode/launch.json` に以下を追加：

```json
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Jest Debug",
      "program": "${workspaceFolder}/node_modules/.bin/jest",
      "args": ["--runInBand"],
      "console": "integratedTerminal",
      "internalConsoleOptions": "neverOpen"
    }
  ]
}
```

### 9.2 Node.js Inspectorでのデバッグ

```bash
node --inspect-brk node_modules/.bin/jest --runInBand
```

Chrome DevTools（chrome://inspect）でデバッグできます。

### 9.3 console.log デバッグ

テストコード内で `console.log` を使用：

```javascript
test('debug example', () => {
  const result = calculate();
  console.log('result:', result);
  expect(result).toBe(expected);
});
```

**注意**: `--verbose` オプションと組み合わせると見やすくなります。

---

## 10. 設定のカスタマイズ

### 10.1 設定ファイルの種類

Jestは以下の設定ファイルをサポートします：

| ファイル | 形式 |
|---------|------|
| `jest.config.js` | JavaScript |
| `jest.config.ts` | TypeScript |
| `jest.config.mjs` | ES Module |
| `jest.config.json` | JSON |
| `package.json` の `jest` フィールド | JSON |

### 10.2 主要な設定オプション

```javascript
// jest.config.js
module.exports = {
  // テスト環境
  testEnvironment: 'node', // or 'jsdom'

  // テストファイルのパターン
  testMatch: ['**/__tests__/**/*.js', '**/*.test.js'],

  // 無視するパターン
  testPathIgnorePatterns: ['/node_modules/'],

  // モジュールエイリアス
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/src/$1',
  },

  // セットアップファイル
  setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],

  // カバレッジ設定
  collectCoverageFrom: ['src/**/*.js'],
  coverageDirectory: 'coverage',

  // タイムアウト
  testTimeout: 10000,
};
```

### 10.3 TypeScript対応

**Babel経由：**

```bash
npm install --save-dev @babel/preset-typescript
```

```javascript
// babel.config.js
module.exports = {
  presets: [
    ['@babel/preset-env', { targets: { node: 'current' } }],
    '@babel/preset-typescript',
  ],
};
```

**ts-jest経由：**

```bash
npm install --save-dev ts-jest
```

```javascript
// jest.config.js
module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
};
```

---

## 11. 日常業務の流れ

本セクションでは、業務フローに沿った日常業務の流れを説明します。

```
業務フロー概要（再掲）
------------------------------------------------------------
【STEP 1】開発者がテストコードを作成 → 4章参照
    |
【STEP 2】アサーションでテスト条件を記述 → 5章参照
    |
【STEP 3】jestコマンドでテストを実行 → 5章参照
    |
【STEP 4】失敗テストを修正、スナップショット更新 → 6章参照
    |
【STEP 5】カバレッジレポートで品質確認 → 7章参照
------------------------------------------------------------
```

### 11.1 【開発者】STEP1: テストコードの作成

新機能を実装する際、以下の流れでテストを作成します。

**手順：**

1. 実装する機能に対応するテストファイルを作成
   - 例: `src/utils/validator.js` に対して `src/utils/validator.test.js`

2. `describe` でテストスイートを構造化
   ```javascript
   describe('Validator', () => {
     describe('validateEmail', () => {
       test('有効なメールアドレスを受け入れる', () => {
         // ...
       });
     });
   });
   ```

3. ウォッチモードを起動して開発
   ```bash
   npm test -- --watch
   ```

### 11.2 【開発者】STEP2-3: テストの実行と検証

実装とテストを繰り返しながら、品質を確保します。

**手順：**

1. テストを実行して失敗を確認（Red）
   ```bash
   npm test
   ```

2. 機能を実装して成功を確認（Green）

3. 必要に応じてリファクタリング（Refactor）

4. モックが必要な場合は適切に設定
   ```javascript
   jest.mock('./api');
   ```

### 11.3 【開発者】STEP4-5: 品質確認とカバレッジ

コードレビュー前に品質を確認します。

**手順：**

1. 全テストを実行
   ```bash
   npm test
   ```

2. カバレッジを確認
   ```bash
   npm test -- --coverage
   ```

3. `coverage/lcov-report/index.html` をブラウザで開いて詳細を確認

4. カバレッジ閾値を満たしていることを確認

5. スナップショットの変更がある場合は意図した変更か確認
   ```bash
   git diff **/__snapshots__/*
   ```

---

## 12. よくある質問と対処法

### 12.1 テスト実行に関するQ&A

**Q: テストが見つかりません（No tests found）**

A: 以下を確認してください：
- テストファイルが `*.test.js` または `*.spec.js` の命名規則に従っているか
- `jest.config.js` の `testMatch` 設定が正しいか
- `testPathIgnorePatterns` でテストファイルが除外されていないか

**Q: テストが非常に遅い**

A: 以下の対策を試してください：
- `--maxWorkers` でワーカー数を調整
- `--runInBand` でシリアル実行に切り替え（メモリ不足の場合）
- 不要なテストを `test.skip` でスキップ
- `--onlyChanged` で変更ファイルに関連するテストのみ実行

### 12.2 モックに関するQ&A

**Q: モジュールのモックが効かない**

A: 以下を確認してください：
- `jest.mock()` がファイルの先頭（importの前）にあるか
- モックするモジュールのパスが正確か
- `jest.resetModules()` が必要な場合があるか

**Q: タイマーのテストが不安定**

A: フェイクタイマーを使用してください：
```javascript
beforeEach(() => {
  jest.useFakeTimers();
});

afterEach(() => {
  jest.useRealTimers();
});

test('timer test', () => {
  // ...
  jest.advanceTimersByTime(1000);
  // ...
});
```

### 12.3 スナップショットに関するQ&A

**Q: スナップショットの差分が大きすぎて確認が困難**

A: 以下を検討してください：
- スナップショット対象を小さくする（コンポーネントを分割）
- 動的な値（日付、ID等）をモックまたは除外
- インラインスナップショットを使用

---

## 13. トラブルシューティング

### 13.1 エラーメッセージと対処法

| エラーメッセージ | 原因 | 対処法 |
|----------------|------|--------|
| `Cannot find module 'xxx'` | モジュールが見つからない | パスを確認、`npm install` を実行 |
| `SyntaxError: Unexpected token` | ES6+構文がトランスパイルされていない | Babel設定を確認 |
| `Timeout - Async callback was not invoked` | 非同期処理が完了していない | `done()` の呼び出し、async/awaitの使用を確認 |
| `Jest has detected the following...open handle` | 非同期リソースが解放されていない | `--detectOpenHandles` で特定 |
| `ENOMEM: not enough memory` | メモリ不足 | `--maxWorkers=1` または `--runInBand` を使用 |

### 13.2 よくあるトラブルと解決方法

**問題: キャッシュが原因で古いコードがテストされる**

解決方法：
```bash
npx jest --clearCache
```

**問題: ウォッチモードが動作しない（ファイル変更を検知しない）**

解決方法：
- macOSの場合: Watchmanをインストール `brew install watchman`
- Linuxの場合: inotify制限を増やす
  ```bash
  echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf
  sudo sysctl -p
  ```

**問題: CI環境でテストが失敗するが、ローカルでは成功する**

解決方法：
- `--runInBand` でシリアル実行を試す
- 環境変数の違いを確認
- タイムゾーンや日付に依存するテストを確認
- `--ci` フラグを使用

### 13.3 サポートへの連絡方法

問題が解決しない場合：

1. **GitHubイシュー**: https://github.com/jestjs/jest/issues
   - 既存のイシューを検索
   - 再現手順を含めて新規イシューを作成

2. **Stack Overflow**: `jest` タグで質問
   - https://stackoverflow.com/questions/tagged/jest

3. **Discord**: Jest Communityに参加
   - https://discord.gg/j6FKKQQrW9

---

## 改訂履歴

| 版数 | 改訂日 | 改訂内容 |
|-----|--------|---------|
| 1.0 | 2026-03-01 | 初版作成 |

---

*本マニュアルは、Jestテスティングフレームワークの業務運用マニュアルです。*
*フレームワークの更新により、コマンドや機能が変更される場合があります。*
*最新情報は公式ドキュメント（https://jestjs.io）を参照してください。*
