runnでTable driven test
はじめに
最近仕事でrunnをAPIのE2Eテストツールとして使っています。シンプルな記述でテストケースを書ける点と、E2Eのテストケースを負荷テストに容易に転用できる点が気に入っています。
この記事では、runnでTable driven testを実装する方法を紹介します。なお、Table driven testについて馴染みがない方はGo Wiki: TableDrivenTestsをご覧ください。
実装
以下のリポジトリにサンプルコードを載せています。
今回は以下の2つのテストケースを実装します。
-
GET https://httpbin.org?q=hello
を呼び出すと、200 OK
かつ{"args":{"q":"hello"}}
を含むレスポンスボディを返す。 -
GET https://httpbin.org?q=world
を呼び出すと、200 OK
かつ{"args":{"q":"world"}}
を含むレスポンスボディを返す。
全体としてこれらのファイルを用います。
-
test.yaml
- 全テストケースを定義するエントリーポイント。テストケース毎に異なる引数や期待する値を定義する。
-
parts/get.yaml
- リクエストの実行やレスポンスのアサーションなどの全テストケースで共通する処理を定義する。
-
.env
- 環境変数を定義する。
では、それぞれのファイルについて説明します。
test.yaml
このファイルに全テストケースを記述します。エントリーポイントとなるファイルです。テストケース毎に異なる引数や期待する値を書きます。
レスポンスのアサーション等はparts/get.yaml
で行います。このファイルでは、runnのinclude機能を使ってparts/get.yaml
を読み込んでいます。
desc: GET /get
steps:
- include:
path: ./parts/get.yaml
vars:
q: "hello"
want_status: 200
want_body_args: |
{
"q": "hello"
}
- include:
path: ./parts/get.yaml
vars:
q: "world"
want_status: 200
want_body_args: |
{
"q": "world"
}
parts/get.yaml
このファイルは、test.yaml
で各テストケース毎に定義したvarsに基づきHTTPリクエストを行いレスポンスをアサートします。
API_BASE_URLは環境変数として設定しています。これにより実行対象環境を容易に切り替えることが可能です。
なお、test
フィールドではexpr-lang/exprの記法が使えます[1]。
runners:
req: ${API_BASE_URL}
steps:
- req:
/get?q={{ vars.q }}:
get:
body: null
test: |
steps[0].res.status == vars.want_status &&
steps[0].res.body.args == fromJSON(vars.want_body_args)
.env
このファイルでは環境変数としてAPI_BASE_URLを定義します。.envファイルはrunnの実行時に--enf-fileオプションでrunn run --env-file .env
のように指定することで環境変数として展開されます。
API_BASE_URL=https://httpbin.org
実行
以下のコマンドでテストを実行します。複数のテストケースが実行されていることが確認できます🎉
$ runn run --verbose --env-file .env test.yaml
=== GET /get (test.yaml)
--- (0) ... ok
=== Generated by `runn new` (parts/get.yaml)
--- (0) ... ok
--- (1) ... ok
=== Generated by `runn new` (parts/get.yaml)
--- (0) ... ok
1 scenario, 0 skipped, 0 failures
おわりに
runn便利ですね。
Discussion