我试图用Pytest创建一个测试环境。我们的想法是将测试方法分组到类中。
对于每个类/组,我想附加一个将要参数化的config
灯具。这样我就可以使用"配置A"来运行所有测试。然后用"配置B"进行所有测试;等等。
但是,我想要一个reset
夹具,可以在特定方法或类的所有方法之前执行。
我遇到的问题是,一旦我将reset
夹具(应用于某个方法或整个类),config
夹具似乎在函数范围内工作,而不是班级范围。因此,一旦我应用reset
夹具,就会在课程中的每个方法之前/之后调用config
夹具。
以下代码重现了这个问题:
import pytest
from pytest import *
@fixture(scope='class')
def config(request):
print("\nconfiguring with %s" % request.param)
yield
print("\ncleaning up config")
@fixture(scope='function')
def reset():
print("\nreseting")
@mark.parametrize("config", ["config-A", "config-B"], indirect=True)
#@mark.usefixtures("reset")
class TestMoreStuff(object):
def test_a(self, config):
pass
def test_b(self, config):
pass
def test_c(self, config):
pass
测试显示config
装置应该如何工作,对整个班级只执行一次。如果取消注释usefixtures
装饰,您会注意到config
装置将在每个测试方法中执行。 是否可以在不触发此行为的情况下使用reset
灯具?
答案 0 :(得分:4)
正如我在评论中提到的,这似乎是Pytest 3.2.5中的一个错误。
有一种解决方法,即“强制”参数化的范围。因此,在这种情况下,如果您在scope="class"
装饰器中包含parametrize
,则会获得所需的行为。
import pytest
from pytest import *
@fixture(scope='class')
def config(request):
print("\nconfiguring with %s" % request.param)
yield
print("\ncleaning up config")
@fixture(scope='function')
def reset():
print("\nreseting")
@mark.parametrize("config", ["config-A", "config-B"], indirect=True, scope="class")
@mark.usefixtures("reset")
class TestMoreStuff(object):
def test_a(self, config):
pass
def test_b(self, config):
pass
def test_c(self, config):
pass
答案 1 :(得分:0)
这取决于您使用的是哪个版本的pytest。
在旧版 {
"_id": "5a0d424079191657fca9e853",
"reason": "Say Hello",
"approved": false,
"held": false,
"doctor": "5a0add9b577d7916187cd9f2",
"patient": "59f5df20a3071554c5f843e1",
"appointmentStamp": 1510927380000,
"__v": 0,
"createdOn": 1510817910134
}
中实现此问题存在一些语义问题。因此,这个想法尚未在较早的pytest
中实现。有人已经提出了实施相同的建议。你可以参考this
“当参数化测试使用参数化夹具时,夹具范围不起作用”。 这就是错误。 您可以参考this
此问题已在最新版本的pytest中得到解决。这是与pytest
希望它会对你有所帮助。