0:00 0:00
記事
Claude CodeでAPI・DB連携テストを作るときのポイント
Claude Codeに結合テスト(インテグレーションテスト)を書かせるときに押さえるポイントを整理します。テストDBの選択、モック方針、外部API、シードデータ、後片付け、CI連携までを依頼文テンプレートとともに扱います。
ユニットテストと違い、APIエンドポイント・DB・外部サービスを含む結合テストは「何をモックして何を実物で動かすか」の設計が結果を左右します。Claude Codeに結合テストを書かせるとき、観点を渡さないと「mockだらけで通るが本番では落ちるテスト」になりがちです。この記事では、APIとDBを含む結合テストを作るときの設計判断と依頼文テンプレートを整理します。
モックする層を最初に決める
結合テストの最大の論点は「何をモックして何を実物で動かすか」です。次の3層モデルで考えると判断が安定します。
| 層 | 例 | 推奨 |
|---|---|---|
| DB層 | PostgreSQL、MySQL、SQLite | 実物を使う(Testcontainersなど) |
| 外部API層 | Stripe、Slack、SendGrid | モックを使う(msw、nock) |
| アプリケーション層 | 自分が書いた関数 | 実物を使う |
DBをモックすると本番のSQL不整合が検出できません。外部APIを実物で叩くと課金や通信コストが発生します。この方針を依頼文とCLAUDE.mdに書いておけば、AIが勝手にDBをモックすることを防げます。
CLAUDE.mdに書く結合テストルール
## 結合テストルール
- DBは実物を使う(テスト用DBコンテナまたはローカルテスト用インスタンス)
- 外部APIはモックする(msw / nock / 自前のスタブ)
- 課金・送信系(Stripe、SendGrid、Twilio)は絶対に実物を叩かない
- テスト前にシードデータを投入し、テスト後に必ずロールバックまたはトランザクション破棄する
- テスト用の認証トークンは固定値を使い、コードに直書きしない(環境変数)
- フィクスチャは tests/fixtures/ に集約する
CLAUDE.mdの書き方の詳細は「CLAUDE.mdテンプレート完全版」を参照してください。
テストDBの3つの選び方
1. Testcontainersで本番同種のDBを起動
Testcontainersは、Dockerコンテナでテスト用DBを起動するライブラリです。本番と同じバージョンのPostgreSQLやMySQLを使えるため、SQL方言の違いによる事故を防げます。CIでDockerが使えるなら第一選択です。
2. ローカル開発DBをトランザクション分離で使う
Dockerで常駐させたDBに対して、各テストをトランザクションで囲み、最後にロールバックする方式です。テストの並列実行に注意が必要ですが、起動が速いメリットがあります。
3. SQLite等の軽量DBで代替
開発初期で本番DB方言依存が無い段階なら、SQLiteのインメモリDBで結合テストを書く選択肢もあります。ただしJSON型・ウィンドウ関数・特殊なインデックスなどを使うなら本番と同じDBに切り替えるべきです。
API結合テストの依頼文テンプレート
依頼:POST /api/users エンドポイントの結合テストを書いてください。
## 観点
- 正常系:正しいリクエストでユーザーが作成され、DBに保存される
- 異常系1:必須フィールド欠損で 400 が返る
- 異常系2:重複メールアドレスで 409 が返る
- 異常系3:外部メール送信APIが失敗してもユーザー作成自体は成功する
## モック方針
- DB:実物(テストコンテナ)を使う
- メール送信API:msw でモック化、成功時/失敗時の両方をテスト
- 認証:テスト用固定トークンで通す
## セットアップ
- 各テストの beforeEach で DB をクリーンにする
- フィクスチャは tests/fixtures/users.ts から読み込む
## 完了条件
- すべてのテストが通る
- npx tsc --noEmit がエラーなしで通る
- テスト後に DB に余分なレコードが残らない
- 外部 API の実物には1回もアクセスしないこと
「外部APIに1回もアクセスしないこと」を完了条件に入れるのがポイントです。テスト実行ログでmswのintercept件数を確認できます。
DB結合テストでよくある失敗パターン
| 症状 | 原因 | 対処 |
|---|---|---|
| 単体では通るが連続実行で落ちる | beforeEachのクリーンアップ漏れ | トランザクション分離またはtruncate |
| CIだけ落ちる | 並列実行で同一レコードを取り合う | テストごとに独立スキーマか、describe.serialで直列化 |
nullがundefinedになる | ORM経由で型が変換されている | DB直接クエリで実値を確認 |
| マイグレーション漏れに気づかない | テストDBに最新スキーマが当たっていない | beforeAllでmigrate実行 |
外部APIモックの依頼文テンプレート
依頼:Stripe決済APIの結合テストを書いてください。
## 制約
- Stripe本番にも sandbox にも一切アクセスしないこと
- msw で /v1/charges のレスポンスをモック化する
- 成功レスポンス(200)と失敗レスポンス(402 card_declined)の両方をテストする
- モックレスポンスは tests/fixtures/stripe.ts に定義する
## 観点
- 正常決済時に DB の order.status が paid になる
- card_declined 時に order.status が failed になり、失敗理由が記録される
- ネットワーク例外時にリトライが3回行われる
## 完了条件
- 実 Stripe API へのアクセスが0件であることをテストログで確認できる
- DB の状態がテストごとに独立していること
Stripeなどの課金系APIは、テストモードであっても本番アカウントの状態を汚す可能性があります。明示的にモック必須と書いておきます。
シードデータと後片付け
テストデータの管理は次の2点を決めれば破綻しにくくなります。
シードデータは関数経由で作る
ハードコードした巨大なJSONより、ファクトリー関数のほうがメンテナンスしやすくなります。
// tests/fixtures/users.ts
export const buildUser = (overrides = {}) => ({
id: crypto.randomUUID(),
email: `test-${Date.now()}@example.com`,
name: "Test User",
...overrides,
});
依頼文で「フィクスチャはbuild関数を作る」と指定すると、AIも一貫した形で生成します。
後片付けはトランザクションロールバックを優先
beforeEachでtruncateするより、テスト全体をトランザクションで囲んでロールバックする方がシンプルかつ高速です。フレームワークによってはテストハーネスが対応しています(Prismaの$transactionなど)。
CI連携の最低条件
CIで結合テストを動かす場合、最低限次を整えます。
- DB起動を待ってからテストを開始する(
pg_isreadyなどのヘルスチェック) - テスト用シークレットはGitHub ActionsのSecretsで注入し、コードに直書きしない
- 失敗時にDBログとアプリログを成果物として保存する
- テスト時間がCI予算を超えないよう、結合テストは並列化または分割実行する
シークレット管理は「Claude Codeに秘密情報を渡さないための実践ルール」を参照してください。
AIが書きがちな危ないテスト
AIが生成する結合テストで頻出する問題パターンです。レビューで弾きます。
- DBを丸ごとモックしている:
jest.mockでORM全体をmock化し、SQLが一切走らない - アサートが
expect(true).toBe(true)相当: 戻り値の存在だけ確認している - モックレスポンスが本物と違う形: 本番APIにない構造を返してテストが通る
any型でレスポンスを受けている: 型安全性が抜ける- 後片付けがない: テストの度にDBレコードが累積する
describe.skipが混入: 通らないテストをスキップで放置
ユニットテストの危ないサインも含めて「Claude Codeにテストコードを生成させるときの依頼文と注意点」で詳しく扱っています。
結合テスト依頼前のチェックリスト
- DB・外部API・アプリ層のモック方針を明示したか
- テスト観点(正常・異常)を3〜5個リストアップしたか
- 「実APIにアクセスしないこと」を完了条件に入れたか
- シードデータの場所(
tests/fixtures/等)を指定したか - 後片付けの方針(truncate / トランザクションロールバック)を決めたか
- 認証トークンを環境変数化する指定をしたか
- CIで実行する場合のシークレット管理を確認したか
次に読むおすすめ記事:
- 「Claude Codeにテストコードを生成させるときの依頼文と注意点」:ユニットテスト含む生成依頼の基礎
- 「Claude Codeでテスト駆動開発をする手順」:Red→Green→Refactorで結合テストを設計する流れ
- 「Claude Codeに秘密情報を渡さないための実践ルール」:テスト用APIキーやDB認証情報の扱い