緑色のステータスコードだけでは、APIの正しさを証明できません。たとえば POST /orders が 201 Created を返し、レスポンスボディも期待どおりでも、注文行が正しい状態でデータベースに保存されたとは限りません。在庫数が減っているか、外部キーが正しく設定されているか、ソフトデリートが意図せずハードデリートになっていないかは、HTTPレスポンスだけでは確認できません。APIテストで「システムが返した内容」だけでなく「実際に永続化した内容」まで検証するには、テストシナリオからデータベースを直接クエリします。
テストでは、リクエスト前に既知の状態をシードし、APIを実行し、リクエスト後にテーブルをクエリして結果を確認します。Apidogでは、データベース接続とデータベース操作プロセッサーを使い、外部スクリプトなしでSQLまたはNoSQLコマンドをシナリオのステップとして実行できます。シナリオ作成の基本は、Apidogでテストシナリオを作成する方法を参照してください。リレーショナルデータの基本を復習したい場合は、MDNのサーバーサイド概要も役立ちます。
テストにおけるデータベース操作の利点
データベースに触れないAPIテストは、基本的にブラックボックステストです。レスポンスを確認するには十分ですが、APIの返却値と永続化データの間にある不整合は検出できません。
データベース操作ステップを追加すると、次の3つを実現できます。
- シード: テスト開始前に必要なデータを作成し、残存データへの依存をなくす
- 永続化の検証: APIが作成・更新したはずの行を直接確認する
- 実値の抽出: DBで生成・保持された値を後続リクエストへ渡す
Apidogでは、まず 設定 > データベース接続 で接続を作成します。その後、リクエストの前に実行するプリプロセッサー、または後に実行するポストプロセッサーとしてデータベース操作を追加します。作成した接続はプロジェクト内の複数シナリオで再利用できます。
利用可能なデータベースにはプラン上の違いがあります。
| データベース | 利用条件 |
|---|---|
| MySQL | 無料プラン |
| SQL Server(2014以降) | 無料プラン |
| PostgreSQL | 無料プラン |
| Oracle | 無料プラン |
| ClickHouse | 有料プラン |
| MongoDB | 有料プラン |
| Redis | 有料プラン |
以降のMySQLの例は無料プランで実行できます。MongoDBとRedisを使う場合は有料プランが必要です。
ステップ1: データベース接続を作成する
- 設定 > データベース接続 を開きます。
- 右上の + 新規 をクリックします。
- データベース種別を選択します。
- 接続情報を入力して保存します。
主な入力項目は次のとおりです。
-
ホスト:
db.staging.internalまたは127.0.0.1 -
ポート: MySQLなら
3306 - ユーザー名
- パスワード
-
データベース名: 例
shop
踏み台サーバー経由で接続する場合は、SSHトンネルを展開してジャンプホストの情報を設定します。
MySQLではSSLモードも選択できます。
-
Prefer: SSLを試行し、失敗時にフォールバックするデフォルト設定 RequireVerify CAVerify Full
可能であれば、サーバーが対応する最も厳格なモードを選択してください。
MySQL 8で認証エラーが出る場合
MySQL 8では、デフォルトの caching_sha2_password 認証プラグインにより接続できない場合があります。認証エラーが発生する場合は、テスト用ユーザーの認証方式を変更して再接続します。
ALTER USER 'tester'@'%'
IDENTIFIED WITH mysql_native_password BY '...';
認証プラグインの違いは、MySQLリファレンスマニュアルで確認できます。
データベース接続の認証情報はローカルマシンに保存され、クラウドへ同期されません。チームメンバーごとに接続を設定してください。チームでの運用方法は、データベース接続設定の共有も参照してください。
ステップ2: プリプロセッサーでデータをシードする
注文作成APIをテストする場合、リクエスト前に既知の顧客を作成しておくと、既存データやテスト実行順に依存しないテストになります。
リクエストを開き、次の手順でデータベース操作を追加します。
- プリプロセッサーを開く
- データベースプロセッサーを追加
- データベース操作を選択
- 操作名を
seed customerに設定 - MySQL接続を選択
- SQLコマンドを入力にSQLを記述
環境変数などの動的な値は {{variable_name}} 形式で参照できます。
INSERT INTO customers (id, email, status)
VALUES ({{customer_id}}, '{{customer_email}}', 'active')
ON DUPLICATE KEY UPDATE status = 'active';
このSQLにより、テスト開始時に次の状態を保証できます。
- 顧客が存在する
- 顧客のステータスが
activeである - 顧客IDが後続ステップで利用できる
テストを自己完結させるため、シード処理はプリプロセッサーに置くのが基本です。
ステップ3: ポストプロセッサーでデータベースをアサートする
次に、APIが作成した注文が実際に orders テーブルへ保存されたことを確認します。
まず、注文作成APIを呼び出します。
POST /api/orders
Content-Type: application/json
{
"customer_id": {{customer_id}},
"items": [{ "sku": "APRON-01", "qty": 2 }]
}
レスポンスに注文IDが含まれる場合は、通常のレスポンスアサーションで order_id として保存します。
続けて、同じリクエストにポストプロセッサーを追加します。
- ポストプロセッサーを追加を選択
- データベース操作を選択
- 操作名を
verify order rowに設定 - 接続を選択
- 次のSQLを設定
SELECT id, status, total_cents
FROM orders
WHERE id = {{order_id}};
クエリ結果は、行ごとのオブジェクト配列として返されます。最初の行の status を変数へ保存するには、結果を抽出(オプション)で結果を変数に抽出を追加します。
-
変数名:
db_order_status - JSONPath式:
$[0].status
実行後、コンソールで生のクエリ結果と抽出値を確認してください。そのうえで、db_order_status が期待する pending などの値と一致するアサーションを追加します。
これにより、以下のような不具合を検出できます。
- APIは
201 Createdを返した - しかしDBでは
status = 'draft'になっていた - レスポンスでは正常に見えるが、永続化処理が不正だった
ステップ4: データベース値を抽出して後続リクエストで使う
データベースからの値抽出は、アサーションだけに使うものではありません。APIレスポンスには含まれない内部生成値を、後続のリクエストで使うケースがあります。
たとえば注文作成時に fulfillment_ref がDB上で生成される一方、APIレスポンスには含まれないとします。後続のエンドポイントがこの値を要求する場合、ポストプロセッサーで取得できます。
SELECT fulfillment_ref
FROM orders
WHERE id = {{order_id}};
抽出設定は次のとおりです。
-
変数名:
fulfillment_ref - JSONPath式:
$[0].fulfillment_ref
後続リクエストでは、URLやリクエストボディで {{fulfillment_ref}} を参照します。
GET /api/fulfillments/{{fulfillment_ref}}
HTTPレスポンスから値を渡すのと同じ考え方ですが、値の取得元がJSONレスポンスではなくデータベースです。関連するパターンは、テストステップ間でデータを渡すおよびAPIテストのオーケストレーションとデータ受け渡しでも確認できます。
MongoDBとRedis: NoSQLのバリアント
MongoDBとRedisでもデータベース操作プロセッサーを利用できます。ただし、どちらも有料機能です。詳細なフィールド仕様はApidogドキュメントを確認してください。
MongoDB
MongoDBでは、生SQLの代わりに操作タイプを選択します。
- Find
- Insert
- Update
- Delete
- データベースコマンドの実行
CRUD操作ではコレクション名が必要です。クエリ条件にはJSONを入力します。
{ "_id": "65486728456e79993a150f1c" }
一致するID文字列は自動的に ObjectId として処理されます。BSON型が必要な場合は、次のヘルパーも利用できます。
ISODate(...)ObjectId(...)NumberDecimal(...)NumberLong(...)
各型の詳細はMongoDBマニュアルを参照してください。
なお、MySQLのようなJSONPathベースの変数抽出については、MongoDBとRedisのドキュメントでは同じ仕組みが明示されていません。まずは状態のシードと確認を中心に使い、抽出が必要な場合はコンソールで動作を確認してください。
Redis
Redis接続では、次の情報を入力します。
- ホスト
- ポート
- パスワード
- データベースインデックス
ビジュアル操作では、次の操作タイプを利用できます。
- GET
- SET
- DELETE
たとえばキャッシュされたセッションを確認する場合、GETを選択し、キーを次のように指定します。
user:session:123
ドロップダウンにない操作は、Redisコマンドの実行タブで実行できます。
KEYS user:*
これにより、APIが書き込むべきキャッシュエントリの確認や、テスト前のキャッシュクリアが可能です。
高度なバリエーションと制限事項
大きなテストスイートを作る前に、以下のポイントを確認してください。
ループ
ForEachステップで行を反復する場合、現在の要素は{{$.StepID.element.field}}で参照できます。StepIDはループステップの実際の番号です。DB値による分岐
ステータスを抽出し、paidとpendingで後続の処理を分岐できます。APIテストシナリオにおける条件ロジックと組み合わせると、DB状態に応じたシナリオを作成できます。環境ごとの接続切り替え
環境ごとに接続を作成しておくと、選択中の環境に対応するDBへ自動的にルーティングされます。ストアドプロシージャ
ビジュアルインターフェースでは、ストアドプロシージャのような複雑な操作は対象外です。SQLは単純なSELECT、INSERT、UPDATE、DELETEに留めてください。Oracleのセットアップ
Oracleへ接続するには、事前にローカルマシンへOracle Clientをインストールする必要があります。
環境ごとの認証情報を管理する
テストが誤って本番データへ接続しないよう、環境ごとにデータベース接続を作成します。
たとえば、以下のように分けます。
-
local: ローカル開発DB -
staging: ステージングDB
各接続には、それぞれのホスト・ユーザー・パスワードを設定します。その後、画面右上の環境ドロップダウンで環境を切り替えます。
-
stagingを選択すると、シナリオ内のクエリはステージングDBで実行される -
localを選択すると、同じSQLがローカルDBで実行される
SQLやテストステップを書き換える必要はありません。
認証情報はローカルに保存されるため、共有クラウドプロジェクトに本番パスワードが同期されることもありません。各エンジニアが自身の認証情報を管理できます。
Apidog CLIでワークフローを自動化する
アプリ上でシナリオが通ったら、CIでも実行してプルリクエストごとにDBアサーションを検証します。
まず、CLIをインストールして認証します。
npm install -g apidog-cli
apidog login --with-token <YOUR_ACCESS_TOKEN>
次に、シナリオIDと環境IDを指定して実行します。
apidog run --access-token $APIDOG_ACCESS_TOKEN -t <scenario_id> -e <env_id> -r cli
主なオプションは次のとおりです。
| オプション | 内容 |
|---|---|
-t |
テストシナリオID |
-e |
環境ID |
-r |
レポーター |
レポーターには cli、html、junit を指定できます。複数指定する場合はカンマ区切りです。
apidog run --access-token $APIDOG_ACCESS_TOKEN \
-t <scenario_id> \
-e <env_id> \
-r html,cli
データベース接続情報はローカルに保存されるため、CIからDBへ接続するには、ランナーに必要な設定を用意する必要があります。データセットの各行で同じDBアサーションを実行する場合は、Apidog CLIによるデータ駆動型テストを参照してください。定期実行は、ApidogによるAPIテストのスケジュール設定で設定できます。
よくある質問
無料で使えるデータベースと有料のデータベースはどれですか?
MySQL、SQL Server(2014以降)、PostgreSQL、Oracleは無料プランで利用できます。ClickHouse、MongoDB、Redisは有料プランが必要です。
データベースの値を後続リクエストで使えますか?
はい。ポストプロセッサーで SELECT を実行し、結果を変数に抽出を使います。たとえば、次のJSONPathで最初の行の値を抽出できます。
$[0].fulfillment_ref
抽出後は {{fulfillment_ref}} のように参照します。
チームメイトは自動的にデータベース接続を取得できますか?
いいえ。接続の認証情報はクライアントごとにローカル保存され、クラウドには同期されません。各メンバーが個別に設定します。
MySQL 8への接続が失敗するのはなぜですか?
MySQL 8のデフォルト認証プラグイン caching_sha2_password が原因の場合があります。必要に応じて、ユーザーを mysql_native_password へ切り替えて再接続してください。
ALTER USER 'tester'@'%'
IDENTIFIED WITH mysql_native_password BY '...';
ストアドプロシージャや複雑なDBロジックを実行できますか?
ビジュアルインターフェースでは対応していません。テストステップでは、標準的な SELECT、INSERT、UPDATE、DELETE のような直接的なステートメントを使ってください。
まとめ
データベースクエリを組み込むと、APIテストを「レスポンスが正しく見える」状態から「データが実際に正しい」状態へ進められます。
実装の基本パターンは次のとおりです。
- プリプロセッサーでテストデータをシードする
- APIリクエストを実行する
- ポストプロセッサーでDBの行をクエリする
- 永続化された値をアサートする
- 必要ならDB値を変数へ抽出し、後続リクエストへ渡す
環境ごとに接続を分ければ、同じシナリオをローカル環境とステージング環境で安全に使い回せます。
まずはApidogをダウンロードし、開発用MySQLへ接続してみてください。次に、APIリクエストが作成した行を確認するポストプロセッサーを1つ追加すると、HTTPレスポンスだけでは見えない不具合を検出できます。

Top comments (0)