пай.тест: передайте параметр к функции приспособления

Я использую py.тест для тестирования некоторого DLL-кода, завернутого в класс python MyTester. Для проверки цели мне нужно зарегистрировать некоторые тестовые данные во время тестов и сделать больше обработки после этого. Как у меня много испытаний... файлы я хочу повторно использовать создание объекта tester (экземпляр MyTester) для большинства моих тестов.

поскольку объект tester-это тот, который получил ссылки на переменные и функции DLL, мне нужно передать список переменных DLL объекту tester для каждого из тестовых файлов (переменные для регистрации одинаковы для test_... папка.) Содержание списка должно использоваться для регистрации указанных данных.

моя идея сделать это как-то так:

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 приспособления из тестового модуля?

3 ответов


у меня была похожая проблема-у меня есть приспособление под названием test_package, и позже я хотел иметь возможность передать дополнительный аргумент этому приспособлению при запуске его в определенных тестах. Например:

@pytest.fixture()
def test_package(request, version='1.0'):
    ...
    request.addfinalizer(fin)
    ...
    return package

(для этих целей не имеет значения, что делает прибор или какой тип объекта возвращается package) является.

тогда было бы желательно как-то использовать это приспособление в тестовой функции таким образом, чтобы я также мог указать version аргумент к этому приспособление для использования с этим тестом. В настоящее время это невозможно, хотя может сделать хорошую функцию.

в то же время это было достаточно легко сделать, мое приспособление просто вернуть функции это делает всю работу, которую ранее делал прибор, но позволяет мне указать :

@pytest.fixture()
def test_package(request):
    def make_test_package(version='1.0'):
        ...
        request.addfinalizer(fin)
        ...
        return test_package

    return make_test_package

теперь я могу использовать это в моей тестовой функции как:

def test_install_package(test_package):
    package = test_package(version='1.1')
    ...
    assert ...

и так далее.

попытка решения OP была направлена вправо направлении, и как @hpk42 это ответ предлагает,MyTester.__init__ можно просто сохранить ссылку на запрос, например:

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

    def dothis(self):
        print "this"

    def dothat(self):
        print "that"

затем используйте это для реализации приспособления, например:

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

при желании MyTester класс может быть немного реструктурирован, чтобы его .args атрибут может быть обновлен после его создания, чтобы настроить поведение для отдельных тестов.


это фактически поддерживается изначально в py.тест через косвенная параметризация.

в вашем случае у вас было бы:

@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

вы можете получить доступ к запрашивающему модулю / классу / функции из функций крепления (и, следовательно, из вашего класса тестера), см. взаимодействие с запросом контекста теста из функции fixture. Так вы смогли объявить некоторые параметры на классе или модуле и приспособление тестера может выбрать его вверх.