マニュアル QA (品質保証)手動 QA エンジニア

レガシー **REST** API から **GraphQL** スキーマの移行を検証する際、異なるバージョンのサポートライフサイクルを持つ異種モバイルクライアントにサービスを提供する場合、後方互換性を確保しながら非推奨フィールドの使用が適切なグレースフルデグレーションメカニズムをトリガーすることを確認するために、どのような体系的な手動テスト戦略を展開しますか?

Hintsage AIアシスタントで面接を突破

質問への回答

最初に、Charles Proxy または Burp Suite を使用して生産トラフィックを傍受し、各モバイルクライアントバージョンがどの特定のフィールドを消費しているかを文書化することで、体系的なバージョンマトリクス手法を確立し、iOSAndroid アプリのバージョンと GraphQL スキーマフィールドを相関させる依存関係マップを作成します。手動クエリを作成して従来のクライアントリクエストを模倣することにより契約検証された探索的テストを実行し、非推奨フィールドに意図的にヌル値を注入して、モバイルクライアントがデータ欠如をエラーバウンダリを通じて処理することを確認して、アプリケーションがクラッシュしないことを確認します。Postman コレクションを通じて REST および GraphQL リクエストを並行して実行するシャドウテストを実施し、応答ペイロードの意味的同等性を比較し、非推奨ヘッダーと @deprecated 指示子がクライアント側のログ記録をトリガーすることでユーザーインターフェースが壊れないことを監視します。

生活からの状況

問題の説明

私たちの e コマースプラットフォームは、推奨エンジンをサポートするために製品カタログを REST エンドポイントから統一された GraphQL スキーマに移行していましたが、2019年にリリースされたバージョン12.4(iOS)以降と API レベル28(Android 9)までのバージョンをサポートしており、15以上のアクティブなアプリバージョンのマトリックスを作成して様々な GraphQL クライアント機能を持っていました。重要なリスクは、iOS v14.2 クライアントが非推奨の productVariants フィールドに依存していたため、これが productOptions に置き換えられていた場合、非推奨ウィンドウ中に予期しないヌル値を返されると、Swift のパーシングロジックがアプリケーションを強制終了させてしまうことでした。さらに、Apollo Client v2.5 を使用する Android クライアントは、ヌル可否を iOSAlamofire 実装とは異なる方法で扱うため、同じスキーマの変更が一方のプラットフォームでは音沙汰無くデータが破損し、他方ではクラッシュを引き起こす可能性がありました。

ソリューション 1: 包括的なエンドツーエンド回帰テスト

すべてのサポートされている OS バージョンで物理デバイスに対してフル回帰スイートを実行し、製品カタログフローを手動でナビゲートして、すべてのプラットフォームで視覚的一貫性とデータ整合性を確認することを検討しました。このアプローチは、ユーザーが目にする機能が正しく動作することを絶対的に保証し、GraphQL データバインディングに関連するプラットフォーム特有の UI グリッチをキャッチすることができます。しかし、これには40以上の物理デバイスへのアクセスと、おおよそ3週間のテスト時間が必要であり、私たちの2週間の移行期限を超え、特定のネットワーク条件下でのみ現れる微妙な API 契約違反の検出を保証するものではありませんでした。

ソリューション 2: モッククライアント応答を用いた API 契約テスト

二つ目のアプローチでは、PostmanMockoon を使用してレガシーモバイルクライアントによって送信される正確なクエリ構造をシミュレートし、GraphQL スキーマが歴史的な REST ペイロード構造に一致する文法的に正しい JSON 応答を返すことを検証しました。この方法は大幅に迅速であり、3日以内にすべてのバージョンの組み合わせをテストできましたが、非推奨ヘッダーとフィールドのヌル可否の正確な検証を提供しました。残念ながら、この純粋に合成的なテストでは、iOSSwift Codable プロトコルが予期しないヌルと欠損キーに対して失敗するなどの重要なプラットフォーム特有のパーシング動作を見逃してしまいました。

ソリューション 3: 生産分析を用いたリスクベースのインターセプトテスト

最終的に、私たちは Firebase Analytics データを分析して、プラットフォームごとのアクティブユーザーベースの85%を占める上位3つのOSバージョンを特定し、Charles Proxy を使用してライブトラフィックを傍受し、REST 応答を GraphQL クエリに書き換えながらクライアントの安定性を監視するハイブリッド戦略を選択しました。これにより、実際のクエリパターンとネットワーク遅延条件をテストし、高影響なバージョンの組み合わせに手動検証労力を集中させることができ、エッジケースに対する自動化された契約テストで補完されました。この方法は、リスクカバレッジと時間の制約のバランスをとりながら、移行が大多数のユーザーに影響を与えないという自信を提供し、iOS のヌル処理バグのような特定の互換性問題を特定しました。

選択されたソリューションと結果

私たちは、手動テストを iOS 14.2、15.0、16.0 と Android 10、11、12 に集中させ、Charles Proxy を使用して productVariants フィールドがヌル値を返すことをシミュレートし、クラッシュを監視しました。iOS v14.2 のテスト中、非推奨フィールドがヌルを返すと、クライアントアプリがフォールバックの UI を表示するのではなく、EXC_BAD_ACCESS エラーでクラッシュすることを発見しました。これにより、Swift のエラーバウンダリが GraphQL エラー応答を誤って解析していることが明らかになりました。この問題を重大な欠陥として文書化し、サーバー側のスキーマ変更を実装して、ヌル値の代わりに非推奨警告付きの空の配列を返すことにし、GraphQL エラー率をアプリバージョンごとに分けて監視アラートを設定しました。移行はサポートされたバージョンでゼロクラッシュで進行しました。

候補者がよく見逃すこと

手動テスト中にサーバーサイドのログや自動負荷テストツールにアクセスできない場合、GraphQL クエリの深さ制限と複雑性スコアリングが適切に施行されていることをどのように確認しますか?

多くの候補者は、GraphQL セキュリティテストには自動スクリプトが必要であると仮定しますが、手動テスターは GraphiQLInsomnia を使用して、意図的に循環参照や深くネストされたオブジェクトを作成し、DoS 保護メカニズムをトリガーするためのネストされたクエリを構築できます。API が特定のエラーコード(GRAPHQL_VALIDATION_FAILEDQUERY_TOO_COMPLEX)を返すことを確認し、複雑性計算がエイリアスが使用されている場合にフィールドの倍率を正しく考慮しているかをテストします。この手動検証は、サーバーの複雑性分析がリクエストされたフィールドを正確にカウントし、設定された閾値を超えるクエリをデータベースリソースを消費する前に拒否することを保証します。

さらに、候補者は、永続クエリ(許可されたクエリホワイトリスト)が本番環境で任意の手動クエリを拒否することをテストすることを忘れがちであり、これがリソース枯渇攻撃を防ぐために重要です。これは、Postman を通じて永続クエリハッシュから逸脱するアドホッククエリを実行し、サーバーがクエリを実行する代わりに PersistedQueryNotFound エラーを返すことを確認することで検証できます。このセキュリティバウンダリは、攻撃者がシステムのパフォーマンスを正当なユーザーのために悪化させるリソース集約型クエリを作成するのを防ぎます。

複数のマイクロサービスが同じエンティティタイプにフィールドを追加するときのGraphQL** スキーマのストッチングやフェデレーションのテストに対する体系的アプローチは何ですか?特に、あるサービスが劣化しているときのエラー伝播に関して。**

Apollo Federation やスキーマストッチングアーキテクチャにおいて、初心者はそれぞれのサービスを単独でテストし、Authentication Service(重要)と Preferences Service(非重要)からフィールドが組み合わさった User タイプの部分的な失敗をテストするのを見逃します。Chaos Monkey テクニックを使用して下流サービスの失敗を手動でトリガーするか、特定のエンドポイントを Charles Proxy でブロックし、その後 Gateway がヌルフィールドと errors 配列内の特定のエラーパスを持つ部分データを返すことを検証する必要があります。これにより、連携層の回復力が検証され、重要なユーザージャーニーが非重要サービスがダウンしたときでも機能し続けることが保証されます。

重要な洞察点は、@defer 指令と @stream 指令が、全体の UI をブロックせずに遅延解決フィールドを正しく処理し、クライアントが特定のコンポーネントに対してフォールバックコンテンツを表示するためにアクション可能なエラーメタデータを受け取ることを確認することです。テスターは、GraphQL 応答の extensions 部分に、どの特定のマイクロサービスが失敗したかを示す正確なサービストレーシング情報が含まれていることを確認し、フロントエンドが劣化状態で非表示にするコンテンツと表示するコンテンツを適切に判断できるようにします。適切なエラー伝播テストは、ユーザーが補足機能(推奨や分析など)が一時的に利用できないときでも、コアトランザクションを完了できることを保証します。

どのようにして意図したGraphQLのヌル可否(実際にヌルになり得るフィールド)と、Apollo CodegenGraphQL Codegen のようなコード生成ツールを使用したアプリケーションをテストする際の実際の欠陥を区別しますか?

候補者は、ビジネスロジックが実際には必要なフィールドをオプション(ヌル可)としてマークする生成された TypeScript または Swift タイプに苦しむことが多く、ヌル値がバグを表しているのか有効な空の状態を示しているのか混乱を招くことがあります。スキーマの感嘆符(!)と生成されたクライアントタイプを調査し、Charles ProxyJSON 応答を手動で操作してヌル値を非ヌルスキーマフィールドに注入することで、サーバーが応答をクライアントに送信する前にデータを適切に検証するかを確認する必要があります。この区別は重要であり、非ヌルスキーマフィールドのヌルはサーバー側の欠陥を示し、ヌルの可否フィールドのヌルはデータの正当な欠如を示す可能性があります。

さらに、クライアントアプリケーションがスキーマ駆動のヌル可否を正しく処理していることを確認するために、潜在的にヌルフィールドにアクセスする際に TypeScript 厳密モードコンパイルが成功することを確認し、生成されたタイプが実行時のヌルポインタ例外から実際に保護していることを保証する必要があります。これは、GraphQL の非ヌルフィールドがサーバーからヌルを返すことが決してない一方、ヌルフィールドはビジネスロジックの仮定に関わらずクライアントコードのオプショナルチェイニングやヌルチェックで常に処理されなければならないことを理解する必要があります。開発者はビジネスロジックがデータが常に存在するを示唆している場合に防御的チェックを追加することをしばしば忘れるため、ヌル注入の厳密な手動テストが潜在的なクラッシュを本番ユーザーに達する前にキャッチするのに役立ちます。