пай.тест: передайте параметр к функции приспособления
Я использую 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. Так вы смогли объявить некоторые параметры на классе или модуле и приспособление тестера может выбрать его вверх.