Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rescope a fixture #3377

Closed
timdiels opened this issue Apr 9, 2018 · 5 comments
Closed

Rescope a fixture #3377

timdiels opened this issue Apr 9, 2018 · 5 comments
Labels
type: question general question, might be closed after 2 weeks of inactivity

Comments

@timdiels
Copy link

timdiels commented Apr 9, 2018

I'd like to change the scope of a fixture within a class, e.g.

class TestIndexPage:

  @pytest.fixture
  def response(self, django_app):
    return django_app.get(...)

  def test_valid_html(self, response):
    assert_is_valid_html(response.text)

  @pytest.mark.parametrize('href', logo_hrefs)
  def test_logo_shown(self, response, href):
    assert response.html.body.find('a', href=href)
    ...

gets the response again for each test function, but this is more isolation than I need as my tests don't modify the response. I'd like response to be class scoped to improve performance, but django_app is function scoped. The only way of changing the scope that I can think of is copy pasting the response fixture, and recursively all of its dependencies to change the scope:

@fixture(scope='class')
def response_class(self, django_app_class):
  ...

@fixture(scope='class')
def django_app_class(self, db_class):
  ...

@fixture(scope='class')
def db_class(self, more_stuff_class):
  ...

...

This also assumes the function scoped django_app is not set up in case it would interfere; it's not needed by these tests, but it is used by other tests outside of this class. The alternative is to simply merge all tests into 1, but I'd rather avoid that.

Is there perhaps some juicy feature I'm overlooking?

@pytestbot
Copy link
Contributor

GitMate.io thinks possibly related issues are #538 (Fixture scope documentation), #2246 (Question regarding fixture visibility), #1588 (Proposal to expand fixtures), #1461 (Suggestion: merge .fixture and .yield_fixture), and #1681 (invocation-scoped fixtures).

@nicoddemus
Copy link
Member

Unfortunately I don't think there's any easy solution to this; if your django application does not hold state, perhaps you can change it into a session-scoped fixture instead? You probably only need to actually cleanup/rollback the database before each test, not the django_app object. @pytest-dev/pytest-django-developers might have other thoughts/suggestions.

@nicoddemus nicoddemus added the type: question general question, might be closed after 2 weeks of inactivity label Apr 9, 2018
@timdiels
Copy link
Author

Thanks, that answers my question. For the record, I've mixed things up a bit when simplifying my example; django_app does not depend on db, but my response fixture depends on user which depends on db etc. I could try a session scoped django app since it has no dependencies.

@nicoddemus
Copy link
Member

@timdiels thanks for the follow up. Can we close this?

@timdiels
Copy link
Author

Yes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: question general question, might be closed after 2 weeks of inactivity
Projects
None yet
Development

No branches or pull requests

3 participants