mcpField
T
tdd

tdd

github.com/blogic-czテスト・品質386 回インストール1 日前に更新
リポジトリ

tdd について

ユーティリティ、サービス、複雑なロジック、バグ修正にテスト駆動開発を適用するコーディングスキルです。Red-Green-Refactorの進め方とEffect向けのテストパターンを示します。

主な機能

  1. 01Red-Green-Refactorの手順
  2. 02テスト先行のバグ再現
  3. 03Effectサービスのテストパターン
  4. 04テスト範囲と配置のガイド
  5. 05リファレンスとサンプル

活用シーン

  1. 01ユーティリティや複雑な業務ロジックの開発
  2. 02再現テストを先に書いてバグを修正
  3. 03モックレイヤーを使ったEffectサービスのテスト

インストール

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

$npx skills add https://github.com/blogic-cz/blogic-marketplace --skill tdd

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

同梱ファイル

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

references/
anti-patterns.md
commands.md
effect-tdd-patterns.md
red-green-refactor.md
test-first-examples.md

詳細

テスト駆動開発(TDD)

厳密なテストファースト開発を実行するには、このスキルを適用します。失敗するテストを書き、テストに合格する最小限のコードを実装してから、テストをグリーンに保ちながらリファクタリングします。

TDD を使うタイミングを判断する

次の判断表を使います。

状況このスキルを使うか?デフォルトのアクション
新しいユーティリティ関数はいすぐに TDD サイクルを実行する
新しい Effect サービスはいまずテストで動作を定義する
複雑なビジネスロジックはい実装前にテストで動作を固める
バグ修正はいまず失敗するテストでバグを再現する
UI のスタイル/レイアウトのみの変更いいえ標準的な実装フローを使う
探索的なプロトタイピングいいえまずプロトタイプを作成し、動作が安定したら TDD に切り替える
TRPC エンドポイント(シンプルな CRUD)通常は使わないデフォルトでは testing-patterns を使います。ユーザーがテストファースト/RGR を明示的に要求した場合のみ、このスキルを使います

Red-Green-Refactor を実行する

一度に 1 つの動作を、次の 3 つのフェーズで進めます。

1. RED - まず失敗するテストを書く
import { describe, expect, it } from "vitest";
import { calculateDiscount } from "../calculate-discount";

describe("calculateDiscount", () => {
  it("applies 10% discount for orders over 100", () => {
    // This test fails first: function does not exist yet
    expect(calculateDiscount(150)).toBe(135);
  });
});

テストを実行して、失敗することを確認します。

bun run vitest run packages/common/src/__tests__/calculate-discount.test.ts
2. GREEN - 最小限のコードを実装する

テストに合格させるための最小限のコードを書きます。

// packages/common/src/calculate-discount.ts
export function calculateDiscount(amount: number): number {
  if (amount > 100) {
    return amount * 0.9;
  }
  return amount;
}

テストを実行して、合格することを確認します。

bun run vitest run packages/common/src/__tests__/calculate-discount.test.ts
3. REFACTOR - 動作を壊さずに改善する

テストをグリーンに保ちながら、コードの品質を改善します。

const DISCOUNT_THRESHOLD = 100;
const DISCOUNT_RATE = 0.1;

export function calculateDiscount(amount: number): number {
  if (amount <= DISCOUNT_THRESHOLD) {
    return amount;
  }
  return amount * (1 - DISCOUNT_RATE);
}

テストを再実行し、リファクタリングによって問題が生じていないことを確認します。

より詳しい例、失敗時の診断、反復的な拡張については、references/red-green-refactor.md を参照してください。


テストの範囲を絞る

まず軽量なテストを優先し、必要な場合にのみ段階を上げます。

  1. ユニットテスト(推奨) - 純粋関数と、モックレイヤーを使った Effect サービス。
  2. TRPC 統合テスト - TRPC と永続化の動作全体。
  3. E2E テスト - ブラウザー上のフローとユーザージャーニー。
状況テストの種類アクション
純粋関数、パーサー、ユーティリティユニットすぐに書く
依存関係のある Effect サービスモックレイヤーを使ったユニットテストすぐに書く
TRPC プロシージャ(DB ロジック)TRPC 統合テストtesting-patterns の判断プロセスに従う
ユーザー向けのフロー、UI の動作E2Etesting-patterns の判断プロセスに従う

Effect 固有の TDD パターンを適用する

明示的なレイヤーを使い、テストファーストでサービスを設計します。

  1. テストでインターフェースを定義する - 実装前に動作を明確にします。
  2. モックレイヤーを作成する - 依存関係を分離し、テストの決定性を保ちます。
  3. サービスを実装する - 最小限の動作でテストを満たします。
  4. リファクタリングする - 動作を維持しながら、読みやすさと構造を改善します。
import { describe, expect, it } from "@effect/vitest";
import { Effect, Layer } from "effect";

describe("PricingService", () => {
  // 1. Define what the service should do via tests
  it.effect("calculates base price without discount", () =>
    Effect.gen(function* () {
      const service = yield* PricingService;
      const result = yield* service.calculatePrice({
        itemId: "item-1",
        quantity: 2,
      });
      expect(result.total).toBe(200);
    }).pipe(Effect.provide(testLayer)),
  );

  it.effect("applies bulk discount for quantity > 10", () =>
    Effect.gen(function* () {
      const service = yield* PricingService;
      const result = yield* service.calculatePrice({
        itemId: "item-1",
        quantity: 15,
      });
      expect(result.total).toBe(1350); // 15% discount
    }).pipe(Effect.provide(testLayer)),
  );
});
モックレイヤーファクトリーパターン
// Create parameterized mock layers for different test scenarios
const createMockInventoryLayer = (inventory: Map<string, number>) =>
  Layer.succeed(InventoryService, {
    getStock: (itemId) => Effect.succeed(inventory.get(itemId) ?? 0),
    reserveStock: (itemId, qty) => Effect.succeed(void 0),
  });

// Use in tests
const testLayer = PricingService.layer.pipe(
  Layer.provide(createMockInventoryLayer(new Map([["item-1", 100]]))),
);

より詳しいガイダンス(エラーパスのテスト、レイヤーの合成、vi.mock() を避ける理由)については、references/effect-tdd-patterns.md を参照してください。


プロジェクトの慣例に沿ったテスト配置を使用する(例)

これらのパスはプロジェクトの慣例/例として扱い、リポジトリで異なるテスト配置が採用されている場合は適宜調整してください。

コードの場所テストの場所
packages/X/src/file.tspackages/X/src/__tests__/file.test.ts
apps/web-app/src/infrastructure/trpc/routers/X.tsapps/web-app/src/__tests__/X.test.ts
apps/web-app/src/routes/**apps/web-app/e2e/feature.e2e.ts

詳細については参考資料を利用する

実行時にこのファイルを拡張するのではなく、対象を絞った参考資料を読み込んでください。

  • 実行可能なコマンドのパターンについては、references/commands.md を使用してください。
  • 失敗例の解説と修正については、references/anti-patterns.md を使用してください。

リソース

references/
  • red-green-refactor.md - 例を交えた詳細なTDDサイクルのワークフロー
  • effect-tdd-patterns.md - Effectサービスのテスト、モックレイヤー、エラーケース
  • test-first-examples.md - このコードベースにおける、手順ごとのTDDの例
  • commands.md - コマンドカタログと、正しい/誤った呼び出しパターン
  • anti-patterns.md - 修正方法を含む、詳細なTDDのアンチパターン解説
関連スキル
  • testing-patterns - テスト構文、TRPC統合テスト、E2Eパターン
  • effect-ts - Effectサービスの設計、レイヤー、エラー処理

コメント