この記事は さくらインターネット Advent Calendar 2025 5日目の記事です。
はじめに
先日、APIテストを書いていると、「一覧取得APIから、特定条件のデータが存在するか確認したい」という場面に遭遇しました。
理想的にはAPIがクエリパラメータでフィルタリング機能を提供していれば、特定条件のデータだけを取得してテストできます。しかし今回は、以下のような状況でした。
- 大量のテストデータがある中で、特定の条件(例:
status == "active")のデータだけを使ってテストを実行したい - しかしAPIにはフィルタリング用の適したクエリパラメータがまだない
- そのため、runn側でレスポンスから必要なデータだけを絞り込んでテストしたかった
このような「テストの実行範囲を絞り込みたい」場面で、runnのfilterを使って解決しました。
本記事では、runnのfilter機能を使って、特定条件のデータだけを抽出してテストする実践方法を紹介します。
状況: 一覧取得APIしかない
ここでは例として、ECサイトの注文履歴APIを使って説明します。
以下のような注文一覧を返すAPIがあるとします。
GET /api/orders
レスポンス:
{
"orders": [
{
"id": 1,
"customer_name": "田中太郎",
"product": "ノートPC",
"amount": 89800,
"status": "pending"
},
{
"id": 2,
"customer_name": "佐藤花子",
"product": "キーボード",
"amount": 8900,
"status": "completed"
},
// ... その他の注文
]
}
このAPIで「注文を作成した後、保留中(pending)の注文が正しく登録されたかテストしたい」という場面を考えます。
理想的には GET /api/orders?status=pending のようなクエリパラメータがあれば絞り込めますが、まだ実装されていない場合、runnのfilter機能を使ってレスポンスから特定条件のデータだけを抽出してテストできます。
解決策: runnのfilter機能
runnはexpr-lang/exprを式評価エンジンとして組み込んでおり、filter、all、mapなどの配列関数が使えます。
使用例1: 注文作成後の確認
注文を作成した後、保留中の注文が正しく登録されたかテストする例です。
desc: 注文作成後、保留中の注文が正しく登録されたことを確認する
runners:
req: http://localhost:8080
steps:
createOrder:
req:
/api/orders:
post:
body:
application/json:
customer_name: "田中太郎"
product: "ノートPC"
amount: 89800
test: |
steps.createOrder.res.status == 201
verifyPendingOrder:
req:
/api/orders:
get:
body: null
bind:
pendingOrders: filter(steps.verifyPendingOrder.res.body.orders, {.status == "pending" && .customer_name == "田中太郎"})
test: |
len(pendingOrders) >= 1
使用例2: 複合条件での絞り込み
高額(50,000円以上)の保留中の注文を抽出:
desc: 高額(50,000円以上)の保留中の注文を抽出する
runners:
req: http://localhost:8080
steps:
getOrders:
req:
/api/orders:
get:
body: null
test: |
steps.getOrders.res.status == 200
filterHighValuePending:
bind:
highValueOrders: filter(steps.getOrders.res.body.orders, {.status == "pending" && .amount >= 50000})
test: |
len(highValueOrders) >= 1
使用例3: 数値範囲での絞り込み
10,000円以下の注文:
desc: 10,000円以下の注文を抽出する
runners:
req: http://localhost:8080
steps:
getOrders:
req:
/api/orders:
get:
body: null
test: |
steps.getOrders.res.status == 200
filterSmallOrders:
bind:
smallOrders: filter(steps.getOrders.res.body.orders, {.amount <= 10000})
test: |
len(smallOrders) >= 1
モックサーバーでの動作確認
実際に動かせるサンプルコードを用意しました。
テストシナリオの実行
# モックサーバー起動
go run mock_server.go
# 別ターミナルでrunnテスト実行
runn run example1_order_creation.yml
まとめ
runnのfilter機能を使えば、以下のような利点があります:
メリット
- テストの対象を自由に絞り込める
- AND/OR、数値比較、文字列マッチなど複雑な条件を柔軟に記述できる
注意点
- レスポンスデータ全体を取得してからフィルタリングするため、大量データには不向き
- サーバー側でのフィルタリングと比べてネットワーク転送量が多いので、使用用途が限定される
こんな場面で活用できる
- テストデータの中から特定条件のデータだけでテストしたい
- デバッグのために特定のエッジケースのデータだけを抽出したい
runnのfilter機能は、データを柔軟に絞り込んでテストするのに便利だなと思いました
ぜひ活用してみてください〜
参考リンク
サンプルコード
本記事で使用したサンプルコードは以下のリポジトリにあります:
-
mock_server.go- モックAPIサーバー -
example1_order_creation.yml- 使用例1: 注文作成後の確認 -
example2_complex_filter.yml- 使用例2: 複合条件での絞り込み -
example3_numeric_range.yml- 使用例3: 数値範囲での絞り込み