Skip to content

Support usage of other fixtures in xunit style methods: setup() and setup_class() #5289

@rsyring

Description

@rsyring

I've been following #517 for some time and I've recently looked at #4091 in the hope that it would help me figure out how I can get better support for xunit style class fixtures. Here is what I want to be able to do:

@pytest.fixture(scope="session")
def db():
    return database.Database()

class TestIt(object):
    def setup_class(cls, db):
        # This method fails with: TypeError: setup_class() takes exactly 2 arguments (1 given)
        cls.foo = db.build_expensive_foo()

    def setup(self, db):
        # fails with same error as setup_class
        cls.bar = db.build_expensive_bar()

    @pytest.fixture(autouse=True, scope='class')
    def prep_class(self, db):
       # db is available here, but self is an instance, not the class itself, so this
       # doesn't work as intended.  I could use self.__class__, but feel like I
       # shouldn't need to.
        print('prepare', self, db)
        self.foo = 'bar'

    def test_foo_bar(self):
        assert self.foo
        assert self.bar

I seem to have two, maybe distinct, problems:

  1. Despite the work done in Use fixtures to invoke xunit-style fixtures #4091, setup_class and setup do not seem to have access to fixtures (db in this example). I'm not sure if that is intended, an oversight, but the above "feels" like it should work to me.

  2. Using an autouse fixture at the class level gives access to the db fixture but the fact that an instance instead of the class is being passed in makes it non-intuitive on how to store state at the class level.

Suggestion

I'd really like to see setup_class() and setup() get support for using fixtures defined elsewhere. We have a lot of tests that use this pattern to cache test data at the class level and it would be helpful to give those methods access to other fixtures.

I understand from the discussions in the issues and PR that pytest is trying to keep a distinction between xunit style and newer fixture style tests, but I'm not sure why that needs to be the case. Unless there is a technical limitation that makes this hard to support, the UX described above feels well balanced IMO and would be ideal for our code bases that are heavily using setup_class and setup extensively.

Being able to use fixtures as proposed also allows a more gradual transition from one style to another.

  1. Maybe consider passing the class object instead of the instance object to class level methods using a fixture

Version Info

Using Arch Linux. Versions:

(pytest-xunit)rsyring@nanite:~/tmp$ pytest --version
This is pytest version 4.5.0, imported from /home/rsyring/tmp/virtualenvs/pytest-xunit/lib/python3.7/site-packages/pytest.py

(pytest-xunit)rsyring@nanite:~/tmp$ pip freeze
atomicwrites==1.3.0
attrs==19.1.0
more-itertools==7.0.0
pluggy==0.11.0
py==1.8.0
pytest==4.5.0
six==1.12.0
wcwidth==0.1.7

(pytest-xunit)rsyring@nanite:~/tmp$ python --version
Python 3.7.3

Edit: tested with clean virtualenv and Python 3

Metadata

Metadata

Assignees

No one assigned

    Labels

    topic: fixturesanything involving fixtures directly or indirectlytype: proposalproposal for a new feature, often to gather opinions or design the API around the new feature

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions