こんにちは。 一休.comの開発基盤を担当しています、akasakasです。
今回は、Tavern という API Test ライブラリ を紹介したいと思います。
一休でAPI Test が必要になった背景
前回のブログでも少し触れましたが、APIのテストを無理やりSeleniumを使ってテストを続けた結果、E2Eが破綻しました。
適切なレイヤーで適切なテストをしようということで、APIに関してはちゃんと API Test ライブラリ の導入を決めました。
API Test を導入する上で考えたポイント
API Test を導入する上で考えたポイントは以下の点です。
- 開発者フレンドリー
- CI連携
開発者フレンドリー
前回のブログでも書きましたが、一休ではQA・テストエンジニアのようなポジションはいないので、開発者がテストも修正するようになってます。
開発者が気軽にテストを追加・修正することができるような API Test ライブラリが必要だと考えました。
CI連携
一休で扱っているAPIは外部の提携先に提供しているAPIが多いです。
もしリリース後、APIで障害が発生した場合、外部の提携先にも影響が及びます。
リリース前の障害事前検知のため、検証環境で定期的にAPI Testを流して、リリース後の障害を防ぎたいです。
その為には、API Test を CIで回せるようにする必要がありました。
Tavernのご紹介
上記の要件を満たせるAPI Test ライブラリを検討した結果、Tavernと出会いました。
Tavern はAPI Test に特化した PyTest のプラグインです。
テストはYAMLで記述できるので、シンプルでわかりやすく、メンテナンスが簡単ですので、開発者フレンドリーであると感じました。
また、PyTestのプラグインでコマンドラインでテストの実行ができるので、CI連携もしやすいです。
API Testのツールでいうと、PostmanやInsomniaがありますが、GUIとして使うのが一般的で、CI連携が難しかったです(PostmanのCLIでNewmanというのがありますが、テストの記述がTavernよりも難しいと感じたので、Newmanの導入も見送りました)。
Tavern のいいところ
Tavern のいいところとしては以下の3点があると思います。
- YAMLでテストを記述できる
- 前のテストの結果を保存できる・次のテストに使える
- CI連携
YAML でテストを記述できる
Github API を例にして Tavern を使って、API Test をしてみましょう。
Tavern で issue を作れることを確認します。
https://developer.github.com/v3/issues/#create-an-issue
先にテストからお見せします
test_name: Github API Test includes: - !include common.yaml stages: - name: Create Issue request: url: https://api.github.com/repos/{service.owner:s}/{service.repo:s}/issues headers: Authorization: "token {service.token:s}" method: POST json: title: "Issue From Tavern Test" body: "一休.comをご利用頂き、誠にありがとうございます。" response: status_code: 201 body: title: "{tavern.request_vars.json.title}" body: "{tavern.request_vars.json.body}" state: "open"
YAMLで書かれているので、どんなことをしているのか、なんのテストをしているのかがイメージしやすいと思います。
- request
- url でテスト対象のエンドポイントを指定
- header で Authorization Header を設定
- jsonでポストするデータを指定 etc
- reponse
- 201 が返却されること
- body の内容がrequestの内容と一致していること
などを記述していることがわかります。
共通のデータは common.yaml で記述しています。
common.yaml の内容としては以下のようなイメージです。
description: used for github api testing name: test includes variables: service: token: "token" owner: "リポジトリオーナー" repo: "リポジトリ"
テストの実行は
tavern-ci test_github.tavern.yaml
で確認できます。
Tavern のお作法として、テストファイルのyamlは test_*.tavern.yaml
という形で統一しているようです。
テストも通りました。
$ tavern-ci test_github.tavern.yaml ================================================== test session starts ================================================== platform darwin -- Python 3.6.1, pytest-4.3.0, py-1.8.0, pluggy-0.9.0 plugins: tavern-0.22.1 collected 1 item test_github.tavern.yaml . [100%] =============================================== 1 passed in 1.66 seconds ================================================
Tavern で Github API を使って、issueを作成することができました。
前のテストの結果を保存できる・次のテストに使える
Tavern の便利なところとして、前のテストの結果を保存して、それを次のテストに使うことができるというのもあります。
Github API を使って
- Issue を作成
- Issue の番号を取得
- その番号のissueを編集する
ということをやってみましょう。
先にテストからお見せします
test_name: Github API Test includes: - !include common.yaml stages: - name: Create Issue request: url: https://api.github.com/repos/{service.owner:s}/{service.repo:s}/issues headers: Authorization: "token {service.token:s}" method: POST json: title: "Issue From Tavern Test" body: "一休.comをご利用頂き、誠にありがとうございます。" response: status_code: 201 save: body: issue_id: number - name: Edit Issue request: url: https://api.github.com/repos/{service.owner:s}/{service.repo:s}/issues/{issue_id} headers: Authorization: "token {service.token:s}" method: PATCH json: title: "Edit Issue From Tavern" body: "一休レストランをご利用頂き、誠にありがとうございます。" response: status_code: 200 body: state: "open"
- Create issue のresponse body で issue_id を save
- Edit Issue の request url で issue_id を使って、テスト
ということをやっています。
Tavern で Github API を使って、issueの作成と編集をすることができました。
CI連携
tavern のインストール自体は、 pip install tavern
のみで済みますし、
テストの実行自体も tavern-ci test_*.tavern.yaml
で済むので、CI連携も容易です。
Tavern の実運用にまつわる細かい話
Tavern の実運用にまつわる細かい話としては
- 環境別のテストデータの設定
が気になるところなのかなと思います。
これに関しては、
https://tavern.readthedocs.io/en/latest/basics.html?#multiple-global-configuration-files
に書いてありますが、各環境別で使うYAML を用意します。
まとめ
今回は、 Tavern を使ったAPI Test について紹介しました。
「API Test ライブラリといえば、コレだ!」というものがない印象でしたが、
- テストを YAML で記述できて、イメージしやすい
- CI連携の容易
という点で、 Tavern は選択肢の一つとしてアリなのかなと思いました。