QAエンジニアの面接:曖昧な仕様からテスト設計と優先順位を説明する
Quick Overview
QAエンジニアの面接に向け、研修予約のキャンセルという独自ケースで仕様確認、期限の境界値、並行取消、再現できる欠陥報告、リスクに基づく判断を練習します。ローカルHTTP検証の29項目と未検証の範囲を区別します。
「予約をキャンセルできるようにしました。どうテストしますか」。QAエンジニアの面接でこの問いを受けたら、正常系と異常系を並べる前に、何を正しい結果とするかを確認しましょう。「開始24時間前まで」という一文だけでは、ちょうど24時間前の操作、連打、通知失敗の期待結果が決まりません。
この記事では、研修予約のキャンセルを題材に、仕様の確認から境界値、並行実行、欠陥報告、リリース判断までをつなげます。面接で伝えたいのはテスト件数よりも、確認したルールがどの検証と判断につながるかです。
根拠の区分: テスト技法や報告の考え方はISTQBなどの公式資料を参照します。予約ルール、コード、回答例はPracHubが作成した独自の練習です。特定企業の選考を再現したものではなく、候補者の体験談も使用していません。採用側が必ず同じ順序で評価する、という主張でもありません。

仕様が曖昧なとき、最初に何を聞くか
まず「誰が、どの予約を、いつ、どの状態から変更するのか」を分けます。「キャンセルできますか」だけでは会話が止まるので、期待結果が変わる具体例を添えます。
| 確認する点 | 面接での聞き方 | 決まるテスト |
|---|---|---|
| 締め切りの一致 | 開始24時間前ちょうども受け付けますか | 境界の前・一致・後 |
| 時刻の基準 | 判定はサーバー時刻ですか。表示時刻との関係は | 同一時点の異なるオフセット |
| 対象と権限 | 自分の予約だけですか。管理者操作は別ですか | 他人の予約、権限不足 |
| 再送 | 成功応答を受け取れず再送したら、何を返しますか | 同じ予約の繰り返し操作 |
| 並行実行 | 二つの端末から同時に取り消すとどうなりますか | 席の返還回数と状態の整合性 |
| 通知失敗 | メール送信に失敗したら、予約まで元に戻しますか | 状態と通知の切り分け |
ここで全部の仕様が確定するとは限りません。未回答の項目には仮定と影響を書き、確認が必要な相手を示します。権限が不明なら「所有者だけが操作できる想定でケースを作ります。管理者の例外は未確認です」と伝えます。仮定を実装済みの仕様として扱わないことが大切です。
公式資料では、ISTQB CTFL v4.0.1が境界値分析やデシジョンテーブルなどを扱っています。以下はその考え方を使った独自ケースであり、公式試験問題ではありません。ISTQB公式シラバス
練習用の判定基準を短く固定する
今回は「定員1名の研修に、予約B7が1件ある」状態から始めます。初期状態は confirmed、空き席は0です。次を練習用の合意事項とします。
- 開始日時は
2026-10-12T12:00:00Z。期限は24時間前の2026-10-11T12:00:00Zで、一致を含めてキャンセルできます。 - 初回の成功で
cancelledに変更し、空き席を1つ返します。同じ予約を繰り返し取り消しても、追加では返しません。 - すでにキャンセル済みなら、期限後の再送でも現在の状態を返します。期限後に未キャンセルの予約を初めて取り消す場合は拒否します。
- 通知に失敗してもキャンセル結果を保持し、通知待ちを記録します。
APIは POST /cancel、本文は {"bookingId":"B7"} とします。成功・再送は200、未知の予約は404、不正な入力は400、未キャンセルの予約に対する期限後の操作は409とする設計です。これらは本ケースの選択であり、すべての予約APIに要求される応答ではありません。
RFC 9110では、冪等性を同じリクエストの反復による意図したサーバー側の効果で説明しています。POSTというメソッド名だけで冪等性が保証されるわけではありません。本ケースでは、同じ予約の取消操作を繰り返しても席を重複返還しないよう設計します。HTTPの公式仕様
面接では、この短い契約を書いてからテストに移ると、「なぜその結果を期待するか」という追問に、合意したルールを使って答えられます。実際の開発なら担当者の確認を得て管理対象の仕様に反映します。ここで書いたルールを、そのまま現実のサービスへ適用してはいけません。
境界値は時刻と状態を一緒に確かめる
期限だけを確認しても、状態が変わったかは分かりません。次の表では各行を独立に実行し、初期状態を毎回リセットします。「同じ予約を順番に全部操作する表」ではありません。
| ケース | 判定に使う時刻 | HTTP | 実行後の状態・空き席 |
|---|---|---|---|
| 期限の1秒前 | 2026-10-11T11:59:59Z | 200 | cancelled・1席 |
| 期限と一致 | 2026-10-11T12:00:00Z | 200 | cancelled・1席 |
| 期限の1秒後 | 2026-10-11T12:00:01Z | 409 | confirmed・0席 |
| 一致と同じ時点を日本のオフセットで表現 | 2026-10-11T21:00:00+09:00 | 200 | cancelled・1席 |
| オフセットのない時刻 | 2026-10-11T12:00:00 | 400 | confirmed・0席 |
Python公式ドキュメントは、日時をタイムゾーン情報の有無によってawareとnaiveに分けています。この練習では、基準の曖昧なnaive時刻を拒否し、aware時刻同士で比較します。Python datetime公式資料
ただし、表の時刻は利用者がAPI本文で自由に送る値ではありません。テスト用の時計をサーバー内部へ注入しています。本番環境で利用者指定時刻を信頼する設計に置き換えると、締め切り判定を回避されるおそれがあります。画面表示のローカル時刻と、サーバーの判定時刻も別に確認します。
「1秒前を試しました」と答えるだけでなく、時刻の精度が秒なのかミリ秒なのかも確認しましょう。本実装は日時を比較しますが、表で検証した代表値は秒単位です。夏時間を含む表示や時計のずれ、複数サーバー間の時刻管理は、この表だけで検証済みとは言えません。
連打と並行実行では、壊れ方が違う
順番に二回操作した結果が正しくても、同時実行に耐えるとは限りません。欠陥版は「まだキャンセルされていない」と確認した後、更新までの間に別の処理が入れます。
初期: B7=confirmed / available=0
A: confirmed を確認
B: confirmed を確認
A: cancelled に更新し、空き席を +1
B: cancelled に更新し、空き席を +1
結果: B7=cancelled / available=2
状態名だけを見ると成功に見えます。しかし定員1名の研修で空き席が2となり、整合性が壊れています。二つのHTTP応答が200であること自体をバグとする必要はありません。合意した契約では、二回目に現在のキャンセル状態を返すのは正しい動作です。
修正版は、キャンセル済みかの確認と、状態・空き席の更新を一つの保護区間にまとめます。二回目は更新済みの状態を読み、追加の返還を行いません。本ケースでは一つのプロセス内のロックを使いますが、複数プロセスや複数サーバーにその保証が広がるわけではありません。

実行した結果と、まだ確認していない範囲
Python 3.12.14のローカルHTTPサーバーへ実際にリクエストを送り、29項目のアサーションを実行しました。結果は29項目すべて成功しました。欠陥版についても、意図した空き席2の再現を確認した結果であり、欠陥版を合格と判定したわけではありません。内訳には期限の代表値、再送、未知の予約、不正な本文、並行取消、通知失敗時の状態確認を含みます。
| 実行対象 | 並行リクエストの応答 | 最終空き席 | 記録された通知数 |
|---|---|---|---|
| 意図的な欠陥版 | 200、200 | 2 | 2 |
| 一つの保護区間で処理する修正版 | 200、200 | 1 | 1 |
| 通知失敗を注入した修正版 | 初回・再送とも200 | 1 | 0、通知待ちあり |
欠陥版では、二つの処理が確認を終える位置を同期させ、問題の順序を意図的に再現しました。これは再現条件を固定した検証であり、「現実の利用で何%発生するか」を測る負荷試験ではありません。29項目という数字も、全品質の保証や29種類の独立した業務シナリオを意味しません。
通知失敗時は状態を保持するところまで実装・検証しました。実メールの配信や再試行処理はありません。認証、データベース、プロセス停止後の復元、画面操作、分散環境の同時実行も対象外です。面接で検証結果を説明する際は、実行した範囲と追加検証が必要な範囲を分けます。
他の人が再現できる欠陥報告を書く
公式資料でも、欠陥報告には環境、再現に必要な情報、期待結果と実際の結果、重大度や修正優先度などが含まれます。以下は本ケースの観測結果を使った報告例です。ISTQB CTFLの欠陥管理
件名: 同一予約の並行キャンセルで、定員1名に対する空き席が2になる。
環境・前提: Python 3.12.14、ローカルHTTP、インメモリ保存。欠陥版を使用し、B7はconfirmed、空き席0、時計は期限と一致する時点に固定。実際の利用者や予約データは使わない。
再現手順: 初期状態を作成し、二つのクライアントから同じB7への POST /cancel を開始する。テスト用の同期点で両方が状態確認を終えるまで待ち、更新へ進ませる。両方の応答と、処理完了後の保存状態・空き席・通知数を取得する。
期待結果: 両方が現在のキャンセル状態を返してよい。空き席は1、通知に相当する記録は1件である。
実際の結果: 両方200、最終状態cancelled、空き席2、通知記録2件。確認と更新を分けた経路で再現し、同じ予約B7・期限一致・二つのリクエストを使った修正版では空き席1となった。
影響と提案: 在庫の整合性を壊し、後続の予約受付に影響し得るため重大度は高いと提案する。実環境での頻度や影響範囲は未測定。修正優先度はリリース範囲や回避策と合わせて関係者が決めるが、取消機能を公開する前の対応を推奨する。
報告を受けた人が追加で推測せず再現できるように、状態と時刻を明記します。逆にログを大量に貼っても、期待結果がなければ判断できません。最小データ、実行条件、比較する値をそろえましょう。実務のログでは個人情報や認証情報を除き、必要な識別子と時刻を残します。
時間が足りないときの順序とリリース判断
本ケースでは、取消の可否、席の整合性、再送の安全性を優先して確認します。これは想定リスクに基づく推奨順序であり、全組織共通の採点表ではありません。限られた時間なら、次のように理由を添えます。
| 順序 | まず確認すること | 判断に使う理由 |
|---|---|---|
| 1 | 期限内・一致・期限後の状態と空き席 | 受付条件と基本の状態変更が誤ると機能の前提が崩れる |
| 2 | 同じ予約の再送と並行取消 | 一件の操作から席が重複返還される経路を防ぐ |
| 3 | 通知失敗時に取消結果を保持できるか | 利用者への通知と業務状態の不一致を把握する |
| 4 | 権限・永続化・実環境での同時実行 | ローカル模型では保証できない公開前の重要項目 |
| 5 | 表示文言や各画面の操作 | 実際の利用と復帰操作を確認する。誤操作を招く表示なら繰り上げる |
この順序は、権限が最後でもよいという意味ではありません。今回のローカル実装に権限処理がないため、公開判断には別の検証が不可欠です。実際に他人の予約を取り消せる疑いがあれば、権限確認を最優先にします。影響と根拠が変われば順序も変えます。
欠陥版については、席の重複返還が残る状態で取消機能を公開しないと提案します。修正版の29項目成功後も、本番リリース可能とは結論づけません。共有データベースでの更新保証、認証・認可、通知待ちの復旧、運用監視を確認する必要があります。
条件付きで進めるなら、「どの範囲を対象にするか」「誰が残余リスクを受け入れるか」「何を検知したら停止・復旧するか」を記録します。機能を止めるだけで壊れた席数が直るわけではないため、整合性の確認と修復手順も分けて用意します。
面接の回答を、証拠の順に組み立てる
回答例は次のようにつなげられます。「まず締め切りの一致、再送、通知失敗の期待結果を確認します。今回は一致を許可し、取消済みの再送は状態を返す契約にします。前・一致・後の時刻に加え、空き席が一回だけ戻ることを確認します。並行取消で空き席2を観測したら、HTTP成功だけで合格にせず整合性の欠陥として報告します。修正後は同じ再現条件で確認し、実環境の保存や権限は追加検証として残します」。
追問で「自動化しますか」と聞かれたら、期待値が固定できる期限と状態の回帰チェックを自動化候補に挙げます。画面の理解しやすさや未確定要件の探索は、別の確認として説明できます。自動化の有無より、何を検出し、何を検出できないかを言えるようにしましょう。
過去の経験を話すときも同じです。自分が仕様を確認した範囲、設計・実行したテスト、開発者や事業担当と決めた内容を区別します。「チームで改善した」を自分一人の成果にせず、判断に使った証拠と担当範囲を具体的に説明してください。
PracHubで次の追問を練習する
次の問題は、同じ企業のQA選考セットではありません。本記事の仕様確認、API、テスト層、並行処理を別の条件へ移して説明するために選んでいます。問題本文の条件を先に読み、本記事の予約ルールを持ち込まないようにしてください。
| PracHubの問題 | 本記事から持ち出す練習 |
|---|---|
| Testing a New Feature: Planning Test Cases and Handling Flaky Tests | 重要な条件を選び、不安定な結果の調査を説明する |
| Write good tests and define integration tests | 関数の確認とHTTP経由の確認の範囲を分ける |
| Contrast UI vs backend testing; design UI-change test cases | バックエンドの状態確認で画面検証を代替しない |
| Design Interviewer Availability and Atomic Booking APIs | 予約の原子的な更新と整合性を考える。閲覧条件の表示あり |
| Code Review of a Multi-File HTTP API: Wrong Method, Payload and Validation Bugs | 入力の問題と状態変更の問題をコードで区別する |
まずはこのケースの期待結果を手元にまとめてから、新機能のテスト計画を立てる問題で、確認したい仕様を三つ挙げ、その答えに応じて期待結果がどう変わるかを声に出して説明してみてください。ケースを増やす前に判定基準を決める練習になります。
Sources and Further Reading
- ISTQB Certified Tester Foundation Level Syllabus v4.0.1 — テスト技法、リスク、欠陥管理の公式資料。
- Python datetime: aware and naive objects — 時刻比較の前提を確認する公式資料。
- RFC 9110: Idempotent Methods — HTTPの冪等性の定義。予約ルールや応答コードの独自契約とは区別する。
Comments (0)