🐈

runnでTable driven test

2025/01/15に公開

はじめに

最近仕事でrunnをAPIのE2Eテストツールとして使っています。シンプルな記述でテストケースを書ける点と、E2Eのテストケースを負荷テストに容易に転用できる点が気に入っています。

この記事では、runnでTable driven testを実装する方法を紹介します。なお、Table driven testについて馴染みがない方はGo Wiki: TableDrivenTestsをご覧ください。

実装

以下のリポジトリにサンプルコードを載せています。

https://github.com/mi-wada/runn_table_driven_test

今回は以下の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を読み込んでいます。

test.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]

parts/get.yaml
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のように指定することで環境変数として展開されます。

.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便利ですね。

脚注
  1. https://github.com/k1LoW/runn?tab=readme-ov-file#expression-evaluation-engine ↩︎

GitHubで編集を提案

Discussion