>& STDOUT

主にソフトウェアに関する日々の標準出力+標準エラー出力

テスト設計に連動してテストコードを動的に変更する

テスト設計の変更に従ってテストコードが自動で変更されて、勝手にテストを実行してくれると嬉しいですよね。その一部として、GIHOZのAPIを使って、期待動作の変更によってテストコードのふるまいを変えるデモを実演してみます。

まずふるまいから

題材のfizzbuzz関数に対して、デシジョンテーブルでド正常系のテストケースを4つ定義します。

テストを走らせると全てPASSします。

なんらかの仕様変更で、現在fizzと表示すべき振る舞いがbuzzに変更されたとして、デシジョンテーブルにそれを反映します。

GIHOZ側のモデルで振る舞いが変更されたので、これと連動してテストがコケます。ポイントは、GIHOZ側のモデルを変更しただけで、テストコードは一切触っていない、点です。TestOpsぽいですね。


仕組み

GIHOZのAPIを利用して、デシジョンテーブルのデータを取ってきて、動作記述部の値をテストコードのexpectに指定します。pytest の @pytest.mark.parametrize デコレータにテストデータ、期待動作のリストを渡してあげるとリストの要素数だけテストを実行してくれるので、簡単なデータ駆動テストを実現できます。

コード

GIHOZのAPIキーは各自 secret.yml に記載してください。本記事の趣旨に沿って分かりやすいように、1ファイルにまとめています。GIHOZからデシジョンテーブルのデータを取得してきて、テスト対象のfizzbuzz()に対してpytestでテストを走らせています。

import requests
import yaml
import json
import pytest

#テスト対象の関数
def fizzbuzz(num):

    if(num%3==0 and num%5==0):
        return "fizzbuzz"
    elif(num%3==0):
        return "fizz"
    elif(num%5==0):
        return "buzz"
    else:
        return num

#GIHOZからAPIでテスト設計データを取得
with open('secret.yml', 'r') as yml:
    config = yaml.safe_load(yml)

headers = {'Authorization': 'Bearer {}'.format(config['api_key'])}
data = requests.get(
    'https://gihoz-api.veriserve.co.jp/api/v1/users/snsk/repositories/MyRepository/test_cases/180acbf7-56dc-498e-b880-bc94952c6e44'
    ,headers=headers
)
data_json = json.loads(data.text)
test_case_json = json.loads(data_json["data"]["attributes"]["test_case_json"])

#テストケースに取得したテスト設計データから期待動作を埋め込む
test_case = [
    (3, test_case_json["data"]["actionRows"][0][1]),
    (5, test_case_json["data"]["actionRows"][1][1]),
    (15,test_case_json["data"]["actionRows"][2][1]),
    (1, 1),
]

#テスト実行
@pytest.mark.parametrize("num, expect", test_case)
def test_fizzbuzz(num, expect):
    assert fizzbuzz(num) == expect

イケてないところ

今回は、テストケースの条件部分を即値で指定しています。これは本来テストモデルから取得するべきですが、現状のGIHOZのAPIで返ってくるjsonからは読み取りが難しそうでした。現状のGIHOZのjsonはviewを構成するための構造になっているので、よりテストケースに向けた構造になると、このような仕組みからも扱いやすくなるかなと思います。フィードバックしました。

参考