api-testing について
api-testingは、RESTおよびGraphQL APIの自動テスト作成を支援するコーディングエージェント向けスキルです。実際のテスト環境で、スキーマ、ステータスコード、ヘッダー、認証境界、性能を検証します。
主な機能
- 01スキーマに基づくレスポンス構造の検証
- 02ステータスコード・ヘッダー・認証境界の確認
- 03RESTとGraphQLエンドポイントのテスト
- 04Playwright APIRequestContextによるテスト
- 05応答時間・ペイロード量・並行処理の検証
活用シーン
- 01CIでAPIレスポンス構造の変更を検出
- 02ログイン、権限、エラー動作を検証
- 03APIでデータを準備し画面表示を確認
- 04ページネーション、ファイル転送、Webhookをテスト
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ petrkindlmann/ qa-skills --skill api-testingインストール後、Claude Code で/api-testingを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/playwright-setup.mdschema-validation.mdtest-patterns.md詳細
検討事項
まず .agents/qa-project-context.md を確認してください。ファイルが存在する場合はその内容を使用し、すでに回答されている項目は省略してください。その後、次の項目を確認します。
- REST、GraphQL、または両方ですか? REST のみのテストスイートでは、標準的な HTTP アサーションを使用します。GraphQL ではクエリ/ミューテーションビルダーが必要で、イントロスペクション差分のスナップショットが役立ちます。
- 認証方式は何ですか? JWT、API キー、OAuth 2.0、セッション Cookie では、それぞれ異なるフィクスチャ戦略が必要です。
- OpenAPI/Swagger の仕様はありますか? ある場合は、Zod スキーマを契約として自動生成し(
orval、openapi-zod-client)、Schemathesis による仕様駆動のファジングも検討してください。
基本原則
- 実装ではなく、契約をテストします。 内部ロジックやデータベースの状態ではなく、レスポンスの形状、ステータスコード、ヘッダーを検証します。
- スキーマ検証で、利用側に影響が出る前にドリフトを検出できます。 スキーマテストが失敗した場合は、フロントエンドに影響が及ぶ前に破壊的変更を検出できたということです。
- 認証フローもテスト対象です。 アプリケーションのログイン、ログアウト、有効期限、権限に関する契約をテストします。更新処理は、サポートされている場合にのみ実行してください。クライアント Cookie がクリアされたからといって、サーバーでセッションが失効したことにはなりません。
- 応答時間もテスト可能なアサーションです。 CI でパフォーマンスの低下を検出するほうが、本番環境でのインシデント対応より低コストです。
探索と自動化:ツール
API の探索(デバッグ、手動での調査、OpenAPI プレイグラウンド)と API の自動テストは、別の作業です。それぞれに適したツールを使用してください。
| ツール | 最適な用途 | 理由 |
|---|---|---|
| Bruno(v3.4+) | ファイルベースのコレクション、Git でレビュー可能なワークフロー、FOSS の Postman 代替 | ファイルシステムを中心に設計され、クラウド同期が不要です。gRPC、OAuth、GraphQL クエリビルダーに対応しています |
| Hurl(8.x) | プレーンテキストでの HTTP テスト、CI のスモークチェック | 1 つのファイルで複数のリクエストとアサーションを実行できます。curl が動作する環境であればどこでも実行でき、証明書と JSONPath(RFC 9535)クエリに対応しています |
| Hoppscotch | Web ベースの Postman 風の探索 | オープンソースで、ブラウザー上で動作し、手早いチェックに適しています |
Playwright APIRequestContext | テストランナーでの自動テスト | このスキルの対象です。以下で説明します |
| Supertest(Node)/httpx(Python) | 自分のアプリを対象としたインプロセス API テスト | 両側を管理できる場合、最も速くフィードバックを得られます |
チームに既存の導入実績がない限り、新しいプロジェクトで Postman/Insomnia を使うのは避けてください。ファイルベースのツール(Bruno、Hurl)は PR でレビューしやすく、コレクションにずれが生じても維持しやすいからです。
Playwright API テスト
APIRequestContext を使うと、ブラウザーを起動せずに単独の API テストを実行でき、ブラウザーコンテキストと Cookie/ストレージの状態を共有できます。次の用途に使用してください。
- 単独の API テスト —
request.get/post/...を使い、ステータス、ヘッダー、本文をアサーションで検証します。 - ブラウザーと API を組み合わせたテスト — API 経由でデータを用意し、それが UI に表示されることを検証した後、API 経由でクリーンアップします。
- 認証済みフィクスチャ — フィクスチャ内で一度ログインし、認証済みの
APIRequestContextをテストに渡して、テスト終了時に破棄します。トークンをハードコードしないでください。
playwright.config.ts、単独テスト、ブラウザーと API を組み合わせたテスト、認証済み API フィクスチャについては、references/playwright-setup.md を参照してください。
スキーマ検証
toHaveProperty で個々のフィールドをスポットチェックするのではなく、スキーマに照らしてレスポンスの形状を検証します。よく使われる方法は次の2つです。
- Zod 4 — スキーマを定義し、レスポンスに対して
safeParseを実行して、result.successをアサートします。失敗した場合は、正確な差分を確認できるようresult.error.issuesをログに記録します。Zod 4 ネイティブの文字列形式であるz.email()、z.uuid()、z.iso.datetime()を使います。チェーン形式のz.string().email()は非推奨で、削除が予定されています。 - AJV と JSON Schema — すでに JSON Schema(たとえば OpenAPI 仕様から生成したもの)がある場合は、
ajvとajv-formatsでコンパイルして検証します。
契約としてのスキーマ: API とテストの両方で同じスキーマファイルをインポートします。レスポンスの形状が変わると、コンシューマーテストがすぐに失敗します。OpenAPI 仕様がある場合は、スキーマを自動生成します(orval または openapi-zod-client)。仕様を先に作成するチームは、CI ジョブとして Schemathesis を追加し、稼働中の API に対して仕様を使ったファジングを行うことで、仕様に記載されていない形状やエッジケースでの 500 エラーを検出できます。
Zod 4、AJV、契約としてのスキーマ、Schemathesis の実装については、references/schema-validation.md を参照してください。
テストパターン
各エンドポイントについて、正常系テストに加えて、少なくとも1つのエラー系テストを作成します。よく使われるパターンは次のとおりです。
- CRUD ライフサイクル — リソースの作成、読み取り、更新、削除を行い、その後 404 を検証する
describe.serialブロックです。各ステップでリソース ID を引き継ぎます。 - 認証フロー — ログイン成功、無効な認証情報、有効期限切れ、ログアウト/失効、権限の境界をテストします。仕様に記載されたステータスと本文をアサートします。リソースによっては、他人の ID と存在しない ID に対して、意図的に区別できない 404 を返すことがあります。アプリケーションがトークンの更新に対応している場合は、トークン更新もテストします。
- エラーレスポンス — 400(不正な形式の本文)、422(フィールドの詳細を含む検証エラー)、429(レート制限と
retry-after)。正常系だけのテストスイートにしないでください。 - レスポンスヘッダー —
content-type、cache-control、レート制限関連のヘッダーを直接アサートします(実行されるとは限らない条件分岐の内側に置かないでください)。以下のパターンを参照してください。 - ページネーション — 1ページ目のメタデータ、範囲外のページに対する空のページ、無効なページサイズの拒否をテストします。
- ファイルのアップロード/ダウンロード — マルチパートアップロードと
content-dispositionヘッダーを検証します。 - GraphQL — 小さな
gqlヘルパーを用意し、クエリ/ミューテーション/無効なクエリ(エラー配列)のケースに加えて、削除されたフィールドを見逃さないようイントロスペクション差分のスナップショットを作成します。 - Webhooks — 使い捨ての HTTP サーバーを起動し、webhook を登録してイベントを発生させ、配信をアサートします。
上記のすべてのパターンとパフォーマンスのアサーションを実行できる形で記載した実装については、references/test-patterns.md を参照してください。
レスポンスヘッダー
ヘッダーには、キャッシュ指示、レート制限情報、コンテンツタイプ、CORS ポリシーなどの契約が含まれています。response.headers() を使ってアサートし、小文字の名前でインデックス参照します。実行されるとは限らない if (rateLimited) の内側にアサーションを置かないでください。
test('GET /api/users sets expected response headers', async ({ request }) => {
const response = await request.get('/api/users');
const headers = response.headers();
expect(headers).toBeDefined();
expect(headers['content-type']).toContain('application/json');
expect(headers['cache-control']).toBeDefined(); // "no-store" | "max-age=60" | ...
});
レート制限と retry-after のパターンについては、references/test-patterns.md(Response Header Validation)を参照してください。
パフォーマンスのアサーション
レスポンス時間とペイロードサイズもテストでアサートできます。たとえば、負荷の高いエンドポイントが定めた時間内(例:500ms)に応答すること、ペイロードがサイズ上限を超えないこと、同時リクエストが集中しても API で 5xx が発生しないことを検証します。コードについては、references/test-patterns.md の Performance Assertions セクションを参照してください。
ワークフローの証拠
HTTP の成功や最終的な正常状態だけでは、途中の遷移が誤っていることを見逃す場合があります。 期待される効果と、もっともらしい不具合を区別できる観測方法を選んでください。
- 失効: ログアウト前に有効なセッションを取得し、通常のクライアントを通じてログアウトした後、独立したコンテキストから古い認証情報を再送します。保護されたリクエストが拒否されることを検証してください。取得した認証情報はレポートやソース管理に含めないでください。
- 永続化: テスト対象の操作の直後、後続の書き込みによって状態が代わりに保存される前に読み取りまたは再起動します。再試行する前にロールバックを確認し、その後、正常に復旧することも確認してください。必要に応じて、明示的なテストサポートを備えた実際のアプリケーション/データベースの状態を使用してください。
- 計算値: 独立して値がわかっている単位値と、複数の組み合わせを使用します。集計結果が1つ正しくても、2つの誤りが相殺されている可能性があります。許容範囲内の境界値に加え、許容範囲外の値もテストしてください。
- 生の本文に対する署名: 送信する正確なバイト列に署名します。余分な空白を含む、有効だが非正規化された JSON 表現と、バイト列を改ざんした場合の拒否ケースを含めてください。検証前に解析して再シリアライズすることで、署名対象のメッセージが暗黙に再定義されてはなりません。
- 冪等性: 同時に発生した重複リクエストの後と再起動後に、永続化された業務上の効果が1つだけであることを検証します。同じキーでペイロードを変更した場合も確認してください。冪等な状態であっても、すべてのリクエストで同じステータスが返る必要はありません。契約上そう定められている場合、DELETE を繰り返すと、最初は 204、次は 404 が返ることがあります。
テストの品質を評価する際は、重要な各アサーションに対して、正常なコントロールと意図的に壊したコントロールを用意してください。コントロールの見落としは製品の不具合ではなく、カバレッジの不足として報告してください。
アンチパターン
1. 認証トークンのハードコード
トークンは期限切れになり、ローテーションされ、環境によって異なります。トークンを動的に取得するログインフィクスチャを使用してください。
2. 本番環境に対するテスト
API テストではデータを作成、変更、削除します。専用のテスト環境またはローカルインスタンスに対して実行してください。
3. エラーレスポンスを検証しない
正常系だけのテストスイートでは、拒否動作を見逃します。各エンドポイントで文書化されているエラーパスをテストし、禁止された副作用がないことを検証してください。すべてのエンドポイントで、すべての HTTP ステータスを要求する必要はありません。
4. ヘッダーを条件付きでしか検証しない
ヘッダーにはキャッシュディレクティブ、レート制限情報、コンテンツタイプ、CORS ポリシーが含まれます。該当するすべてのレスポンスで直接検証してください。if (rateLimited) の中に埋め込まれたチェックは実行されない可能性があり、何の証明にもなりません。
5. テストデータを作成した後にクリーンアップしない
リソースを作成して削除しないテストは、データベースを汚染します。afterEach/afterAll フックまたはフィクスチャのティアダウンを使用してください。
6. API テストを単体テストとして扱う
データベースをモックしないでください。API テストでは、利用者の視点から契約を検証します。自分たちが所有していない正当なサードパーティ(決済ゲートウェイ、外部 SaaS)のみをモックしてください。
7. 冪等性を無視する
PUT と DELETE は、繰り返し実行しても意図した状態を維持する必要があります。各試行について、エンドポイントで文書化されたレスポンス契約に従って、状態と副作用を確認してください。
完了条件
- 対象となるすべてのエンドポイントに、少なくとも正常系のテストが1つ、エラーパスのテスト(検証済みの 4xx または 5xx レスポンス)が1つあります。
- サポートされている認証フローをテストしています。正常なログイン、無効な認証情報、期限切れ、ログアウト/失効、文書化された権限境界を含めてください。リフレッシュが実装されている場合は、それも含めてください。
- Zod 4 または AJV を使用してレスポンスの形状に対するスキーマ検証アサーションを行っています。
toHavePropertyによる部分的なチェックだけでは不十分です。 - 少なくとも
content-typeと、API が設定するキャッシュ/レート制限ヘッダーを、条件を付けずに検証するアサーションがあります。 - 別のチームまたはサービスが利用するすべてのエンドポイントに対し、契約テストを用意しています(共有スキーマファイル。コンシューマー主導の検証には
contract-testingを使用してください)。 - 正当なサードパーティへの呼び出し(決済ゲートウェイ、外部 SaaS)はモック化または仮想化し、API とそのデータベースは実際に動作させています。
- テスト環境に対してスイートを実行する CI ジョブが終了コード 0(成功)で終了します。
参考ファイル(references/ 内)
- playwright-setup.md —
playwright.config.ts、単独の API テスト、ブラウザーと API を組み合わせたテスト、認証済みのAPIRequestContextフィクスチャ。 - schema-validation.md — Zod 4 と AJV/JSON-Schema によるレスポンス検証、スキーマを契約として扱うパターン、Schemathesis による仕様駆動型ファジング。
- test-patterns.md — 実行可能な CRUD ライフサイクル、認証フロー、エラーレスポンス、レスポンスヘッダー、ページネーション、ファイルのアップロード/ダウンロード、GraphQL(+イントロスペクションの差分)、Webhook、パフォーマンステスト。
関連スキル
- contract-testing — Pact/ブローカーを使用したコンシューマー主導の契約検証。別チームが API を利用していて、共有スキーマだけでなく互換性を保証する必要がある場合に参照してください。
- playwright-automation — ブラウザーベースの E2E テスト、Page Object Model、ブラウザーと API を組み合わせたパターン。
- ci-cd-integration — CI パイプラインでの API テストスイートの実行、並列化、環境管理。
- test-strategy — API レイヤー、ユニットテスト、E2E のそれぞれで何をテストするかの判断。