HTTPリダイレクト設定のテストにTavernを使ってみた

2022.03.13

いわさです。

先日、S3静的ホストで大量のリダイレクト設定をしていました。
設定の変更や追加をするたびにデグレードテストしないといけないなぁと思ったのでテストフレームワークでリダイレクト動作のテストを行うようにしてみました。

テストフレームワークにはTavernを使ってみました。
そこで、Tavernの使い方などを残しておきたいと思います。

なお、この記事ではmacOS Big Surで動作確認をしています。

Tavernとは

Tavernは、pytestをベースにした、APIテストフレームワークです。

特徴としては、最小限の機能を備えていて、かつpytestと統合出来るという点でしょうか。
今回私は、cURLくらい気軽にリクエストを送りたかったので、多機能ではなくCLIからかつ簡単に使えるものを探していて目にしました。
APIテストフレームワークには全く精通していないのですが、変数やテストステージ機能など必要な機能は揃ってる感じがします。なんとなくですが。

あと、今回は使わないですが、MQTTメッセージのテストにも使えるようです。

使い方

私が今回使っている環境は以下のようにS3静的ホスティングで大量のリダイレクトを設定している環境です。
なお、S3静的ホスティングやリダイレクト機能については以下を参照してください。
S3のリダイレクト機能を改めて整理してみた | DevelopersIO

Resources:
  PrimaryBucket:
    Type: AWS::S3::Bucket
    Properties:
      ...
      WebsiteConfiguration:
        IndexDocument: index.html
        ErrorDocument: error.html
        RoutingRules:
          - RoutingRuleCondition:
              KeyPrefixEquals: hoge/?p=fuga
            RedirectRule:
              HostName: !Ref RedirectHostName
              ReplaceKeyWith: fuga/
          - RoutingRuleCondition:
              KeyPrefixEquals: hoge/?p=piyo
            RedirectRule:
              HostName: !Ref RedirectHostName
              ReplaceKeyPrefixWith: piyo/

セットアップ

pipでセットアップ出来ます。本日時点でPython3.4以降がサポートされており、Python2はサポートされていません。

pip install tavern

テスト定義

次に、テストフレームワークが実行するためにテストを定義します。
TarvenではYAMLでテストを記述します。
シンプルな使い方をする限りは、記述方法はかなり直感的です。送信したいリクエストと期待するレスポンスの情報を記述するだけです。

テストファイル名は、pytestを使うのであればtest_x.tavern.yaml形式のフォーマットが推奨されています。
別名を使う場合は実行時にファイル名か代替のフォーマットを指定します。今回は推奨形式に則って命名しています。

テストは1つ以上のステージで構成されます。
今回は単純なGETリクエストを送信して、レスポンスのステータスコードとlocationヘッダーを確認するだけなのでステージは1つしか使っていません。
複雑なシナリオではトークンを取得してリソースの更新を行うなど様々なテストステップが想定されます。そういった場合にステージを使うことが出来ます。

ステージは同一ファイルに定義します。
ステージで複数のテストを表現することも出来ますが、後述のテストレポートなどの兼ね合いもあり、1テスト1ファイルとしたほうが良いでしょう。

test_common_1.tavern.yaml

test_name: redirect test

includes:
  - !include param.yaml

stages:
  - name: test1
    request:
      url: https://{request-host}/hoge/?p=fuga
      method: GET
    response:
      status_code: 301
      headers:
        location: https://{redirect-host}/fuga/

パラメータ

この場合は、全テストで共通のパラメータを使いたい場合があります。
Tavernではいくつかのオプションがあるのですが、ここでは外部パラメータファイルのインクルード機能を使っています。

param.yaml

name: common parameter
description: common parameter
variables:
  request-host: old.example.com
  redirect-host: new.example.com

実行

pytestでの実行が推奨されています。
何らかの理由でpytestが使えない場合はTavern単体での実行も可能です。
その場合はtavern-ciコマンドを使います。

この記事ではpytestを使っています。

$ pytest
=================================================== test session starts ====================================================
platform darwin -- Python 3.9.4, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
Test order randomisation NOT enabled. Enable with --random-order or --random-order-bucket=<bucket_type>
rootdir: /Users/iwasa.takahito/src/hoge
plugins: localserver-0.5.1.post0, random-order-1.0.4, allure-pytest-2.9.45, hypothesis-6.36.1, tavern-1.20.0
collected 33 items                                                                                                         

hoge/Tests/CorporateRedirect/test_common_1.tavern.yaml .                                  [  3%]
hoge/Tests/CorporateRedirect/test_common_2-1.tavern.yaml .                                [  6%]
hoge/Tests/CorporateRedirect/test_common_2-2.tavern.yaml .                                [  9%]
hoge/Tests/CorporateRedirect/test_common_3.tavern.yaml .                                  [ 12%]
hoge/Tests/CorporateRedirect/test_common_4.tavern.yaml .                                  [ 15%]
hoge/Tests/CorporateRedirect/test_common_5.tavern.yaml .                                  [ 18%]
hoge/Tests/CorporateRedirect/test_common_6.tavern.yaml .                                  [ 21%]
hoge/Tests/CorporateRedirect/test_common_7.tavern.yaml .                                  [ 24%]
hoge/Tests/CorporateRedirect/test_individual_10.tavern.yaml .                             [ 27%]
hoge/Tests/CorporateRedirect/test_individual_11.tavern.yaml .                             [ 30%]
hoge/Tests/CorporateRedirect/test_individual_12.tavern.yaml .                             [ 33%]
hoge/Tests/CorporateRedirect/test_individual_13.tavern.yaml .                             [ 36%]
hoge/Tests/CorporateRedirect/test_individual_14.tavern.yaml .                             [ 39%]
hoge/Tests/CorporateRedirect/test_individual_15.tavern.yaml .                             [ 42%]
hoge/Tests/CorporateRedirect/test_individual_16.tavern.yaml .                             [ 45%]
hoge/Tests/CorporateRedirect/test_individual_17.tavern.yaml .                             [ 48%]
hoge/Tests/CorporateRedirect/test_individual_18.tavern.yaml .                             [ 51%]
hoge/Tests/CorporateRedirect/test_individual_19.tavern.yaml .                             [ 54%]
hoge/Tests/CorporateRedirect/test_individual_20.tavern.yaml .                             [ 57%]
hoge/Tests/CorporateRedirect/test_individual_21.tavern.yaml .                             [ 60%]
hoge/Tests/CorporateRedirect/test_individual_22.tavern.yaml .                             [ 63%]
hoge/Tests/CorporateRedirect/test_individual_23.tavern.yaml .                             [ 66%]
hoge/Tests/CorporateRedirect/test_individual_24.tavern.yaml .                             [ 69%]
hoge/Tests/CorporateRedirect/test_individual_25.tavern.yaml .                             [ 72%]
hoge/Tests/CorporateRedirect/test_individual_26.tavern.yaml .                             [ 75%]
hoge/Tests/CorporateRedirect/test_individual_27.tavern.yaml .                             [ 78%]
hoge/Tests/CorporateRedirect/test_individual_28.tavern.yaml .                             [ 81%]
hoge/Tests/CorporateRedirect/test_individual_29.tavern.yaml .                             [ 84%]
hoge/Tests/CorporateRedirect/test_individual_30.tavern.yaml .                             [ 87%]
hoge/Tests/CorporateRedirect/test_individual_31.tavern.yaml .                             [ 90%]
hoge/Tests/CorporateRedirect/test_individual_32.tavern.yaml .                             [ 93%]
hoge/Tests/CorporateRedirect/test_individual_8.tavern.yaml .                              [ 96%]
hoge/Tests/CorporateRedirect/test_individual_9.tavern.yaml .                              [100%]

==================================================== 33 passed in 7.23s ====================================================

レポート

レポート形式で確認したい場合は、pytestからテストレポートツールであるAllure Frameworkを使うことが出来ます。

セットアップ

brew install allure
pip install allure-pytest

実行

alluredirオプションを指定し、レポートデータ生成後にallure serveでレポートを作成します。

$ pytest --alluredir=reporthoge

...

======================================================= 8 passed in 1.34s =======================================================
$ allure serve reporthoge 
Generating report to temp directory...
Report successfully generated to /var/folders/d_/_8lb414x7_sg_kc6y534t_s40000gn/T/12648918461063662307/allure-report
Starting web server...
2022-03-11 11:29:45.212:INFO::main: Logging initialized @2750ms to org.eclipse.jetty.util.log.StdErrLog
Server started at <http://192.168.0.151:61129/>. Press <Ctrl+C> to exit

allure serve実行後にブラウザで自動的に展開されます。

このレポート機能良いな。

さいごに

本日はTavernを紹介しました。
テストフレームワークの導入って、私は準備が少し億劫になりがちなのですが、わりと簡単でした。あとテスト定義も直感的でドキュメントあまり読まなくてもテストの定義内容がわかやりやすくて良いですね。
使い方も簡単なのでCI/CDパイプラインへも簡単に組み込めそうです。