简体   繁体   中英

Failing a test after teardown_method has executed in pytest

I am trying to figure out how to write a pytest plugin that can be used to fail a test after it has been run (for anyone who wants more context, this is related to astropy/pytest-openfiles#28 ). Let's consider the following simple test file:

class TestClass:

    def setup_method(self, method):
        print("In setup_method")

    def teardown_method(self, method):
        print("In teardown_method")

    def test_simple(self):
        print("In test")

I can now define a conftest.py file that contains:

def pytest_runtest_teardown(item, nextitem):
    print("In pytest_runtest_teardown")

In this hook, I can carry out checks - for example in the case I'm interested in, we are checking for unclosed file handles. However, the issue is that this hook gets run after setup_method and after the test itself ( test_simple ) but before teardown_method :

% pytest test.py -vs
...
collected 1 item                                                                                                                                      

test.py::TestClass::test_simple In setup_method
In test
PASSEDIn pytest_runtest_teardown
In teardown_method

I have considered instead using:

def pytest_runtest_makereport(item, call):

    if call.when != 'teardown':
        return

    print("In pytest_runtest_makereport")

which does get executed after teardown_method but at that point if I raise an exception pytest will output an INTERNALERROR and will still consider the test as successful.

Is there any way to fail/error a test after teardown_method has been called?

After test_simple is over Pytest consider it done, everything from now own will be outside the test scope. You could add @pytest.fixture annotation to a function, this will provide you with pytest setup and teardown functionality. The test itself will be considered ass passed, but not the all suite. TestClass will be marked as failure with the exception raised from teardown_method

class TestClass:

    @pytest.fixture
    def run_for_test(self):
        self.setup_method()
        yield
        self.teardown_method()

    def setup_method(self, method):
        print("In setup_method")

    def teardown_method(self, method):
        print("In teardown_method")
        # just for the example
        if not method:
            raise AssertionError

    def test_simple(self):
        print("In test")

Output

In setup_method
.In test
In teardown_method
>           raise AssertionError
E           AssertionError

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM