mcpField
T
test-generator

test-generator

github.com/oimiragieoテスト・品質44122 回インストール17 週間前に更新
リポジトリ

test-generator について

仕様やコードを基に、プロジェクトの既存ルールに沿ったテストを生成するプロンプト駆動型スキルです。ユニット、統合、API、エンドツーエンドテストを追加し、カバレッジや実行可能性を確認したい開発者向けです。

主な機能

  1. 01プロジェクトの規約に沿ったテスト生成
  2. 02ユニット・統合・API・E2Eテストに対応
  3. 03境界条件とエラーケースの分析
  4. 04構文・設定・カバレッジの確認

活用シーン

  1. 01新しいコンポーネントや関数のテスト追加
  2. 02APIエンドポイントのテスト作成
  3. 03ユーザーフローのE2Eテスト作成
  4. 04既存コードのテストカバレッジ確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/oimiragieo/agent-studio --skill test-generator

インストール後、Claude Code で/test-generatorを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

commands/
test-generator.md
hooks/
post-execute.cjs
pre-execute.cjs
references/
research-requirements.md
rules/
test-generator.md
schemas/
input.schema.json
output.schema.json
scripts/
main.cjs
templates/
implementation-template.md

詳細

モード:コグニティブ/プロンプト主導 — 単独で実行するユーティリティスクリプトはありません。エージェントのコンテキストを通じて使用します。

テスト生成スキル — プロジェクトのテストパターンと規約に従って、仕様、コンポーネント、API エンドポイントからテストコードを生成します。 - 新しいコンポーネントのテストを生成する - API エンドポイントのテストを作成する - ユーザーフローの E2E テストを生成する - 統合テストを作成する - 既存コードのテストカバレッジを追加する
ステップ 1:テストの種類を特定する

必要なテストの種類を判断します。

  • ユニットテスト:コンポーネント/関数のテスト
  • 統合テスト:サービス/API の統合テスト
  • E2E テスト:ユーザーフロー全体のテスト
  • API テスト:エンドポイントのテスト
ステップ 2:対象コードを分析する

テスト対象のコードを調べます(Parallel Read/Grep/Glob を使用)。

  • コンポーネント/関数のコードを読む
  • テストケースを特定する
  • 依存関係を把握する
  • エッジケースを確認する
ステップ 3:テストパターンを分析する

既存のテストを確認します。

  • 類似するテストファイルを読む
  • テストパターンを特定する
  • テストフレームワークの使用方法を確認する
  • モック戦略を把握する
ステップ 4:テストコードを生成する

パターンに従ってテストを作成します。

  • 適切なテストフレームワークを使用する
  • プロジェクトの規約に従う
  • 網羅的なカバレッジを含める
  • エッジケースとエラーシナリオを追加する
ステップ 5:カバレッジを分析する

テストを生成したら、カバレッジを分析します。

  1. 生成したテストがすべての要件を網羅していることを確認する:

    • すべての関数/メソッドがテストされていることを確認する
    • すべての分岐(if/else、switch など)が網羅されていることを確認する
    • すべてのエッジケースがテストされていることを確認する
    • エラーシナリオが網羅されていることを確認する
  2. テストを実行できることを検証する:

    • テストの構文が有効であることを確認する
    • インポートが正しいことを確認する
    • テストフレームワークが適切に設定されていることを確認する
    • テストのセットアップ/ティアダウンが正しいことを検証する
  3. カバレッジ率を報告する:

    • 行カバレッジを算出する(可能な場合)
    • 分岐カバレッジを算出する(可能な場合)
    • 未カバーのコードパスを報告する
    • 未カバーの箇所に対する追加テストを提案する
  4. カバレッジ検証チェックリスト:

    • すべての公開関数/メソッドにテストがある
    • すべてのエラーパスがテストされている
    • すべてのエッジケースが網羅されている
    • テストの構文が有効である
    • テストを正常に実行できる
    • カバレッジがプロジェクトのしきい値を満たしている(定義されている場合) </execution_process>
**ユニットテスト(React コンポーネント)**
import { render, screen, waitFor } from '@testing-library/react'
import { describe, it, expect, vi } from 'vitest'
import { UserProfile } from './user-profile'

describe('UserProfile', () => {
  it('renders user information', async () => {
    const mockUser = { id: '1', name: 'John', email: '[email protected]' }

    render(<UserProfile user={mockUser} />)

    await waitFor(() => {
      expect(screen.getByText('John')).toBeInTheDocument()
      expect(screen.getByText('[email protected]')).toBeInTheDocument()
    })
  })

  it('handles loading state', () => {
    render(<UserProfile user={null} loading />)
    expect(screen.getByTestId('loading')).toBeInTheDocument()
  })

  it('handles error state', () => {
    render(<UserProfile user={null} error="Failed to load" />)
    expect(screen.getByText('Failed to load')).toBeInTheDocument()
  })
})

</code_example>

<code_example> 統合テスト(API)

import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import { createTestClient } from './test-client';

describe('Users API', () => {
  let client: TestClient;

  beforeAll(() => {
    client = createTestClient();
  });

  afterAll(async () => {
    await client.cleanup();
  });

  it('creates a user', async () => {
    const response = await client.post('/api/users', {
      email: '[email protected]',
      name: 'Test User',
    });

    expect(response.status).toBe(201);
    expect(response.data).toHaveProperty('id');
    expect(response.data.email).toBe('[email protected]');
  });

  it('validates required fields', async () => {
    const response = await client.post('/api/users', {});

    expect(response.status).toBe(400);
    expect(response.data).toHaveProperty('errors');
  });
});

</code_example>

<code_example> E2E テスト(Cypress)

describe('User Authentication Flow', () => {
  beforeEach(() => {
    cy.visit('/login');
  });

  it('allows user to login', () => {
    cy.get('[data-testid="email-input"]').type('[email protected]');
    cy.get('[data-testid="password-input"]').type('password123');
    cy.get('[data-testid="login-button"]').click();

    cy.url().should('include', '/dashboard');
    cy.get('[data-testid="user-menu"]').should('be.visible');
  });

  it('shows error for invalid credentials', () => {
    cy.get('[data-testid="email-input"]').type('[email protected]');
    cy.get('[data-testid="password-input"]').type('wrong');
    cy.get('[data-testid="login-button"]').click();

    cy.get('[data-testid="error-message"]')
      .should('be.visible')
      .and('contain', 'Invalid credentials');
  });
});

</code_example>

**Developer Agent との統合**: - 開発中にテストを生成する - テストカバレッジを確保する - 実装を検証する

QA Agent との統合:

  • 包括的なテストスイートを作成する
  • テスト計画を生成する
  • テストの品質を検証する

<best_practices>

  1. パターンに従う:既存のテスト構造に合わせる
  2. 包括的なカバレッジ:正常系とエッジケースをテストする
  3. 明確なテスト名:テスト内容を説明する名前を付ける
  4. テストを分離する:各テストを独立させる
  5. 依存関係をモックする:適切なモック戦略を使用する </best_practices>
**コマンド例**:
# Generate tests for a file
node .claude/skills/test-generator/scripts/main.cjs src/components/UserProfile.tsx

# The tool will analyze the file and generate appropriate tests

</usage_example>

絶対遵守事項

  1. 必ずテストコードを生成する前に、既存のテストパターンとフレームワークの規約を分析する
  2. 実装の詳細を調べるテストを決して生成しない。公開された振る舞いと出力のみをテストする
  3. 必ずテスト対象の各単位について、null/undefined の入力、境界値、エラーシナリオなどのエッジケースを含める
  4. 変更可能な共有状態を持つテストを決して作成しない。beforeEach/afterEach を使って各テストを分離する
  5. テスト生成の完了とする前に、生成したテストの構文が有効で、実行可能であることを必ず確認する

アンチパターン

アンチパターン失敗する理由正しい方法
実装の詳細をテストする動作が変わっていなくても、リファクタリングでテストが失敗しますパブリック API の動作と観測可能な出力をテストします
テスト本体にアサーションがないテストは常に成功し、何も検出しませんすべてのテストケースに明示的なアサーションを追加します
テスト間で変更可能な状態を共有する実行順序によってテストが失敗しますbeforeEach/afterEach を使用して完全に分離します
アサーションにマジックナンバーを使う期待値が不明確になり、テストが壊れやすくなります名前付き定数または説明的なフィクスチャデータを使用します
エラーパスのテストがないカバレッジが不十分になり、本番環境で障害が見過ごされます成功と失敗の両方のシナリオをテストします

メモリープロトコル(必須)

開始前: .claude/context/memory/learnings.md を読みます

完了後:

  • 新しいパターン -> .claude/context/memory/learnings.md
  • 見つかった問題 -> .claude/context/memory/issues.md
  • 決定事項 -> .claude/context/memory/decisions.md

中断を前提にしてください。メモリーに記録されていなければ、起きていないものとして扱います。

コメント