Pytest: Using Class Based Test Autouse Fixture Teardowns To Run Post-Test Assertions

Created on 27 Feb 2020  路  1Comment  路  Source: pytest-dev/pytest

Hi, I have a conceptual question.

In general, would it be a bad idea to use the post yield part of an autouse=True fixture to run post test assertions?

The code below passes, and I've used this general strategy once so far in a class based test that uses a lot of different fixtures, albeit only session and function scoped fixtures. It also has a database connection and the test passes. I'm potentially concerned though that if I'm not careful some "teardown" code could get executed by some other fixture before (using the example below) the self.run_post_assertion() teardown code gets executed, messing up the state of the code to where an assertion that would normally work (I.E. querying the database for a value and making sure it's something we expect) breaks because, say the database connection was closed because of some other teardown, etc.

import pytest

class TestSomething:
    @pytest.fixture(autouse=True)
    def setup(self):
        ...
        yield
        self.run_post_assertion()

    def test_one(self):
        ...
        self.result = 1

    def test_two(self):
        ...
        self.result = 2

    def test_three(self):
        ...
        self.result = 3

    def run_post_assertion(self):
        assert 1 <= self.result <= 3
fixtures question

Most helpful comment

I personally would avoid this pattern. While it probably works right now, it's easy to break silently by accident (or just omit a check, such as the self.result = ...), and could also be broken by subtle changes to fixture teardown in your project (e.g. by adding or updating a plugin).

Perhaps implementing the same check as a decorator or a context manager would work? If that's too noisy my next stops would be a class decorator.

>All comments

I personally would avoid this pattern. While it probably works right now, it's easy to break silently by accident (or just omit a check, such as the self.result = ...), and could also be broken by subtle changes to fixture teardown in your project (e.g. by adding or updating a plugin).

Perhaps implementing the same check as a decorator or a context manager would work? If that's too noisy my next stops would be a class decorator.

Was this page helpful?
0 / 5 - 0 ratings