web-dev-qa-db-ja.com

フィクスチャ関数にパラメーターを渡す

DLLクラスMyTesterにラップされたpythonコードをテストするためにpy.testを使用しています。検証のために、テスト中にいくつかのテストデータを記録し、その後さらに処理を行う必要があります。多くのtest _...ファイルがあるので、ほとんどのテストでテスターオブジェクトの作成(MyTesterのインスタンス)を再利用したいと思います。

テスターオブジェクトはDLLの変数と関数への参照を取得したものなので、DLLの変数のリストを各テストファイルのテスターオブジェクトに渡す必要があります(ログに記録される変数はtest_でも同じです)。 。file)。リストの内容は、指定されたデータを記録するために使用されます。

私の考えは、何とかこのようにすることです:

import pytest

class MyTester():
    def __init__(self, arg = ["var0", "var1"]):
        self.arg = arg
        # self.use_arg_to_init_logging_part()

    def dothis(self):
        print "this"

    def dothat(self):
        print "that"

# located in conftest.py (because other test will reuse it)

@pytest.fixture()
def tester(request):
    """ create tester object """
    # how to use the list below for arg?
    _tester = MyTester()
    return _tester

# located in test_...py

# @pytest.mark.usefixtures("tester") 
class TestIt():

    # def __init__(self):
    #     self.args_for_tester = ["var1", "var2"]
    #     # how to pass this list to the tester fixture?

    def test_tc1(self, tester):
       tester.dothis()
       assert 0 # for demo purpose

    def test_tc2(self, tester):
       tester.dothat()
       assert 0 # for demo purpose

このように達成することは可能ですか、それとももっとエレガントな方法がありますか?

通常、ある種のセットアップ関数(xUnitスタイル)を使用して、各テストメソッドで実行できます。しかし、私は何らかの再利用を獲得したいと考えています。備品でこれが可能かどうか誰にもわかりますか?

私はこのようなことができることを知っています:(ドキュメントから)

@pytest.fixture(scope="module", params=["merlinux.eu", "mail.python.org"])

しかし、テストモジュールで直接パラメーター化する必要があります。 テストモジュールからフィクスチャのparams属性にアクセスすることは可能ですか?

87
maggie

これは、実際にはpy.testで 間接パラメーター化 を介してネイティブにサポートされています。

あなたの場合、あなたが持っているでしょう:

@pytest.fixture
def tester(request):
    """Create tester object"""
    return MyTester(request.param)


class TestIt:
    @pytest.mark.parametrize('tester', [['var1', 'var2']], indirect=True)
    def test_tc1(self, tester):
       tester.dothis()
       assert 1
122
imiric

フィクスチャ関数から(したがって、Testerクラスから)要求モジュール/クラス/関数にアクセスできます。 フィクスチャ関数からのテストコンテキストの要求との対話 を参照してください。したがって、クラスまたはモジュールでいくつかのパラメーターを宣言し、テスターフィクスチャがそれを取得できます。

11
hpk42

imiric's answer :この問題を解決するもう1つのエレガントな方法は、「パラメーターフィクスチャ」を作成することです。個人的には、indirectpytest機能よりも好みます。この機能は pytest_cases から利用でき、元のアイデアは Sup3rGeo によって提案されました。

import pytest
from pytest_cases import param_fixture

# create a single parameter fixture
var = param_fixture("var", [['var1', 'var2']], ids=str)

@pytest.fixture
def tester(var):
    """Create tester object"""
    return MyTester(var)

class TestIt:
    def test_tc1(self, tester):
       tester.dothis()
       assert 1

pytest-casesは、フィクスチャでパラメーター化マークを使用できる@pytest_fixture_plusと、別のモジュールの関数からパラメーターを取得できる@cases_dataも提供することに注意してください。詳細については、 doc を参照してください。ちなみに私は著者です;)

2
smarie