2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JavaScriptにおけるテスト設計戦略:ユニット / 結合 / E2E の分離、モック戦略、UIとロジックのテスト方針

Posted at

概要

テストとは「書くもの」ではなく「設計を証明するもの」である。
それは単なるチェックリストではなく、設計が意図どおりであることを保証する、もう一つのインターフェースである。

本稿では、JavaScriptにおけるテストを「単なるツール」から「設計構造の一部」へと昇華させるために必要な戦略を解説する。


1. テスト三層構造の理解と責務分離

レイヤー 主な対象 特徴
Unit Test 関数 / クラス 高速、ピュア、責務明確
Integration モジュール / サービス 実際の依存間の整合性検証
E2E Test UI + サーバ ユーザー視点での振る舞い保証

→ ✅ それぞれ何を守るためのテストかを明確に設計する


2. ユニットテスト:純粋な構造の保証

function add(a, b) {
  return a + b;
}
test('加算関数', () => {
  expect(add(1, 2)).toBe(3);
});
  • ✅ 入力と出力のみで定義される関数は最小の保証対象
  • ✅ 副作用なし・依存なしが前提

3. 結合テスト:依存間の接続保証

import { fetchUser } from './api';
import { renderUser } from './ui';

test('ユーザー情報の取得と表示', async () => {
  const user = await fetchUser();
  const ui = renderUser(user);
  expect(ui).toContain(user.name);
});
  • ✅ 外部呼び出し(API / DBなど)はmock/stubで制御
  • ✅ 依存先の“契約”を守るテスト → インターフェース保証

4. モック戦略:何を偽装し、何を残すか

jest.mock('./api', () => ({
  fetchUser: jest.fn().mockResolvedValue({ id: 1, name: 'Toto' }),
}));
  • ✅ モックは副作用の排除 or テスト高速化のための構造
  • ✅ モックが乱立するとテストの意味が失われる → 構造の一部として設計すべき

5. E2Eテスト:動作の保証ではなく、流れの保証

// e.g. with Playwright
test('ログインしてダッシュボードが表示される', async ({ page }) => {
  await page.goto('/login');
  await page.fill('#email', 'user@example.com');
  await page.fill('#password', 'securepassword');
  await page.click('button[type=submit]');
  await expect(page).toHaveURL('/dashboard');
});
  • ✅ E2Eは振る舞いの確認 + 回帰テストの最後の砦
  • ❌ 頻度は少なめでよい → 回帰用に絞って設計

6. テスト容易性を前提にした構造設計

  • 関数は副作用と切り離して設計
  • グローバル依存を減らし、DI / hook / context などで外部注入
  • データ構造は関数引数で与える
function createUserStore(apiClient) {
  return {
    fetch: () => apiClient.get('/user'),
  };
}

→ ✅ モック可能な構造にすることでテストしやすさ = 設計品質となる


7. CI / カバレッジとの統合戦略

  • ✅ 全てのテストをCI上で実行し、“守られている”構造を保つ
  • ✅ カバレッジはあくまで補助指標 → 低くても「テストすべき場所」がカバーされているならOK
  • ✅ 重要なのは**“設計の意図がテストで守られているか”**

設計判断フロー

① テストがUI中心に偏っていないか? → ロジック単位の分離を検討

② モックが意味をなしているか? → 副作用・契約・境界で切る

③ ロジックとDOMが分離されているか? → ユニットとE2Eの分離設計へ

④ テストが壊れたとき“なぜ”かがわかるか? → 名前 / 構造を明示的に

⑤ テスト対象が関数でなければテスト不能では? → 設計見直し

よくあるミスと対策

❌ UIの見た目ばかりをsnapshotでテストし、内部ロジックが壊れても気づかない

→ ✅ テストの粒度をUI / ロジックに明示的に分離


❌ モックだらけでテストが意味を成していない

→ ✅ モックの対象を**「制御不能な外部」だけに限定**


❌ E2Eで全てを保証しようとして時間がかかりすぎる

→ ✅ E2Eはユーザーフロー + 致命的回帰の監視用に絞る


結語

テストとは「安心を得るため」ではない。
それは**“設計を守るための防波堤”**であり、
未来の開発者への契約文書でもある。

  • 責務単位で分離し
  • モックは構造的に設計し
  • 振る舞いではなく“意図”を検証する

JavaScriptにおけるテスト設計とは、
“壊れても壊れた理由が分かり、すぐに直せる構造”をつくる戦略である。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?