Пи.тест: передайте параметр к функции приспособления
Я использую py.тест для тестирования некоторого кода DLL, завернутого в класс python MyTester.
Для проверки цели мне нужно зарегистрировать некоторые тестовые данные во время тестов и сделать больше обработки после этого. Как у меня много test_... файлы я хочу повторно использовать создание объекта 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-style). Но я хочу получить какое-то повторное использование. Кто-нибудь знает, возможно ли это с помощью светильники вообще?
Я знаю, что могу сделать что-то вроде этого: (из документов)
@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 ...и так далее.
попытка решения ОП была направлена вправо направление, а так же @hpk42's ответ предлагает,
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
вы можете получить доступ к запрашивающему модулю / классу / функции из функций прибора (и, следовательно, из вашего класса тестера), см. взаимодействие с запросом тестового контекста из функции приспособления. Таким образом, вы можете объявить некоторые параметры в классе или модуле, и тестер может забрать его.
Comments