tavern でRestAPIのテスト

# はじめに

WEB APIのテストでtavern というものがあると聞いたので調べてみました。
自分でRestAPIサーバをたてて、GET/POST でテストするところまでできました。

# Example を試す

以下、

https://tavern.readthedocs.io/en/latest/examples.html

に書いてあることをフォローしたときのメモです。

### yamlを書く

JSON Placeholder APIを使ったテストいうのが紹介されています。これ、以下のようなレスポンスが返ってきます。

```shell
$ curl https://jsonplaceholder.typicode.com/posts/1
{
  "userId": 1,
  "id": 1,
  "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
  "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}
```

これをテストするために、以下のyaml ファイルを用意します。Tavern はファイル名が test_*.tavern.yaml (or test_*.tavern.yml)でないと実行できません。

```yaml:test_minimal.tavern.yaml
test_name: Get some fake data from the JSON placeholder API

stages:
  - name: Make sure we have the right ID
    request:
      url: https://jsonplaceholder.typicode.com/posts/1
      method: GET
    response:
      status_code: 200
      json:
        id: 1
        userId: 1
        title: "sunt aut facere repellat provident occaecati excepturi optio reprehenderit"
        body: "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
```

まぁ、ぱっと見で、request と response が書いてありますね。。。以上の感想がありませんが。

そしてテストを実行します。


```
$ tavern-ci test_minimal.tavern.yaml
================================================= test session starts ==================================================
platform linux -- Python 3.8.10, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /mnt/c/Users/xxx/Documents/yyyyyyyyyyyyyyy/2022_04_12_tavern
plugins: tavern-1.20.0
collected 1 item

test_minimal.tavern.yaml .                                                                                       [100%]

================================================== 1 passed in 4.62s ===================================================
```

## 自分で作ったWEBサーバで試す

こちらにあるサイトを参考にローカルでサーバを起動させます。FastAPIを使ってみました。
こちらに書いてあるとおり、「爆速」でWEB APIを起動できました。^^;

https://qiita.com/yota_dev/items/ab8dea7f71c8a130d5bf

```shell
$ docker build -t sample-api:1.0.0 .
$ docker run -d --name sample-api-container -p 5000:80 sample-api:1.0.0
```

以下のように動作しています。

```shell
$ $ curl localhost:5000
{"message":"Hello World"}
$ curl "localhost:5000/items/123?q=hoge"
{"item_id":123,"q":"hoge"}
$ curl -X POST "localhost:5000/items" -H 'Content-Type: application/json' -d '{"name":"おなまえ","price":123}' 
{"item_name":"おなまえ","twice price":246.0}
```


これに対して、以下のファイルを用意します。

```yaml:test_sample_api.tavern/api.yaml
test_name: sample api

stages:
  - name: hello world
    request:
      url: "http://localhost:5000/"
      method: GET
    response:
      status_code: 200
      headers:
        content-type: application/json
      json:
        message: "Hello World"

  - name: items
    request:
      url: "http://localhost:5000/items/123?q=foo"
      method: GET
    response:
      status_code: 200
      headers:
        content-type: application/json
      json:
        item_id: 123
        q: "foo"

  - name: items with no q
    request:
      url: "http://localhost:5000/items/123"
      method: GET
    response:
      status_code: 200
      headers:
        content-type: application/json
      json:
        item_id: 123

  - name: items by post
    request:
      url: "http://localhost:5000/items"
      method: POST
      json:
        name: "おなまえ"
        price: 123.0
    response:
      status_code: 200
      headers:
        content-type: application/json
      json:
        item_name: "おなまえ"
        twice price: 246.0
```

実行してみると、以下のように確認できます。

```shell
$ tavern-ci ./test/test_sampole_api.tavern.yaml 
============================================================== test session starts ==============================================================
platform linux -- Python 3.8.10, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /home/user/git/repository/MY_NOTEBOOK/2022_04_12_tavern/02
plugins: anyio-3.5.0, tavern-1.20.0
collected 1 item                                                                                                                                

test/test_sampole_api.tavern.yaml .                                                                                                       [100%]

=============================================================== 1 passed in 0.21s ===============================================================
```

# まとめ

とりあえずRest APIの実装を自分で行ったとき、テストする方法がわかりました。TODOですが、

- tavern で変数を設定する。特に、環境で切り替えるとか
- 認証があるときの方法の確認

まぁ、先は長いな。。。来週も生き延びられるかな。

### 参考

https://qiita.com/flatfisher/items/d8377711a30af1e9856b

https://hawksnowlog.blogspot.com/2021/03/getting-started-tavern-python.html#%E3%81%A8%E3%82%8A%E3%81%82%E3%81%88%E3%81%9A-get-%E3%82%92%E3%82%B3%E3%83%BC%E3%83%AB

https://www.nikutama.com/2019/12/01/python-memo-tavern/

https://dev.classmethod.jp/articles/http-redirect-test-tavern/