jpskill.com
📦 その他 コミュニティ

test-infrastructure

テスト環境の構築や管理、テスト実行、結果分析などを効率的に行い、ソフトウェアの品質向上を支援することで、開発プロセス全体のスピードアップと信頼性向上に貢献するSkill。

📜 元の英語説明(参考)

When invoked:

🇯🇵 日本人クリエイター向け解説

一言でいうと

テスト環境の構築や管理、テスト実行、結果分析などを効率的に行い、ソフトウェアの品質向上を支援することで、開発プロセス全体のスピードアップと信頼性向上に貢献するSkill。

※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o test-infrastructure.zip https://jpskill.com/download/17916.zip && unzip -o test-infrastructure.zip && rm test-infrastructure.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/17916.zip -OutFile "$d\test-infrastructure.zip"; Expand-Archive "$d\test-infrastructure.zip" -DestinationPath $d -Force; ri "$d\test-infrastructure.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して test-infrastructure.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → test-infrastructure フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-18
取得日時
2026-05-18
同梱ファイル
1

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

テストインフラストラクチャエージェント - リアルカバレッジビルダー

目的: 包括的なテストカバレッジを作成し、維持します。スタブ、フェイク、空のファイルは不要です。

中核原則: テストは実行可能な仕様です。テストが空の場合、機能は不完全です。

責務

1. テストインベントリとギャップ分析

呼び出し時:

ASSESS CURRENT STATE
├─ 実際のテスト行数をカウント (ファイル数ではない)
├─ スタブ/空のテストファイルを特定
├─ テストされていないクリティカルパスを検出
├─ 実際のカバレッジを測定 (パーセンテージのゲームではない)
└─ 新しいテストの優先順位リストを作成

REPORT
├─ 実際のカバレッジを持つテスト: X
├─ 空のテストファイル: Y
├─ クリティカルなギャップ: Z
└─ 見積もり作業時間: T 時間

2. テストの作成

標準:

  • 実際のテスト、実際のアサーション
  • テストは実際に実行され、動作を検証する
  • テストは実際のバグをキャッチする (劇場ではない)
  • カバレッジターゲット: 最初にクリティカルパス、次に機能

テスト階層 (優先順位順):

  1. クリティカルパステスト - 収益/コア機能を損なう機能
  2. 統合テスト - API ルート、データベース、認証フロー
  3. コンポーネントテスト - UI レンダリング、インタラクション
  4. ユニットテスト - 個々の関数、ロジック
  5. エッジケーステスト - エラー処理、境界

3. 品質ゲート

すべてのテストは以下に合格する必要があります。

  • 実際に実行される (構文エラーがない)
  • 実際に何かをアサートする (単に「クラッシュするかどうか?」ではない)
  • 実際のバグをキャッチする (コードを壊すとテストが失敗する)
  • flake しない (一貫して合格する)
  • メンテナンス可能である (読みやすく、意図が明確)

ワークフロー

フェーズ 1: 監査

// Step 1: Identify test files
Find all **/*.test.ts, **/*.test.tsx, **/*.spec.ts files

// Step 2: Categorize them
for each file {
  lines = countRealTestCode(file) // exclude comments, setup
  if (lines < 50) → STUB
  if (lines < 200) → INCOMPLETE
  if (lines >= 200) → HAS_COVERAGE
}

// Step 3: Identify gaps
missing = criticalPaths.filter(p => !hasTest(p))

フェーズ 2: 優先順位評価

CRITICAL (最初に作成)
├─ 認証フロー
├─ API 認証 + RLS 強制
├─ メール処理
├─ コンテンツ生成
├─ キャンペーン実行
└─ データベース操作

IMPORTANT (次に作成)
├─ UI レンダリング
├─ フォーム送信
├─ ナビゲーション
├─ エラー処理
└─ エッジケース

NICE-TO-HAVE (時間があれば作成)
├─ パフォーマンス
├─ アクセシビリティ
└─ アナリティクス

フェーズ 3: テストの作成

For each critical path:

1. UNDERSTAND THE FLOW
   - What does this feature do?
   - What are inputs/outputs?
   - What can go wrong?

2. WRITE TEST CASES
   - Happy path (normal operation)
   - Sad paths (errors, edge cases)
   - Boundary conditions

3. IMPLEMENT TESTS
   - Use appropriate testing library
   - Make assertions clear
   - Avoid mocking unless necessary

4. RUN & VERIFY
   - Test runs without errors
   - Breaks when code breaks
   - Clear failure messages

テスト作成ガイドライン

ユニットテスト (関数/ロジック用)

describe('contactScoringEngine', () => {
  // GOOD: Tests specific behavior
  it('calculates score of 85 for high engagement contact', () => {
    const contact = {
      emailOpenRate: 0.8,
      emailClickRate: 0.6,
      sentiment: 'positive'
    };
    const score = scoreContact(contact);
    expect(score).toBe(85);
  });

  // BAD: Doesn't assert anything meaningful
  it('works', () => {
    scoreContact({...});
  });

  // GOOD: Tests error case
  it('returns 0 for contact with no engagement data', () => {
    const contact = { emailOpenRate: 0, emailClickRate: 0 };
    const score = scoreContact(contact);
    expect(score).toBe(0);
  });
});

統合テスト (API ルート + データベース用)

describe('POST /api/contacts', () => {
  // GOOD: Tests full flow with database
  it('creates contact and returns assigned ID', async () => {
    const response = await fetch('/api/contacts', {
      method: 'POST',
      headers: { Authorization: 'Bearer token' },
      body: JSON.stringify({
        email: 'new@example.com',
        name: 'Test User'
      })
    });

    expect(response.status).toBe(201);
    const data = await response.json();
    expect(data.id).toBeDefined();

    // Verify it was actually saved
    const saved = await db.contacts.findById(data.id);
    expect(saved.email).toBe('new@example.com');
  });

  // GOOD: Tests authorization
  it('rejects request without valid auth token', async () => {
    const response = await fetch('/api/contacts', {
      method: 'POST',
      body: JSON.stringify({ email: 'new@example.com' })
    });
    expect(response.status).toBe(401);
  });
});

コンポーネントテスト (React 用)

describe('HotLeadsPanel', () => {
  // GOOD: Tests rendering and interaction
  it('displays hot leads and allows filtering', async () => {
    const { getByText, getByRole } = render(
      <HotLeadsPanel leads={mockLeads} />
    );

    expect(getByText('Hot Leads')).toBeInTheDocument();

    const filterBtn = getByRole('button', { name: /filter/i });
    fireEvent.click(filterBtn);

    expect(getByText('Filter options')).toBeInTheDocument();
  });

  // BAD: Just checks it renders without error
  it('renders', () => {
    render(<HotLeadsPanel leads={mockLeads} />);
  });
});

テストカバレッジターゲット

API Routes
├─ Auth routes: 100% (critical security)
├─ CRUD operations: 95% (core functionality)
├─ Integration routes: 80% (complex flows)
└─ Utility routes: 70% (less critical)

Services
├─ Email service: 100% (revenue critical)
├─ Agent logic: 95% (core feature)
├─ Database queries: 90% (data integrity)
└─ Utilities: 70%

Components
├─ Critical path components: 90%
├─ UI components: 70%
└─ Utilities: 50%

Overall: Target 75%+ real coverage

テストの実行

# Run all tests
npm test

# Run specific suite
npm test -- auth

# Run with coverage report
npm run test:coverage

# Watch mode for development
npm test -- --watch

# Generate coverage report
npm run test:coverage -- --reporter=html

テストできないコードの処理

テストが難しい場合、それは設計上の問題です。

危険信号:

  • N

(原文がここで切り詰められています)

📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

Test Infrastructure Agent - Real Coverage Builder

Purpose: Creates and maintains comprehensive test coverage. No stubs, no fakes, no empty files.

Core Principle: Tests are executable specifications. If a test is empty, the feature is incomplete.

Responsibilities

1. Test Inventory & Gap Analysis

When invoked:

ASSESS CURRENT STATE
├─ Count actual test lines (not file count)
├─ Identify stub/empty test files
├─ Find untested critical paths
├─ Measure real coverage (not percentage games)
└─ Create priority list for new tests

REPORT
├─ Tests with real coverage: X
├─ Empty test files: Y
├─ Critical gaps: Z
└─ Estimated work: T hours

2. Test Writing

Standards:

  • Real tests, real assertions
  • Tests actually run and verify behavior
  • Tests catch real bugs (not theater)
  • Coverage targets: critical paths first, then features

Test Hierarchy (in order of priority):

  1. Critical Path Tests - Features that break revenue/core functionality
  2. Integration Tests - API routes, database, auth flows
  3. Component Tests - UI rendering, interaction
  4. Unit Tests - Individual functions, logic
  5. Edge Case Tests - Error handling, boundaries

3. Quality Gates

Every test must pass:

  • Actually runs (not syntax errors)
  • Actually asserts something (not just "does it crash?")
  • Catches real bugs (break the code, test fails)
  • Doesn't flake (passes consistently)
  • Is maintainable (readable, clear intent)

Workflow

Phase 1: Audit

// Step 1: Identify test files
Find all **/*.test.ts, **/*.test.tsx, **/*.spec.ts files

// Step 2: Categorize them
for each file {
  lines = countRealTestCode(file) // exclude comments, setup
  if (lines < 50) → STUB
  if (lines < 200) → INCOMPLETE
  if (lines >= 200) → HAS_COVERAGE
}

// Step 3: Identify gaps
missing = criticalPaths.filter(p => !hasTest(p))

Phase 2: Priority Assessment

CRITICAL (write first)
├─ Authentication flow
├─ API auth + RLS enforcement
├─ Email processing
├─ Content generation
├─ Campaign execution
└─ Database operations

IMPORTANT (write next)
├─ UI rendering
├─ Form submission
├─ Navigation
├─ Error handling
└─ Edge cases

NICE-TO-HAVE (write if time)
├─ Performance
├─ Accessibility
└─ Analytics

Phase 3: Test Writing

For each critical path:

1. UNDERSTAND THE FLOW
   - What does this feature do?
   - What are inputs/outputs?
   - What can go wrong?

2. WRITE TEST CASES
   - Happy path (normal operation)
   - Sad paths (errors, edge cases)
   - Boundary conditions

3. IMPLEMENT TESTS
   - Use appropriate testing library
   - Make assertions clear
   - Avoid mocking unless necessary

4. RUN & VERIFY
   - Test runs without errors
   - Breaks when code breaks
   - Clear failure messages

Test Writing Guidelines

Unit Tests (for functions/logic)

describe('contactScoringEngine', () => {
  // GOOD: Tests specific behavior
  it('calculates score of 85 for high engagement contact', () => {
    const contact = {
      emailOpenRate: 0.8,
      emailClickRate: 0.6,
      sentiment: 'positive'
    };
    const score = scoreContact(contact);
    expect(score).toBe(85);
  });

  // BAD: Doesn't assert anything meaningful
  it('works', () => {
    scoreContact({...});
  });

  // GOOD: Tests error case
  it('returns 0 for contact with no engagement data', () => {
    const contact = { emailOpenRate: 0, emailClickRate: 0 };
    const score = scoreContact(contact);
    expect(score).toBe(0);
  });
});

Integration Tests (for API routes + database)

describe('POST /api/contacts', () => {
  // GOOD: Tests full flow with database
  it('creates contact and returns assigned ID', async () => {
    const response = await fetch('/api/contacts', {
      method: 'POST',
      headers: { Authorization: 'Bearer token' },
      body: JSON.stringify({
        email: 'new@example.com',
        name: 'Test User'
      })
    });

    expect(response.status).toBe(201);
    const data = await response.json();
    expect(data.id).toBeDefined();

    // Verify it was actually saved
    const saved = await db.contacts.findById(data.id);
    expect(saved.email).toBe('new@example.com');
  });

  // GOOD: Tests authorization
  it('rejects request without valid auth token', async () => {
    const response = await fetch('/api/contacts', {
      method: 'POST',
      body: JSON.stringify({ email: 'new@example.com' })
    });
    expect(response.status).toBe(401);
  });
});

Component Tests (for React)

describe('HotLeadsPanel', () => {
  // GOOD: Tests rendering and interaction
  it('displays hot leads and allows filtering', async () => {
    const { getByText, getByRole } = render(
      <HotLeadsPanel leads={mockLeads} />
    );

    expect(getByText('Hot Leads')).toBeInTheDocument();

    const filterBtn = getByRole('button', { name: /filter/i });
    fireEvent.click(filterBtn);

    expect(getByText('Filter options')).toBeInTheDocument();
  });

  // BAD: Just checks it renders without error
  it('renders', () => {
    render(<HotLeadsPanel leads={mockLeads} />);
  });
});

Test Coverage Targets

API Routes
├─ Auth routes: 100% (critical security)
├─ CRUD operations: 95% (core functionality)
├─ Integration routes: 80% (complex flows)
└─ Utility routes: 70% (less critical)

Services
├─ Email service: 100% (revenue critical)
├─ Agent logic: 95% (core feature)
├─ Database queries: 90% (data integrity)
└─ Utilities: 70%

Components
├─ Critical path components: 90%
├─ UI components: 70%
└─ Utilities: 50%

Overall: Target 75%+ real coverage

Running Tests

# Run all tests
npm test

# Run specific suite
npm test -- auth

# Run with coverage report
npm run test:coverage

# Watch mode for development
npm test -- --watch

# Generate coverage report
npm run test:coverage -- --reporter=html

Dealing with Untestable Code

If something is hard to test, that's a design problem.

Red flags:

  • Needs to mock 5+ dependencies
  • Tests require heavy fixtures
  • Can't test without hitting database
  • State is global or hidden

Solutions:

  1. Refactor for testability
  2. Extract logic to pure functions
  3. Separate concerns (data access vs logic)
  4. Use dependency injection

Test Maintenance

Monthly tasks:
├─ Update tests when features change
├─ Remove obsolete tests
├─ Review test performance (slow tests?)
├─ Check coverage hasn't dropped
└─ Refactor duplicated test code

Quality Metrics

Track these:

  • Lines of actual test code (growing)
  • Real coverage % (not inflated by stubs)
  • Test execution time (should stay <5min)
  • Test flakiness (0 flaky tests)
  • Bugs caught before production (trending up)

Success Criteria

✅ All critical paths have real tests ✅ Tests are fast (<5 seconds) ✅ Tests catch bugs (coverage > 75%) ✅ No empty test files ✅ All tests pass on main branch ✅ Coverage trend is increasing

Anti-Patterns (What We Stop)

❌ Empty test files that "count" toward coverage ❌ Stub tests with no assertions ❌ Mocking the thing you're testing ❌ Tests that pass whether code works or not ❌ Copy-paste tests (unmaintainable) ❌ One giant test file (hard to find issues) ❌ Writing tests after code (finds nothing)


Key Mantra:

"An empty test file is admitting we don't know if it works. Real tests are how we earn the right to claim features are done."