Skip to content

Add scenarios_class: return a test class instead of injecting into the caller module (#545)#814

Draft
golikovichev wants to merge 2 commits into
pytest-dev:masterfrom
golikovichev:feature/545-scenarios-class
Draft

Add scenarios_class: return a test class instead of injecting into the caller module (#545)#814
golikovichev wants to merge 2 commits into
pytest-dev:masterfrom
golikovichev:feature/545-scenarios-class

Conversation

@golikovichev

Copy link
Copy Markdown
Contributor

Draft for discussion #545. Opening it early, as discussed, so you can redirect on the API shape before I build out the deprecation path.

What this does

Adds scenarios_class(*feature_paths, ...), which parses the feature files exactly like scenarios() but returns a class instead of injecting the generated tests into the caller module:

from pytest_bdd import scenarios_class

TestLogin = scenarios_class("login.feature")

The generated tests are now visible to editors and linters, and a single scenario can be overridden by subclassing:

class TestLogin(scenarios_class("login.feature")):
    @staticmethod
    @pytest.mark.xfail(reason="known issue")
    @scenario("login.feature", "Failed login")
    def test_failed_login():
        ...

Method names follow the same test_<scenario name> convention (and the same collision suffixing) as scenarios().

Notes and open questions

  • Name. scenarios_class is provisional. Happy to rename to feature_tests or whatever reads best to you.
  • Override needs @staticmethod. The generated wrapper only takes the request and example fixtures, not self, so the methods are stored as staticmethods and an override has to be a staticmethod too (see the second test). If you would rather the override read as a plain method, @scenario would need to become method-aware. Wanted your call before going further.
  • Deprecation path (your steer). Not in this draft. The plan is to emit a DeprecationWarning from scenarios() pointing at the new API, then drop the injection in the next major so it fails loudly. One wrinkle: pytest.ini turns pytest_bdd warnings into errors, so the warning needs the right stacklevel (point at the user module) and the existing suite may need an explicit filter. Happy to do that in a follow-up once the API shape is settled.

Tests

  • scenarios_class returns a collectable class and runs every scenario.
  • subclassing overrides one scenario while the rest run from the base class.

golikovichev and others added 2 commits June 19, 2026 23:19
…pytest-dev#545)

scenarios_class parses the feature files like scenarios() but returns a class
whose test_* methods run the scenarios, instead of injecting them into the
caller module. The generated tests are then visible to editors and linters,
and a single scenario can be overridden by subclassing the returned class.
@codecov

codecov Bot commented Jul 3, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 86.04651% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.92%. Comparing base (9454b38) to head (dbc3034).

Files with missing lines Patch % Lines
src/pytest_bdd/scenario.py 75.00% 1 Missing and 5 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #814      +/-   ##
==========================================
- Coverage   96.10%   95.92%   -0.19%     
==========================================
  Files          55       56       +1     
  Lines        2390     2431      +41     
  Branches      136      144       +8     
==========================================
+ Hits         2297     2332      +35     
- Misses         56       57       +1     
- Partials       37       42       +5     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants