py.test:将一个parameter passing给一个fixture函数

我正在使用py.test来testing包装在python类MyTester中的一些DLL代码。 为了validation目的,我需要在testing过程中logging一些testing数据,然后再做更多的处理。 因为我有很多testing_…文件,我想在testing中重用testing器对象的创build(MyTester的实例)。

由于testing者对象是获得对DLL的variables和函数的引用的对象,因此我需要将每个testing文件的DLLvariables列表传递给testing者对象(要logging的variables对于testing是相同的。 。文件)。 列表的内容应该用来logging指定的数据。

我的想法是这样做:

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)为每个testing方法执行此操作。 但我想获得某种重用。 有没有人知道这是可能的夹具?

我知道我可以做这样的事情:(从文档)

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

但是我需要直接在testing模块中进行参数化。 是否有可能从testing模块访问灯具的参数属性?

我有一个类似的问题 – 我有一个名为test_package的夹具,后来我想在特定的testing中运行它时,能够将可选parameter passing给该夹具。 例如:

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

(这些目的无关紧要,或者返回的package是什么types)。

然后以某种方式在testing函数中使用这个夹具,以便我也可以指定该夹具的version参数用于该testing。 这目前是不可能的,虽然可能会成为一个很好的function。

与此同时,很容易使我的灯具返回一个函数 ,完成灯具之前所做的所有工作,但是允许我指定version参数:

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

现在我可以在我的testing函数中使用这个:

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

等等。

OP的尝试解决scheme是朝着正确的方向前进的,正如@ 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类可以重新MyTester一点,这样它的.args属性可以在创build后被更新,以调整个别testing的行为。

这实际上是通过间接参数化在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 

您可以从fixture函数(也就是您的Tester类)访问请求的模块/类/函数,请参阅从fixture函数请求testing上下文进行交互 。 所以你可以在一个类或模块上声明一些参数,testing仪器可以把它拿起来。