Python 我可以将参数传递给pytest装置吗?
我所有测试的基准是,出租车上至少会有一名乘客。我可以通过一些基本装置轻松实现此设置:Python 我可以将参数传递给pytest装置吗?,python,pytest,fixtures,Python,Pytest,Fixtures,我所有测试的基准是,出租车上至少会有一名乘客。我可以通过一些基本装置轻松实现此设置: from blah import Passenger, Taxi @pytest.fixture def passenger(): return Passenger() @pytest.fixture def taxi(passenger): return Taxi(rear_seat=passenger) 测试基线非常简单: def test_taxi_contains_passenge
from blah import Passenger, Taxi
@pytest.fixture
def passenger():
return Passenger()
@pytest.fixture
def taxi(passenger):
return Taxi(rear_seat=passenger)
测试基线非常简单:
def test_taxi_contains_passenger(taxi)
assert taxi.has_passenger()
当我开始需要更复杂的测试设置时,我的问题就出现了。在某些情况下,我需要出租车有多个乘客,在某些情况下,我需要定义乘客属性。例如:
def test_three_passengers_in_taxi(taxi)
assert taxi.has_passengers(3)
assert taxi.front_passenger_is_not_a_child()
我可以通过为特定的测试使用特定的夹具来解决这个问题。对于上述测试,我将创建以下夹具:
@pytest.fixture
def three_passenger_test_setup(taxi)
taxi.add_front_seat_passenger(Passenger(child=False))
taxi.add_rear_seat_passenger(Passenger())
return taxi
我可以把上面的夹具放到我的测试用例中,一切都很好,但是如果我沿着这条路线走下去,我可能会在每次测试中都得到一个夹具,而且我觉得应该有一种更有效的方法来实现这一点
有没有一种方法可以将参数传递给设备,以便这些参数可以用于创建设备返回的对象?我应该参数化测试函数吗?赛程?或者我是在浪费时间,每次测试都使用一个fixture吗?那
fixture
只是一个Python装饰器
@decorator
def function(args):
...
喜欢
def function(args):
...
function = decorator(function)
因此,您可以编写自己的decorator,将要修饰的函数包装到所需的任何东西和夹具中:
def myFixture(parameter):
def wrapper(function):
def wrapped(*args, **kwargs):
return function(parameter, *args, **kwargs)
return wrapped
return pytest.fixture(wrapper)
@myFixture('foo')
def function(parameter, ...):
...
这将类似于夹具
,但会将一个值('foo'
)作为参数
传递给函数
有没有一种方法可以将参数传递给设备,以便这些参数
可用于创建装置返回的对象?
我应该参数化测试函数吗
您可以将测试参数化与indirect=True
一起使用。
在pytest文档中:。
如图所示:
赛程
另一个可能适合您的选项是使用某些装置,该装置使用参数化指定参数:
@pytest.fixture(params=[3,4])
def number_of_passengers(request):
return request.param
然后从滑行和测试本身访问该夹具:
@pytest.fixture
def taxi(number_of_passengers):
return Taxi(rear_seat=Passenger() * number_of_passengers)
def test_three_passengers_in_taxi(taxi, number_of_passengers)
assert taxi.has_passengers(number_of_passengers)
assert taxi.front_passenger_is_not_a_child()
如果您的测试和断言在您的案例之间非常相似,那么这种方法是很好的
还是我在浪费时间,每次测试都要进行一次固定装置测试
我想说你绝对不应该为每个测试函数创建一个夹具。为此,您可以将设置放在测试中。这实际上是一个可行的替代方案,因为您必须针对出租车的不同情况作出不同的主张
最后,你可以使用的另一种可能的模式是出租车工厂。虽然对于您介绍的示例,它不是很有用,但如果需要多个参数,并且只有一些参数正在更改,则可以创建类似于以下内容的夹具:
from functools import partial
@pytest.fixture
def taxi_factory():
return partial(Taxi, 1, 2, 3)
我们可以使用一个方法来实现这一点,该方法在fixture中获取args并从fixture返回该方法
让我给你举个例子
@pytest.fixture
def my_fixture():
def _method(a, b):
return a*b
return _method
def test_me(my_fixture):
result1 = my_fixture(2, 3)
assert result1 == 6
result2 = my_fixture(4, 5)
assert result2 == 20
我喜欢这个而且很实用你能再解释一下吗?如果我的_fixture()不接受任何参数,为什么我可以将参数传递给它?另外,如果我在测试用例中使用多个fixture,但我只想将参数传递给其中一个,会发生什么情况?@jacobbavlock这样想。当您将fixture函数my\u fixture
作为参数传递给test\u me
时,将调用该函数。返回的值存储在my_fixture
参数中。因此,当您在test\u me
中调用my\u fixture
时,实际上是在调用返回值