GraphQL APIテスト:完全ガイド

GraphQL APIはREST APIとは異なる特性を持っており、効果的にテストするにはその違いを理解する必要があります。GraphQLを強力にする柔軟性——クライアントが必要なデータだけをリクエストできること、任意のクエリ合成、リアルタイムサブスクリプション——は、RESTを前提としたツールや戦略では十分に対応できないテスト上の課題も生み出します。
本ガイドでは、GraphQL APIのテストを体系的に解説します。テストすべき内容、最適なツール、そしてGraphQLテストをCI/CDに統合する方法を網羅しています。
GraphQLテストがRESTと異なる点
単一エンドポイント、無限のクエリ
REST APIは個別のエンドポイントを公開します:GET /users、POST /orders、PUT /products/:id。各エンドポイントにはリクエストとレスポンスの形式が定義されており、テスト対象を列挙できます。
GraphQL APIは単一エンドポイント(通常は /graphql)を公開し、任意のクエリを受け付けます。考えられるクエリの数は理論上無限であり、すべてのクエリの組み合わせをテストすることは不可能です。代表的なカバレッジを戦略的にテストする必要があります。
契約としてのスキーマ
GraphQLの型システムは厳密なスキーマを定義します。すべてのフィールドには型があり、すべてのクエリはスキーマに準拠しなければなりません。スキーマはサーバーとクライアント間の契約として機能するため、スキーマが期待通りであることを検証するスキーマテストは特に重要です。
スキーマの破壊的変更(フィールドの削除や型の変更)は、そのフィールドに依存するすべてのクライアントを静かに壊す可能性があります。スキーマのリグレッションテストは、GraphQL APIにおける最重要課題のひとつです。
N+1クエリのパフォーマンス
GraphQLのネストされたクエリ機能は、リゾルバーがデータローダーを使って実装されていない場合、N+1のデータベースクエリを引き起こす可能性があります。これは導入しやすく、機能テストでは検出できないパフォーマンスバグです——APIは正しいデータを返すものの、大規模時には壊滅的なパフォーマンス低下を招きます。N+1パターンのテストには、特別な注意が必要です。
GraphQLテストの種類
スキーマテスト
GraphQLスキーマが破壊的な方法で変更されていないことを確認します。graphql-inspectorなどのツールを使ってスキーマを比較し、変更を「非破壊的(フィールドの追加)」「潜在的に破壊的(フィールドの非推奨化)」「破壊的(フィールドの削除や名前変更)」に分類できます。
CIでスキーマ比較を実行し、破壊的変更がデプロイ前に検出されるようにします:
破壊的なスキーマ変更には、デプロイゲートを設ける必要があります。メジャーバージョンのバンプ、クライアント移行の検証、またはすべてのクライアントが更新済みであることを確認した明示的な承認のいずれかが必要です。
クエリテスト
GraphQLサーバーに対して、特定のクエリとミューテーションをテストします:
認可テスト
GraphQLのフィールドレベルの解決は、細かい粒度の認可の機会を提供する一方で、細かい粒度の認可バグも生み出します。以下の点をテストしてください:
- 未認証のリクエストがデータではなく適切なエラーを返すこと
- ユーザーが自分自身のデータにのみアクセスでき、他のユーザーのフィールドにはアクセスできないこと
- 管理者専用フィールドが一般ユーザーからアクセスできないこと
- ネストされたクエリが認可をバイパスしないこと(よくあるGraphQL固有の脆弱性:認可されたフィールドが、そのフィールド自体は認可されていない関連オブジェクトに解決される場合)
エラーハンドリングテスト
GraphQLには固有のエラーレスポンス形式があります:HTTPステータス200の成功レスポンスのボディに errors 配列が含まれます。リゾルバーが、無効な入力・リソース未検出・認可エラーに対して正しいエラー形式を生成することをテストしてください。
多くのGraphQL APIは、本来4xx HTTPステータスコードを返すべきケースに対して、誤って200とエラーレスポンスを返しています。GraphQL仕様ではこれが許容されていますが、一部のクライアントやプロキシは正しく処理できません。
パフォーマンスとN+1テスト
ネストされたデータを含むGraphQLクエリごとに、リゾルバーがデータローダーを使用してデータベースクエリをバッチ処理していることを確認してください。ユーザー一覧とその投稿を取得するクエリは、N+1件のデータベースクエリ(ユーザーごとに1件)を実行すべきではありません。
テスト環境でクエリ数をログに記録し、上限を検証する方法が最も実用的なアプローチです。
サブスクリプションテスト
GraphQL APIがサブスクリプション(WebSocket経由のリアルタイムデータ)を使用している場合、以下の点をテストしてください。
- ミューテーション発生時にサブスクリプションが正しいイベントを受信すること
- サブスクリプション接続に認証が適用されていること
- クライアント切断時にサブスクリプションが正しくクリーンアップされること
CI/CDにおけるGraphQLテスト
GraphQL APIのCI/CDテストセットアップ:
- スキーマのリグレッションチェック — PRごとに実行され、スキーマをmainブランチと比較し、破壊的変更が検出された場合に失敗します
- リゾルバーのユニットテスト — リゾルバーロジックを対象とした高速かつ独立したテスト
- クエリ/ミューテーションのインテグレーションテスト — テストデータベースに対して実行し、主要な操作を網羅します
- GraphQLを利用するUIフローのE2Eテスト — TestSpriteは、GraphQL APIを使用するフロントエンドフローをテストする際にこれらを自動的にカバーします
TestSpriteのAPIテストカバレッジには、標準のテスト生成の一環としてGraphQLエンドポイントが含まれています。要件を読み込んでGraphQLの使用を検出すると、手動でのテスト作成なしに、クエリ機能・認可の適用・エラーハンドリングを網羅するテストケースを生成します。
GraphQL APIテストをCI/CDパイプラインに追加する →