一休.com Developers Blog

一休のエンジニア、デザイナー、ディレクターが情報を発信していきます

API Test ライブラリ Tavern のご紹介

こんにちは。 一休.comの開発基盤を担当しています、akasakasです。

今回は、Tavern という API Test ライブラリ を紹介したいと思います。

一休でAPI Test が必要になった背景

前回のブログでも少し触れましたが、APIのテストを無理やりSeleniumを使ってテストを続けた結果、E2Eが破綻しました。

適切なレイヤーで適切なテストをしようということで、APIに関してはちゃんと API Test ライブラリ の導入を決めました。

user-first.ikyu.co.jp

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を作成することができました。

f:id:akasakas:20190427201406p:plain:w500

前のテストの結果を保存できる・次のテストに使える

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の作成と編集をすることができました。

f:id:akasakas:20190427202300p:plain

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 は選択肢の一つとしてアリなのかなと思いました。

参考

github.com

taverntesting.github.io

tavern.readthedocs.io