py.test - 如何使用上下文管理器在funcarg /夹具
密切相关的:In python, is there a good idiom for using context managers in setup/teardownpy.test - 如何使用上下文管理器在funcarg /夹具
我有一个在测试中使用固定的时间/时区上下文管理。我想要一个pytest funcarg(或夹具,我们使用pytest
2.2.3,但我可以向后翻译)。我可以这样做:
def pytest_funcarg__fixedTimezone(request):
# fix timezone to match Qld, no DST to worry about and matches all
# Eastern states in winter.
fixedTime = offsetTime.DisplacedRealTime(tz=' Australia/Brisbane')
def setup():
fixedTime.__enter__()
return fixedTime
def teardown(fixedTime):
# this seems rather odd?
fixedTime.__exit__(None, None, None)
...但它有点恶心。在相关的Q jsbueno中指出:问题是如果发生异常,代码没有规定可以正确调用对象的__exit__
方法。
His answer使用元类方法。但是这对于pytest来说并不是那么有用,在pytest中,测试通常只是函数,而不是类。那么解决这个问题的最好方法是什么?涉及runtest hooks的内容?
恐怕目前没有在灯具中使用上下文管理器的优雅方式。但是,如果测试失败的终结将运行:
import contextlib, pytest
@contextlib.contextmanager
def manager():
print 'manager enter'
yield 42
print 'manager exit'
@pytest.fixture
def fix(request):
m = manager()
request.addfinalizer(lambda: m.__exit__(None, None, None))
return m.__enter__()
def test_foo(fix):
print fix
raise Exception('oops')
如果你运行这个与pytest -s
,你会看到__exit__()
调用发生。
由于2.4,py.test
有yield
款式夹具支持。我们可以直接在其内部使用with
上下文。
@pytest.yield_fixture
def passwd():
with open("/etc/passwd") as f:
yield f.readlines()
自3.0,py.test
弃用@pytest.yield_fixture
使用。我们可以直接使用@pytest.fixture
作为上下文管理器。
@pytest.fixture
def passwd():
with open("/etc/passwd") as f:
yield f.readlines()
我认为屈服风格的装置已被弃用? – 2016-08-25 17:22:54
@NeilG感谢您的评论。我更新了pytest 3.0更改的答案。 – 2016-08-26 04:55:01
我担心的不是'__exit__'不能被调用,但它不会被[右值]调用(http://docs.python.org/2/reference/datamodel的.html#上下文经理)。 '__exit__'通常被调用,其值与'with'块中提出的任何异常有关(或者在这种情况下它将是测试主体)。 – pfctdayelise 2013-04-05 01:19:02