🐈

runnでTable driven testを実装する

2025/01/15に公開

はじめに

最近仕事でAPIのE2Eテストツールとしてrunnを使っています。シンプルな記述でテストケースをかける点と、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"}}を含むレスポンスボディを返す。

以下のファイルにテストケースを記述します。runnのinclude機能を使って./parts/get.yamlを読み込んでいます。./parts/get.yamlには共通する処理やアサーションを記述しています。

e2e/e2e.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は以下のような内容です。e2e.yamlから渡されたqをクエリパラメーターにセットしてリクエストし、レスポンスをアサートしています。API_BASE_URLは環境変数で設定しています。testフィールドではexpr-lang/exprの記法が使えます[1]

e2e/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)

API_BASE_URLは以下のように.envファイルで設定しています。.envファイルはrunnの実行時に--enf-fileオプションで指定することで環境変数として読み込まれます。

e2e/.env
API_BASE_URL=https://httpbin.org

そして以下のコマンドでテストを実行します。複数のテストケースが実行されていることが確認できます🎉

$ runn run --verbose --env-file ./e2e/.env e2e/e2e.yaml
=== GET /get (e2e/e2e.yaml)
    --- (0) ... ok
        === Generated by `runn new` (e2e/parts/get.yaml)
            --- (0) ... ok
    --- (1) ... ok
        === Generated by `runn new` (e2e/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