首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PyTest skip module_teardown()

PyTest skip module_teardown()
EN

Stack Overflow用户
提问于 2015-07-15 13:37:48
回答 2查看 2.4K关注 0票数 3

我的测试模块中有下面的代码

代码语言:javascript
复制
def teardown_module():
    clean_database()
def test1(): pass
def test2(): assert 0

我希望只有在某些测试失败时才调用teardown_module() (一些清理代码)。否则(如果全部通过)这段代码不应该被调用。我能用PyTest做这样的把戏吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-09-02 07:49:03

你可以的。但这是个小问题。如这里所写:http://pytest.org/latest/example/simple.html#making-test-result-information-available-in-fixtures执行以下操作,以设置一个属性,用于保存测试调用的每个阶段的状态:

代码语言:javascript
复制
# content of conftest.py
import pytest
@pytest.mark.tryfirst
def pytest_runtest_makereport(item, call, __multicall__):
    rep = __multicall__.execute()
    setattr(item, "rep_" + rep.when, rep)
    return rep

在夹具中,您只需检查这些属性的条件,如下所示:

代码语言:javascript
复制
import pytest
@pytest.yield_fixture(scope="module", autouse=True)
def myfixture(request):
    print "SETUP"
    yield
    # probably should not use "_collected" to iterate over test functions
    if any(call.rep_call.outcome != "passed" for call in request.node._collected):
        print "TEARDOWN"

这样,如果与该模块夹具相关的任何测试没有“通过”(因此“失败”或“跳过”),则条件仍然有效。

票数 3
EN

Stack Overflow用户

发布于 2020-12-22 23:56:06

这里发布的答案和指向文档的链接是有用的,但不足以满足我的需要。如果模块(.py)文件中的任何测试失败,我需要为每个模块独立执行一个模块拆卸函数。

GitHub上有一个完整的示例项目

首先,我们需要一个挂钩将测试函数结果附加到测试节点。这是直接从pytest文档获取的:

代码语言:javascript
复制
# in conftest.py
@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"
    var_name = "rep_" + rep.when
    setattr(item, var_name, rep)

在此之后,我们需要另一个测试用例挂钩来查找模块并将其存储在那里,这样模块就可以很容易地找到它的测试用例。也许有更好的方法,但我找不到。

代码语言:javascript
复制
# also in conftest.py
@pytest.fixture(scope="function", autouse=True)
def _testcase_exit(request):
    yield
    parent = request.node.parent
    while not isinstance(parent, pytest.Module):
        parent = parent.parent
    try:
        parent.test_nodes.append(request.node)
    except AttributeError:
        parent.test_nodes = [request.node]

一旦我们这样做了,最好有一个装饰器函数,让模块在完成时检查它的测试节点,找出是否有任何故障,然后如果调用了与装饰器关联的函数:

代码语言:javascript
复制
# also also in conftest.py
def module_error_teardown(f):
    @wraps(f)
    @pytest.fixture(scope="module", autouse=True)
    def wrapped(request, *args, **kwargs):
        yield
        try:
            test_nodes = request.node.test_nodes
        except AttributeError:
            test_nodes = []

        something_failed = False
        for x in test_nodes:
            try:
                something_failed |= x.rep_setup.failed
                something_failed |= x.rep_call.failed
                something_failed |= x.rep_teardown.failed
            except AttributeError:
                pass
        if something_failed:
            f(*args, **kwargs)
    return wrapped

现在我们有了所有必要的工作框架。现在,具有失败测试用例的测试文件很容易编写:

代码语言:javascript
复制
from conftest import module_error_teardown


def test_something_that_fails():
    assert False, "Yes, it failed."


def test_something_else_that_fails():
    assert False, "It failed again."


@module_error_teardown
def _this_gets_called_at_the_end_if_any_test_in_this_file_fails():
    print('')
    print("Here's where we would do module-level cleanup!")
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31432013

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档