mcpField
T
testing

testing

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

testing について

ソフトウェア開発者向けのフレームワーク非依存のテストスキルです。TDD、テストの階層化、モック、カバレッジを扱い、pytest、vitest、jest などで信頼性と保守性の高い振る舞いテストを支援します。

主な機能

  1. 01TDD のレッド・グリーン・リファクタリング
  2. 02ユニット・統合・E2E テストの階層化
  3. 03外部依存のモック方針
  4. 04テスト構成と命名の指針
  5. 05カバレッジ目標と完了チェックリスト
  6. 06pytest、vitest、jest の例

活用シーン

  1. 01機能実装前に失敗するテストを作成
  2. 02ユニット・統合・E2E テストの配分を計画
  3. 03API やデータベースなど外部依存のモックを選定
  4. 04テストのカバレッジ、独立性、安定性を確認

インストール

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

$npx skills add https://github.com/scientiacapital/skills --skill testing

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

同梱ファイル

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

config.json
reference/
coverage-strategies.md
integration-testing.md
test-organization.md
unit-testing.md

詳細

TDD ワークフロー、テストピラミッド戦略、モッキングパターン、カバレッジのガイダンスを網羅する包括的なテストスキルです。pytest、vitest、jest、その他のテストフレームワークに適用できる、フレームワークに依存しないパターンを扱います。

このスキルでは、メンテナンスの負担にならずに信頼性を提供するテストを書くことを重視します。テストは高速で信頼性が高く、実装の詳細ではなく振る舞いに焦点を当てるべきです。

<quick_start> TDD の Red-Green-Refactor サイクル:

  1. RED: まず失敗するテストを書きます

    test('adds numbers', () => {
      expect(add(1, 2)).toBe(3);  // Fails - add() doesn't exist
    });
    
  2. GREEN: 通るための最小限のコードを書きます

    const add = (a, b) => a + b;  // Test passes
    
  3. REFACTOR: テストがグリーンのままリファクタリングします

テストピラミッド: ユニット 70%、インテグレーション 25%、E2E 5% </quick_start>

<success_criteria> 次の条件を満たすとき、テストは成功です:

  • TDD サイクルに従っている: 実装コードの前にテストを書いている
  • テストピラミッドのバランスが取れている: ユニット約 70%、インテグレーション約 25%、E2E 約 5%
  • テストが独立しており、任意の順序で実行できる
  • フレーキーなテストがない(信頼性を確認するために 3 回実行する)
  • カバレッジが目標を満たしている: 行 70〜80%、クリティカルパス 100%
  • テスト名が振る舞いを説明している(何を + いつ + 期待される結果)
  • モックは外部依存に対してのみ使用し、自作コードには使用しない </success_criteria>

<core_principles>

テストの心得

  1. テストはドキュメントである - 失敗するテストは、まだ実装されていない仕様です
  2. 実装ではなく振る舞いをテストする - テストはリファクタリングに耐えるべきです
  3. 高速なフィードバックループ - ユニットテストは秒ではなくミリ秒で実行されます
  4. デフォルトで分離 - 各テストは独立しているべきです
  5. Arrange-Act-Assert - すべてのテストで明確な構造を保ちます </core_principles>

<tdd_workflow>

TDD: Red-Green-Refactor

┌─────────────────────────────────────────────────────────┐
│                    TDD CYCLE                             │
│                                                          │
│    ┌─────────┐                                          │
│    │   RED   │ ◄─── Write a failing test                │
│    └────┬────┘                                          │
│         │                                                │
│         ▼                                                │
│    ┌─────────┐                                          │
│    │  GREEN  │ ◄─── Write minimum code to pass          │
│    └────┬────┘                                          │
│         │                                                │
│         ▼                                                │
│    ┌─────────┐                                          │
│    │REFACTOR │ ◄─── Clean up while tests stay green     │
│    └────┬────┘                                          │
│         │                                                │
│         └──────────────► Back to RED                    │
└─────────────────────────────────────────────────────────┘
ルール
  1. まず失敗するテストを書く - 失敗するテストなしにプロダクションコードを書いてはいけません
  2. 失敗するのに十分なテストだけを書く - コンパイルエラーも失敗に含まれます
  3. 通るのに十分なコードだけを書く - それ以上でもそれ以下でもありません
  4. グリーンのときだけリファクタリングする - 失敗するテストがある状態でリファクタリングしてはいけません
よくある TDD の間違い
間違いなぜ間違っているか代わりに
コードの後にテストを書くテストが確証バイアスになるRed-Green-Refactor
プライベートメソッドをテストする振る舞いではなく実装をテストしている公開インターフェースをテストする
テストの複雑さを大きく飛躍させる失敗のデバッグが難しい小さなステップで進める
リファクタリングのステップを飛ばす技術的負債が蓄積する常にクリーンアップする
</tdd_workflow>

<test_pyramid>

テストピラミッド

                    ┌───────────┐
                    │    E2E    │  Few, slow, expensive
                    │   Tests   │  (minutes)
                    └─────┬─────┘
                          │
               ┌──────────┴──────────┐
               │   Integration Tests  │  Some, medium speed
               │   (API, Database)    │  (seconds)
               └──────────┬───────────┘
                          │
        ┌─────────────────┴─────────────────┐
        │          Unit Tests                │  Many, fast, cheap
        │    (Functions, Components)         │  (milliseconds)
        └────────────────────────────────────┘
分布のガイドライン
種類割合速度スコープ
ユニット70〜80%各 <10ms単一の関数/コンポーネント
インテグレーション15〜25%各 <1s複数のコンポーネント、DB
E2E5〜10%各 <30sユーザーフロー全体
どこで何をテストするか

ユニットテスト:

  • 純粋関数
  • ビジネスロジック
  • データ変換
  • バリデーションルール
  • コンポーネントのレンダリング

インテグレーションテスト:

  • API エンドポイント
  • データベース操作
  • サービス間のやり取り
  • コンポーネントの統合

E2E テスト:

  • クリティカルなユーザーフロー(ログイン、チェックアウト)
  • ハッピーパスのみ
  • スモークテスト </test_pyramid>

<when_to_mock>

モッキング戦略

ロンドン派 vs デトロイト派

ロンドン派(モッキスト):

  • すべての依存をモックする
  • 完全に分離してテストする
  • テストは非常に焦点が絞られている

デトロイト派(クラシシスト):

  • 外部サービスのみをモックする
  • 自然な単位をまとめてテストする
  • テストはより現実に即している

推奨: 実用的なアプローチ

  • 外部サービス(API、ユニットテストにおける DB)をモックする
  • 必要でない限り自作コードをモックしない
  • インテグレーションテストでは実際の実装を使用する
何をモックするか
モックするモックしない
外部 API自作の純粋関数
ファイルシステム(ユニットテストにおいて)データ変換
ネットワークリクエストビジネスロジック
時間/乱数インメモリのデータ構造
高コストな計算単純なユーティリティ
モッキングパターン
// GOOD: Mock external dependency
const mockFetch = vi.fn().mockResolvedValue({ data: [] });

// BAD: Mocking your own utilities
const mockFormatDate = vi.fn(); // Don't do this

// GOOD: Dependency injection for testability
function createService(httpClient = fetch) {
  return {
    getData: () => httpClient('/api/data')
  };
}

// In test:
const mockClient = vi.fn();
const service = createService(mockClient);

</when_to_mock>

<test_structure>

テストの構成

ファイルの命名
src/
├── components/
│   ├── Button.tsx
│   └── Button.test.tsx      # Colocated test
├── utils/
│   ├── format.ts
│   └── format.test.ts
└── __tests__/               # Or separate folder
    └── integration/
        └── api.test.ts
テストの命名
// Pattern: describe what + when + expected result
describe('UserService', () => {
  describe('createUser', () => {
    it('returns user object when given valid email', () => {});
    it('throws ValidationError when email is invalid', () => {});
    it('sends welcome email after successful creation', () => {});
  });
});

// Alternative: BDD style
describe('UserService', () => {
  describe('when creating a user with valid data', () => {
    it('should return the created user', () => {});
    it('should send a welcome email', () => {});
  });

  describe('when email is invalid', () => {
    it('should throw ValidationError', () => {});
  });
});
Arrange-Act-Assert
it('calculates total with discount', () => {
  // Arrange - set up test data
  const cart = createCart([
    { price: 100, quantity: 2 },
    { price: 50, quantity: 1 }
  ]);
  const discount = 0.1;

  // Act - perform the action
  const total = calculateTotal(cart, discount);

  // Assert - verify result
  expect(total).toBe(225); // (200 + 50) * 0.9
});

</test_structure>

<what_not_to_test>

テストしないもの

次のものは省略します
  1. フレームワークのコード - React の useState、Express のルーティング
  2. サードパーティライブラリ - 独自のテストがあります
  3. 単純なゲッター/セッター - ロジックがなければテストは不要です
  4. 実装の詳細 - プライベートメソッド、内部状態
  5. 1行の関数 - 複雑なロジックがある場合を除きます
注力する項目
  1. ビジネスロジック - バグが潜む場所です
  2. エッジケース - null、空の配列、境界値
  3. エラーパス - 問題が起きたときの動作
  4. ユーザー向けの動作 - ユーザーが実際に行うこと
  5. リグレッション - 一度修正したバグの再発
カバレッジの目標
指標目標備考
行カバレッジ70-80%高ければよいとは限りません
分岐カバレッジ70-80%行カバレッジより重要です
重要な処理経路100%認証、支払い、データの変更

警告: カバレッジが100%でも、優れたテストとは限りません。意味のある内容をテストせずに、すべての行を実行する不適切なテストもあります。 </what_not_to_test>

詳しいパターンについては、適切なリファレンスを読み込んでください。
トピックリファレンスファイル読み込むタイミング
単体テストのパターンreference/unit-testing.md単体テストの作成、モックの使用時
統合テストreference/integration-testing.mdAPI テスト、データベーステスト時
テストの構成reference/test-organization.mdテストスイートの構成時
カバレッジ戦略reference/coverage-strategies.mdカバレッジ目標の設定時

読み込むには: トピックを指定するか、コンテキストから判断してください。

<framework_patterns>

フレームワーク別クイックリファレンス

pytest (Python)
# Fixtures
@pytest.fixture
def user():
    return User(name="test")

def test_user_greet(user):
    assert user.greet() == "Hello, test"

# Parametrize
@pytest.mark.parametrize("input,expected", [
    ("hello", "HELLO"),
    ("world", "WORLD"),
])
def test_uppercase(input, expected):
    assert uppercase(input) == expected
vitest/jest (TypeScript)
// Basic test
test('adds numbers', () => {
  expect(add(1, 2)).toBe(3);
});

// Mock
vi.mock('./api', () => ({
  fetchUser: vi.fn().mockResolvedValue({ name: 'test' })
}));

// Component test
import { render, screen } from '@testing-library/react';

test('renders button', () => {
  render(<Button>Click</Button>);
  expect(screen.getByRole('button')).toHaveTextContent('Click');
});
Testing Library の原則
  1. テスト ID ではなくロールでクエリします
  2. 実装ではなく、ユーザーに見える内容をテストします
  3. fireEvent より userEvent を優先します
  4. 内部状態のテストは避けます </framework_patterns>
## テストのチェックリスト

コードの完成とする前に、次の項目を確認してください。

  • 単体テストで正常系をカバーしている
  • 単体テストでエラーケースをカバーしている
  • エッジケースをテストしている(null、空、境界値)
  • API エンドポイントの統合テストがある
  • 不安定なテストがない(3回実行して確認)
  • テストが独立している(任意の順序で実行できる)
  • テスト名が動作を説明している
  • ハードコードされたタイムアウトがない(waitFor を使用)
  • テスト間でモックがリセットされる
  • カバレッジがプロジェクトの基準を満たしている

結果サイドカーの出力

最後の手順として、~/.claude/skill-analytics/last-outcome-testing.json に書き込みます。

{"ts":"[UTC ISO8601]","skill":"testing","version":"1.0.0","variant":"default",
 "status":"[success|partial|error]","runtime_ms":[estimated ms from start],
 "metrics":{"tests_written":[n],"coverage_delta_pct":[n]},
 "error":null,"session_id":"[YYYY-MM-DD]"}

一部の段階が失敗しても結果が生成された場合は、ステータスに「partial」を使用してください。出力が何も生成されなかった場合に限り、「error」を使用してください。

コメント