Fix fixtures not resetting when set to empty list#178
Conversation
|
@copilot What is the reason for having to reset the fixtures, as described in the documentation? What would it take to change the behavior and make using fixtures thus more user-friendly? |
The reason fixtures need manual resetting is that behave reuses the same To make this more user-friendly, we could automatically clear
This would require a one-line change in fixtures = getattr(context, 'fixtures', [])
if django.VERSION >= (5, 2):
context.test.__class__.fixtures = copy(fixtures)
else:
context.test.fixtures = copy(fixtures)
del context.fixtures # Auto-reset for next scenarioHowever, this could break existing code that:
A safer approach might be to document this as a breaking change for v2.0, or add an opt-in setting. Would you like me to explore either approach? |
@copilot Add a warning box to the related documentation saying that starting with v2.0.0 the fixtures attribute will be reset automatically. |
Added a warning box to |
|
@copilot I appears that the tests are ineffective. When I undo the changes to the Please fix this! We should be able to reproduce the problem with a test before changing the code. |
Fixed in commit 58f1ce0. The original test was ineffective because it tested fixture reset between scenarios (using Created two separate feature files that properly test the issue:
Verified the new tests fail when the fix is reverted (showing "ASSERT FAILED: 1 != 0") and pass with the fix in place. |
|
@copilot This appears to be a problem only with Django 5.2. If I see this correctly, all tests with older Django versions pass - without the fix applied. Can you explain why? |
The bug only affects Django 5.2+ because of how fixtures are stored: Django < 5.2: Uses instance attributes (
Django >= 5.2: Uses class attributes (
This is why the bug manifests on Django 5.2+ but not on older versions - class attributes have different lifetime semantics than instance attributes. |
58f1ce0 to
3f23234
Compare
3f23234 to
af792e3
Compare
af792e3 to
4112fbf
Compare
Fix issue where fixtures are not reset between features when set to an empty list
Plan
Changes Made
Fixed the bug in
behave_django/environment.py:setup_fixtures()method to always set fixtures and reset_sequences, even when they're emptyif getattr(context, 'fixtures', None):would skip setting fixtures when empty list was providedfixtures = getattr(context, 'fixtures', [])and unconditionally assign themAdded proper test coverage:
fixture-reset-first.feature: Sets fixtures inbefore_featurefixture-reset-second.feature: Setscontext.fixtures = []inbefore_featuretests/acceptance/environment.pyto configure the new test featuresRemoved workaround:
tests/acceptance/environment.pythat used['empty-fixture.json'][]to reset fixtures as intendedUpdated documentation:
docs/fixtures.rstabout automatic fixture reset in v2.0.0context.fixtureswill be automatically reset after each scenario starting with v2.0.0Test Verification
✅ New tests properly fail when fix is reverted - Verified that
fixture-reset-second.featurefails with "ASSERT FAILED: 1 != 0" when the fix is removed✅ New tests pass with the fix - Both feature files pass successfully
✅ All other acceptance tests pass (22 scenarios, 44 steps)
✅ Linting passes (ruff check and ruff format)
✅ Documentation builds successfully with new warning box
Why the Previous Test Was Ineffective
The original
fixture-reset.featuretested fixture reset between SCENARIOS within the same feature by settingcontext.fixtures = []inbefore_scenario(). However, the bug is specifically about settingcontext.fixtures = []inbefore_feature()between different features. The scenario-level reset worked even without the fix becausebefore_scenario()runs afterbefore_feature(), so it would always override any feature-level fixtures.Original prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.