GraphQL APIテスト:完全ガイド

Yunhao Jiao
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テストセットアップの例:

  1. スキーマのリグレッションチェック — PRごとに実行され、スキーマをmainブランチと比較し、破壊的変更が検出された場合に失敗
  2. リゾルバーのユニットテスト — リゾルバーロジックを対象とした高速な独立テスト
  3. クエリ・ミューテーションの統合テスト — テスト用データベースに対して、コアオペレーションを網羅
  4. GraphQLを利用したUIフローのE2Eテスト — GraphQL APIを使用するフロントエンドフローのテスト時に、TestSpriteが自動的にカバー

TestSpriteのAPIテストカバレッジには、標準のテスト生成の一環としてGraphQLエンドポイントが含まれています。要件を読み込んでGraphQLの使用を検出すると、手動でのテスト作成なしに、クエリ機能・認可の適用・エラーハンドリングをカバーするテストケースを自動生成します。

GraphQL APIテストをCI/CDパイプラインに追加する →