💡

Tavernのresponseで自作関数を呼び出すときの注意点

2024/01/25に公開

はじめに

結論から言うと自作関数の第一引数にresponseを指定するのが必要なんですが、
これに気付くまでハマったので備忘録として残しておきます。

ハマったケース

TavernでAPIのE2Eテストを書いている際に、responseを受け取った後に自作関数を呼び出したくなる事があります。
例えば以下のような場合があります。

  • API内でDBに登録・更新されるデータだがレスポンスに含まれない、かつ、後のテストで使用するデータのため、直接DBを参照してデータ取得する必要がある場合
  • テストのために作成したデータの後始末(削除)をしたいが削除APIが存在しないため、DBを直接操作してレコード削除する必要がある場合

これらの事情からTavernのresponseで自作関数を呼び出すようなテストを書きました。
前者の例で言えばこんな感じです。

  • Tavern
- name: テスト1
  request:
    url: "http://example.com/api1"
    method: POST
    json:
      post_data_1: "test"
   response:
     status_code: 200
     save:
       $ext:
         function: ext_func:hoge
	 extra_kwargs:
	   id: "0001"
	   type: "ABC"
  • 自作関数(hoge)
def hoge(id: str, type: str):
    # ここでDBからレコードを参照して保存するreturnを書く

一見引数の名前も数も合っているので動くように見えますが、
以下のエラーメッセージでテストがコケます。

got multiple values for argument 'id'

このため、idが複数指定されてしまっていると思い、いろいろ試しましたが解決しませんでした。

解決

このときのスタックトレースにPythonのシステム関数(なんと表現するのが正しいのか分からず…)が表示されており、
そこには自作関数の呼び出し元として、たしか以下のように記載されていたと思います。

func(response, *args, **kargs)

解決策が分からず悩んでいる時にこのコードを見ていて、上記のエラーメッセージは引数の数が違うときにも発生するんだよな、と思い立ち、以下のように試しに第一引数にresponseを追加してみました。

def hoge(response, id: str, type: str):
    # ここでDBからレコードを参照して保存するreturnを書く

結果、これが功を奏し無事テストが通りました。

さいごに

正直エラーメッセージの文面が分かりづらいのでなんとかして欲しい…。
同じ引数が複数指定されているのと、期待している引数が指定されていないは別だと思うんだけど…。
Tavernから呼び出す際は仕方ないのかな。

勉強になりました。

Discussion