DEV Community

Cover image for Apidog APIテストにおけるIf/Else条件分岐とフロー制御の実装方法
Akira
Akira

Posted on • Originally published at apidog.com

Apidog APIテストにおけるIf/Else条件分岐とフロー制御の実装方法

ほとんどのAPIテストは、ログイン → チェックアウト → レシート取得のように一本道で実行されます。しかし、ログインが401を返した場合でも次のチェックアウトを実行すると、本来の原因とは別の失敗が増え、レポートが読みにくくなります。前の応答を確認し、続行するか停止するかを判断する条件分岐を入れることで、失敗箇所を明確にできます。

今すぐApidogを試す

この記事では、Apidogのテストシナリオでif/else分岐を使い、ログインが成功した場合だけチェックアウトを実行するフローを構築します。シナリオの基本操作は、Apidogでテストシナリオを作成する方法を参照してください。条件式そのものの考え方は、MDNの条件文ガイドも参考になります。

フロー制御とは何か

Apidogでは、テストモジュール内にテストシナリオを作成し、その中へテストステップを追加します。ステップには通常のHTTPリクエストだけでなく、フロー制御要素も追加できます。

Apidogのフロー制御画面

フロー制御を使うと、シナリオは単にリクエストを順番に送るだけでなく、応答内容に応じた処理を実行できます。Apidogのフロー制御・条件分岐ドキュメントでは、利用できる要素と設定項目を確認できます。

この記事で扱うのは Conditional Branching、つまりif/else分岐です。

  • 条件分岐: 条件に応じて、ステップを実行するか別のステップを実行するかを一度だけ選択する
  • ループ: 同じステップ群を繰り返し実行する

複数の注文IDを順番に処理する場合は、条件分岐ではなくForEachループを使います。詳細はForEachループチュートリアルを参照してください。

実装するシナリオ

今回作成するフローは次のとおりです。

ログイン
  └─ status === 200 ?
       ├─ Yes: チェックアウトを作成
       └─ No : 失敗を記録して停止
Enter fullscreen mode Exit fullscreen mode

この構成により、認証に失敗したときにチェックアウトAPIを無駄に呼び出さず、失敗の原因をログイン処理へ集約できます。

ステップ1: テストシナリオを作成する

  1. Apidogを開く
  2. テストモジュールへ移動する
  3. 検索バー横の + をクリックする
  4. 保存先ディレクトリと優先度を選択する
  5. 新しいテストシナリオを作成する

空のシナリオを作成したら、ログインリクエストを最初のステップとして追加します。

ステップ2: ログインリクエストを追加する

既存のエンドポイント定義、保存済みケース、cURL、カスタムリクエストなどからステップを追加できます。ここではカスタムリクエストを使います。

POST https://api.your-store.com/v1/login
Content-Type: application/json

{
  "email": "dana@example.com",
  "password": "correct-horse-battery-staple"
}
Enter fullscreen mode Exit fullscreen mode

まずはこのステップだけを実行し、ログインAPIが期待どおりに動くことを確認します。成功時の応答例は次のとおりです。

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "userId": "usr_10482"
}
Enter fullscreen mode Exit fullscreen mode

後続リクエストでトークンを使う場合は、ここで返される token を参照または変数へ抽出します。

ステップ3: オーケストレートモードを開く

任意のステップをクリックして、オーケストレートモードに入ります。

  • 左側: シナリオ全体のフロー
  • 右側: 選択中ステップの設定

ステップの順序を変える場合は、ステップ上の アイコンをドラッグします。

ステップ4: Conditional Branchingを追加する

Add Step をクリックし、メニューから Conditional Branching を選択します。

空のIfブロックが作成されるので、ログイン応答のステータスコードを条件に設定します。

ログイン応答のステータスコード Equals 200
Enter fullscreen mode Exit fullscreen mode

Apidogの条件ビルダーでは、以下のような演算子を利用できます。

  • Equals / Not Equals
  • Exists / Does Not Exist
  • Less Than / Less Than or Equal
  • Greater Than / Greater Than or Equal
  • Matches Regex
  • Contains / Does Not Contain
  • Is Empty / Is Not Empty
  • In List / Not In List

ログインの成功判定には、まず Equals200 を使うのが分かりやすい設定です。

ステップ5: 前のステップの応答を条件で参照する

前のログインステップから値を取得する方法は2つあります。

方法1: Retrieve pre-step dataを使う

条件の値フィールドをクリックし、魔法の杖アイコンから Retrieve pre-step data を選びます。

前ステップの応答を直接参照できます。内部的には次のような構文になります。

{{$.<ステップID>.response.body.<フィールドパス>}}
Enter fullscreen mode Exit fullscreen mode

たとえば、ログインステップのIDが 1 で、レスポンスボディの token を使う場合は次のとおりです。

{{$.1.response.body.token}}
Enter fullscreen mode Exit fullscreen mode

Retrieve pre-step dataの設定画面

この方法には注意点があります。

  1. テストモジュールでのみ利用できます
  2. シナリオ全体を実行した場合にのみ値が解決されます

単一ステップだけを実行すると、前ステップの値が存在しないため、参照が空に見えることがあります。これは想定どおりの動作です。

方法2: Extract Variableで名前付き変数に保存する

複数のステップやモジュールで同じ値を使うなら、名前付き変数を使います。

  1. ログインリクエストを開く
  2. ポストプロセッサを追加する
  3. Extract Variable アクションを選択する
  4. JSONPathとして $.token を指定する
  5. 変数名を token として保存する

以降のステップでは次のように参照できます。

{{token}}
Enter fullscreen mode Exit fullscreen mode

ステップ間で値を受け渡す方法は、テストステップ間でデータを渡す方法で詳しく確認できます。

今回のステータスコード判定だけであれば、Retrieve pre-step data でログインステップのステータスを参照する方法が最短です。

ステップ6: Else分岐を追加する

Ifブロックにカーソルを合わせ、+ Else をクリックします。

これで、ログインが200を返さなかった場合の処理を定義できます。

Ifブロック: チェックアウトを実行する

Ifブロック内にチェックアウトリクエストを追加します。

POST https://api.your-store.com/v1/checkout
Authorization: Bearer {{token}}
Content-Type: application/json

{
  "items": [
    {
      "productId": "prod_123",
      "quantity": 1
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

トークンを変数として抽出していない場合は、前ステップ参照を使えます。

Authorization: Bearer {{$.1.response.body.token}}
Enter fullscreen mode Exit fullscreen mode

認証済みリクエストで Authorization ヘッダーにトークンを渡す構成は一般的です。Stripe APIドキュメントでも認証済みリクエストのパターンを確認できます。

Elseブロック: 明示的に失敗を記録する

Elseブロックでは、失敗が分かるステップを追加します。たとえば、次のいずれかを実施します。

  • エラー内容を記録するロギングAPIを呼び出す
  • 通知用エンドポイントへリクエストを送る
  • 常に失敗するアサーションを持つカスタムリクエストを追加する

重要なのは、ログイン失敗時にチェックアウトを実行せず、シナリオレポートで失敗理由を明確にすることです。

完成したフローは次のように読めます。

ログインが200ならチェックアウトを実行する。
それ以外なら失敗を報告して停止する。
Enter fullscreen mode Exit fullscreen mode

ステップ7: 保存してシナリオ全体を実行する

Save All をクリックして保存します。

未保存の変更がある場合は点のインジケーターが表示されます。保存後は、必ずシナリオ全体を実行して分岐を確認してください。

  • 有効な認証情報を使う: Ifブロックが実行される
  • 無効な認証情報を使う: Elseブロックが実行される

前ステップの参照を使っている場合、単一ステップ実行ではなくシナリオ全体を実行する必要があります。

バリエーションと高度なフロー制御

ステータスコード以外の値で分岐する

条件にはステータスコード以外の応答値も使えます。

たとえば、ログインAPIが200を返しても、アカウント状態がレスポンスボディの status に含まれている場合は次のように判定できます。

{{$.1.response.body.status}} Equals "active"
Enter fullscreen mode Exit fullscreen mode

他にも、以下のような判定が可能です。

残高 Greater Than 0
role In List ["admin", "operator"]
message Contains "locked"
Enter fullscreen mode Exit fullscreen mode

ForEachループ内で条件分岐する

商品IDの配列を処理する場合、ForEachループと条件分岐を組み合わせられます。

ForEach product
  └─ 在庫あり?
       ├─ Yes: 注文処理
       └─ No : スキップ
Enter fullscreen mode Exit fullscreen mode

ループインデックスは次の形式で参照します。

{{$.<ループステップID>.index}}
Enter fullscreen mode Exit fullscreen mode

ForEachの現在要素は次の形式です。

{{$.<ループステップID>.element.<フィールドパス>}}
Enter fullscreen mode Exit fullscreen mode

ForEachループと条件分岐の例

ループ処理の詳細はForEachループチュートリアルを参照してください。

Break Ifでループを途中終了する

ループ中に条件を満たした時点で反復を止めたい場合は、Break If condition を使います。

たとえば、対象レコードが見つかった時点で残りの検索を止める、といったケースに使えます。

On Errorでループ中のエラーを制御する

ループには開始位置に固定された On Error 要素があります。主な選択肢は次のとおりです。

設定 動作
Ignore 次のリクエストへ進む
Continue 現在のサイクル内の残りをスキップする
Break execution ループを停止して後続ステップへ進む
End execution シナリオ全体を停止する

Waitで待機時間を入れる

書き込み直後に読み取りAPIを呼ぶ場合、ダウンストリームサービスへの反映待ちが必要なことがあります。

Wait 要素を追加すると、ミリ秒単位で遅延を入れられます。

POST /orders
  ↓
Wait 1000ms
  ↓
GET /orders/{id}
Enter fullscreen mode Exit fullscreen mode

スクリプトから前ステップの値を読む

条件ビルダーだけでは複雑な判定を表現できない場合、プリプロセッサまたはポストプロセッサスクリプトで処理できます。

スクリプト内では {{variable}} 構文を直接使えません。代わりに pm.variables.get() を使います。

const token = pm.variables.get("$.2.response.body.token");

if (!token) {
  throw new Error("ログイントークンが取得できませんでした");
}
Enter fullscreen mode Exit fullscreen mode

リクエスト連鎖の設計については、リクエストチェーンおよびAPIテストオーケストレーションとデータ受け渡しも参照してください。

シナリオは自分自身を参照できません。これは、ネストしたシナリオによる意図しない無限ループを防ぐためです。

Apidog CLIでCIから実行する

作成したシナリオは、Apidogアプリ内だけでなくCLIからも実行できます。CIで実行する場合は、Apidog CLIをインストールしてアクセストークンでログインします。

npm install -g apidog-cli
apidog login --with-token <YOUR_ACCESS_TOKEN>
Enter fullscreen mode Exit fullscreen mode

次に、テストシナリオIDと環境IDを指定して実行します。

apidog run --access-token $APIDOG_ACCESS_TOKEN -t <scenario_id> -e <env_id> -r cli
Enter fullscreen mode Exit fullscreen mode

主なオプションは次のとおりです。

オプション 内容
-t テストシナリオID
-e 環境ID
-r レポーター

レポーターには、コンソール出力用の cli、CI成果物向けの htmljunit を指定できます。複数指定する場合はカンマ区切りです。

apidog run \
  --access-token $APIDOG_ACCESS_TOKEN \
  -t <scenario_id> \
  -e <env_id> \
  -r html,cli
Enter fullscreen mode Exit fullscreen mode

CLI実行でも、アプリ内と同じ条件分岐が評価されます。ログインが失敗すればElseパスが実行され、終了コードにも結果が反映されるため、CIジョブを失敗として扱えます。

セットアップはApidog CLIインストールガイド、GitHub Actionsとの連携はApidog CLI GitHub Actionsガイドを参照してください。定期実行が必要な場合は、ApidogでAPIテストをスケジュールする方法も利用できます。

よくある質問

条件分岐とループはどう使い分けますか?

条件分岐は、条件に応じて処理を1回選択する機能です。ログインに成功した場合だけチェックアウトへ進む、といった用途に向いています。

ループは同じステップを繰り返す機能です。配列内の全注文IDに対して同じAPIリクエストを送る場合は、ForまたはForEachを使います。

Retrieve pre-step data が空になるのはなぜですか?

主な原因は2つです。

  1. この機能はテストモジュールでのみ利用できる
  2. シナリオ全体ではなく単一ステップを実行している

前ステップのデータは、シナリオ全体を実行したときに解決されます。

応答ボディの値で分岐できますか?

できます。たとえば、次のように前ステップのレスポンスボディを参照します。

{{$.1.response.body.status}}
Enter fullscreen mode Exit fullscreen mode

その値に対して EqualsContainsIn List などの演算子を適用できます。

スクリプトで変数を参照するにはどうすればよいですか?

スクリプト内では {{variable}} を使わず、pm.variables.get() を使います。

const token = pm.variables.get("$.2.response.body.token");
Enter fullscreen mode Exit fullscreen mode

条件分岐に追加料金や自己ホスト環境は必要ですか?

Apidogのドキュメントには、フロー制御、条件分岐、ループ、ステップ間データ受け渡しについてプランごとの制限や、クラウド版・自己ホスト版による区別は記載されていません。テストシナリオを作成できる環境であれば、分岐を追加できます。

まとめ

条件分岐を追加すると、APIテストは単なる直列実行から、応答に応じて判断するワークフローへ変わります。

実装の要点は次の3つです。

  1. Conditional Branching を追加する
  2. Retrieve pre-step data または抽出済み変数で前ステップの応答を参照する
  3. Ifには成功時の処理、+ Else には失敗時の処理を配置する

ログイン失敗後にチェックアウトを実行しないだけでも、テスト結果のノイズを減らし、原因調査を速くできます。ローカルで確認できたら、apidog run を使って同じシナリオをCIへ組み込みましょう。

Apidogを無料で試す

Top comments (0)