Skip to content

fixtures: refactor FixtureRequest/SubRequest a bit  #11218

@bluetech

Description

@bluetech

The FixtureRequest/SubRequest situation is currently quite confusing.

  • FixtureRequest (on its own, not its subclass SubRequest) is used for the request fixture in a test function itself. One is created even if the request fixture is not explicitly requested. The name is a bit confusing -- it is not a request for a fixture. I think it wanted to be named RequestFixture i.e. the request fixture, but not 100% sure.

    A test function itself cannot be parametrized using request.param, only a fixture can.

    For FixtureRequest the request.scope is always function and the request.node is the item.

    In the pytest internals, it is used to drive getting the fixture values of the fixtures needed by the item (_fillfixtures).

  • SubRequest is used for request inside a fixture. The SubRequest holds a reference to the FixtureDef it handles.

    For parametrized fixtures it holds the parameter value (request.param).

    In the pytest internals, it is used to drive the execution of a specific "fixture request" .

    While executing an item, the SubRequests and the top FixtureRequest form a chain/stack. For example, if we have test_it requesting fix1 requesting fix2, then there is SubRequest(fix2) which points to SubRequest(fix1) which points to FixtureRequest(test_it). This is only used in practice for printing a "fixture stack" in some errors, but is useful to understand conceptually.

SubRequest inherits from FixtureRequest, but in a pretty hard to understand way, e.g. its __init__ doesn't call the super.

As an initial way to clarify things a bit, I propose making FixtureRequest itself abstract, and add a new TopRequest subclass for the test-function request.

The name TopRequest would not be my TopChoice, but renaming FixtureRequest or SubRequest at this point would be a disruptive breaking change, so better to choose a name which makes sense in relation to SubRequest.

This will break plugins which instantiate FixtureRequest directly. It's private so not an official breaking change. I found pytest-alembic, pytest-yield, pytest-wdl, pytest-play. I can notify them about this change if this proposal is accepted.

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