python - 在 pytest 中,如何中止夹具拆卸?
问题描述
我们的 pytest 环境有很多固定装置(主要是scope='function'
和scope='module'
),它们正在执行以下形式的操作:
@pytest.yield_fixture(scope='function')
def some_fixture():
... some object initialization ...
yield some_object
... teardown ...
我们使用fixture的teardown阶段(在yield之后)删除一些专门为测试创建的资源。
但是,如果测试失败,我不希望执行拆解,因此我们将拥有仍然存在的资源以进行进一步调试。
例如,这是一个在我们所有测试框架中重复的常见场景:
@pytest.yield_fixture(scope='function')
def obj_fixture():
obj = SomeObj.create()
yield obj
obj.delete()
def test_obj_some_field(obj_fixture):
assert obj_fixture.some_field is True
在这种情况下,如果 中的条件assert
是True
我想要obj.delete()
执行。obj.delete()
但是,如果测试失败,我希望pytest跳过yield
.
谢谢你。
编辑 我希望在不更改夹具和测试代码的情况下完成该过程,我更喜欢自动过程而不是在我们的整个测试代码库中进行此重构。
解决方案
pytest 文档中有一个关于如何执行此操作的示例。基本思想是,您需要在钩子函数中捕获此信息并将其添加到 testitem
中,这在 test 上request
可用,可通过 fixture 提供给 fixture/tests request
。
对你来说,它看起来像这样:
# conftest.py
import pytest
@pytest.hookimpl(tryfirst = True, hookwrapper = True)
def pytest_runtest_makereport(item, call):
# execute all other hooks to obtain the report object
outcome = yield
rep = outcome.get_result()
# set a report attribute for each phase of a call, which can
# be "setup", "call", "teardown"
setattr(item, "rep_" + rep.when, rep)
# test_obj.py
import pytest
@pytest.fixture()
def obj(request):
obj = 'obj'
yield obj
# setup succeeded, but the test itself ("call") failed
if request.node.rep_setup.passed and request.node.rep_call.failed:
print(' dont kill obj here')
else:
print(' kill obj here')
def test_obj(obj):
assert obj == 'obj'
assert False # force the test to fail
如果你运行它pytest -s
(不让 pytest 捕获来自固定装置的输出),你会看到像这样的输出
foobar.py::test_obj FAILED dont kill obj here
这表明我们正在命中条件的正确分支。
推荐阅读
- android - Glide 需要时间来加载大图 Android
- protocol-buffers - libprotobuf-dev libprotoc-dev 或 protobuf-compiler 的区别是什么
- oracle - oracle如何将值转换为变量对象名称
- ruby-on-rails - 如何迭代哈希数据对象并存储在 Rails 中的 SQLite 数据库中?
- smtp - TeamCity 电子邮件通知程序错误 SMTP 端口重置
- python - pandas ValueError:模式不包含捕获组
- c# - 如何在虚拟主机上修复代理后面的 .net 核心
- java - 公共布尔操作:缺少返回语句
- nlp - 我在哪里可以找到英特尔 AI 实验室提供的 nlp_architect 的完整 API 参考
- node.js - 使用 Node.js 和 Nodemailer 在此 Angular 代码中修复此重置密码功能应该做些什么