LoginSignup
1
2

More than 3 years have passed since last update.

部分テストパラメータの値を使ってテストパラメータを生成する

Last updated at Posted at 2018-12-19

generating test parameters using wrapper for collected partial parameters like test scenario, without metafunc

pytest URL
xdistの-nオプションについて https://qiita.com/cielavenir/items/3f3319f3fa153c16c703
デコレータの作り方 https://qiita.com/cielavenir/items/542f7eaa612c6bb9ed90
デコレータに引数を渡す https://qiita.com/cielavenir/items/2c971ca4bc138c375d17
部分テストパラメータの値を使ってテストパラメータを生成する https://qiita.com/cielavenir/items/ce328313a9f0f498cbcb
pytestのfixtureを別の箇所でライブラリとして読み込みたい
(当該環境にはpytestが存在しない可能性がある)
https://qiita.com/cielavenir/items/8144774a6ac2eca2e2ce

基底データをさまざまな角度からテストしたいということはそれなりにあると思う。

何も考えずに作ると、基底データをパラメータにして、テストの中でループさせることになると思う。

loop.py
import pytest
def collect_data():
  return [1,2,3]

@pytest.mark.parametrize('num',collect_data())
def test_0(num):
  for idx in range(0,num):
    print([idx,num])

@pytest.mark.parametrize('num',collect_data())
def test_1(num):
  for idx in range(1,num):
    print([idx,num])

しかし、これはループ中にテストが失敗した場合にテストケース全体が失敗してしまうため、テストの作法としてはよろしくないとされる。

基底データを受け取ってテストパラメータを生成する関数を噛ませればよいのではないかと思った。

wrap.py
import pytest
def collect_data():
  return [1,2,3]

def collect_test0():
  tests = []
  for num in collect_data():
    for idx in range(0,num):
      tests.append((idx,num))
  return tests

def collect_test1():
  tests = []
  for num in collect_data():
    for idx in range(1,num):
      tests.append((idx,num))
  return tests

@pytest.mark.parametrize(('idx','num'),collect_test0())
def test_0(idx,num):
  print([idx,num])

@pytest.mark.parametrize(('idx','num'),collect_test1())
def test_1(idx,num):
  print([idx,num])

行数は長くなったが、実際にはcollect_test0/1の処理はより複雑になると思われるので(たとえばcollect_dataがdatとjsonを返してtest1でだけjsonを読むとか)、誤差の範囲だと思われる。

2つのテストの出力は同じだが、前者のテスト数は6、後者のテスト数は9になった。idxについてもテストケースが分離されたことが確認できた。

collected 6 items                                                                                                                                                                                                

loop.py [0, 1]
.[0, 2]
[1, 2]
.[0, 3]
[1, 3]
[2, 3]
..[1, 2]
.[1, 3]
[2, 3]
.

collected 9 items                                                                                                                                                                                                

wrap.py [0, 1]
.[0, 2]
.[1, 2]
.[0, 3]
.[1, 3]
.[2, 3]
.[1, 2]
.[1, 3]
.[2, 3]
.

余談:これぐらいテスター的には常識なのかもしれないが、私はこの方法を思いつくのに半日かかってしまった。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2