3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【QA実務】API × DB整合性チェックでバグを潰す 〜SQLで検証するテスト戦略〜

3
Posted at

はじめに

E2EテストやUIテストだけで「問題なし」と判断したにも関わらず、リリース後にデータ不整合のバグが発覚した経験はないでしょうか。

実務において、以下のような「画面の見た目に騙される」ケースは少なくありません。

  • 画面上は正常に表示されているが、DBの値が誤っている
  • APIレスポンスとDBの格納内容が一致していない
  • ユーザーの連続操作によって、裏側でデータの先祖返りが起きている

本記事では、こうした「見えないバグ」を防ぐための API × DB観点でのテスト戦略 について、実務ベースの事例を交えて解説します。


なぜUIテストだけでは不十分なのか

UI(画面)はあくまで「内部処理の結果の一部」を出力しているに過ぎず、システムの正しい状態を100%保証するものではありません。

事象 原因
画面上はエラーに見えない フロントエンド側のフォールバック処理がAPIの失敗を隠蔽している
画面に「成功」と表示される DBへの保存処理が失敗・ロールバックされている
リロードで古いデータが表示される 非同期処理の影響で画面が古い状態に上書きされる

「見た目が正しい = データが正しい」ではない という前提に立つことが、QAエンジニアにとって非常に重要です。


実務で遭遇したバグ事例

ケース:価格履歴の取得ロジック不具合(不動産システム)

不動産系システムにおいて、物件の価格履歴テーブルから「最初の価格(基準価格)」を特定して画面に表示するロジックに不具合がありました。

🚨 発生していた事象

  • 同一の物件に対して、複数の価格変更履歴が存在する
  • データの移行(マイグレーション)や過去の仕様変更の影響で、変更日(changed_date)が NULL のデータが混在している
  • システムの自動一括更新により、作成日時(created_at)が完全に同一のレコードが複数存在する

この状況下で、従来のテスト(正常なデータパターンのみの画面確認)では気づけなかったバグが発生しました。

❌ 原因となった不十分なSQLロジック

開発環境のソースコード(裏側のクエリ)を確認すると、以下のような単純なソートになっていました。

ORDER BY changed_date ASC

この条件では、以下の問題が発生します。

  • NULL の扱い(先頭に来るか、末尾に来るか)が RDBMS の仕様や設定依存になり不明確
  • 日時が完全に同一であるレコードの優先順位が不定(ランダム)になる

結果として、「画面を開くたびに、または環境によって、表示される歴史的価格が変わる」 という致命的なデータ不整合(flakyなバグ)を引き起こしていました。

✅ 改善アプローチ(QA視点でのロジック指摘)

仕様を明確化し、以下のようにソート順の優先順位を厳密に定義(Window関数の導入など)するよう修正を依頼しました。

SELECT 
  *,
  ROW_NUMBER() OVER (
    PARTITION BY trn_property_id
    ORDER BY 
      changed_date IS NULL ASC, -- NULLを明確に末尾(または先頭)に制御
      changed_date ASC,         -- 日付順を明確化
      created_at ASC            -- 同一日時の場合はIDや作成順で一意に決定
  ) AS rn
FROM trn_property_prices;

修正のポイント

  1. NULL の評価順を明確に制御した
  2. 日付が同じ場合のセカンドキー(created_at)を指定し、取得結果の決定論的(Deterministic)な一意性を担保した

API × DB テスト戦略:実務で使える5つのチェックポイント

裏側のデータまで品質を担保するために、QAチームが実践すべきアクションです。

1. APIレスポンスとDBを必ず「突き合わせる」

画面のテキストを見るだけでなく、開発者ツール(Networkタブ)でAPIの生のJSONレスポンスを確認し、それが実際のDBレコードと1対1で整合しているかをSQL(LEFT JOIN などを用いた不整合チェッククエリ)で直接検証します。

-- 例:APIが返すIDに対応するDBレコードが存在するかチェック
SELECT 
  api.id,
  db.id AS db_id,
  CASE WHEN db.id IS NULL THEN '❌ 不整合' ELSE '✅ 一致' END AS status
FROM api_response_ids api
LEFT JOIN actual_table db ON api.id = db.id;

2. ステータスコードだけで「正常」と判断しない

APIが 200 OK{"status": "success"} を返していても、中身のデータが欠損していたり、型(String型とInt型の取り違えなど)が誤っているケースがあります。レスポンスボディのスキーマ検証まで踏み込みます。

200 OK ≠ データが正しい。レスポンスボディのスキーマと値まで必ず検証する。

3. 境界条件・異常データ(境界値)を直接インプットする

UIの入力バリデーションをバイパスして、APIツール(Postmanなど)やDB操作を通じて以下のデータを直接投入し、システムの挙動を確認します。

投入パターン 確認観点
NULL / 空文字 "" デフォルト値処理・エラーハンドリング
特殊文字・全角半角混在 エスケープ処理・文字化け
重複するユニークキー 制約エラーの適切な返却

4. テスターもSQLを必須スキルとする

データの裏付けを取るために、以下のSQL操作はQAの日常業務に組み込むべきです。

-- 更新前後の状態差分確認
SELECT * FROM target_table WHERE id = :target_id;

-- 親子テーブル間の孤立データ検出
SELECT child.*
FROM child_table child
LEFT JOIN parent_table parent ON child.parent_id = parent.id
WHERE parent.id IS NULL;

-- 意図しない重複データのあぶり出し
SELECT column_a, COUNT(*)
FROM target_table
GROUP BY column_a
HAVING COUNT(*) > 1;

5. 非同期処理・イベント競合を考慮する

「APIを叩いた直後に画面遷移する」といったシナリオでは、バックエンドのDB書き込み処理が完了する前に次の画面の読み込み(SELECT)が走り、古いデータが表示されることがあります。時間差(レイテンシー)を意識したテスト設計が必要です。

APIコール → [非同期書き込み中] → 画面遷移 → SELECT(古いデータが返る!)
                ↑
          ここの時間差を見落とさない

よくあるアンチパターン

❌ UIだけでOKと判断する

バックエンドのデータ構造が崩れていることに気づかず、将来的なデータ移行やバッチ処理で大事故を起こす。

❌ 正常系データしか見ない

本番環境でユーザーがイレギュラーな操作(ブラウザバック、連打など)をした際に、データの先祖返りや重複が発生する。

❌ 「仕様書に書いていないから」とキーイベント操作を無視する

ダイアログ表示中に背後で Delete キーが反応してデータが消えるような、致命的なUX・セキュリティ不備を見落とす。


まとめ

API × DBの観点を取り入れたテストの本質は、以下の通りです。

# 本質
1 UIだけに依存せず、データの真実(Single Source of Truth)を見る
2 SQLを活用して、ブラックボックステストをグレーボックス化する
3 異常系や環境依存の境界値を重視する

QAエンジニアの最大の価値は、「目に見える画面の動作確認」ではなく、「見えないところにあるリスク(バグ)を未然に見つけること」 にあります。

裏側のデータ構造にまで興味を持つことで、テストのクオリティは劇的に向上します。


おわりに

テストは「仕様を疑うこと」から始まりますが、APIやDBを含めた検証は 「仕様の裏にある『事実』を確認すること」 に近いと考えています。

表面的な挙動に満足せず、一歩踏み込んだデータ検証を行うことで、プロダクトの信頼性は確実に変わります。

今後も、日本の不動産IT(PropTech)などの実務現場で得た知見をもとに、一歩進んだテスト戦略について発信していきます。

最後までお読みいただき、ありがとうございました!

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?