Background
PR #641 TEST-phase surfaced a test-infra debt: test_staleness.py and pact_context.py interact through a module-level cache that bleeds across tests. The pollution requires importlib.reload(staleness) workarounds in test fixtures to isolate state, surfaced during the post-#628 coverage adversarial review.
Secretary Pass-2 consolidation flagged this as outstanding test-infra debt (recommendation #4).
Symptom
When test_staleness.py runs in the same pytest session as a test that imports pact_context.py, the module-level cache in pact_context retains state from a prior test's setup. Tests that depend on a fresh cache must:
import importlib
import pact_context
import staleness
def test_with_clean_state():
importlib.reload(pact_context) # workaround for cache pollution
importlib.reload(staleness)
# ...
Without reload, tests pass in isolation but flake when ordering changes.
Root cause hypothesis
pact_context.py likely uses a module-level dict / singleton-ish pattern for context state (legitimate runtime optimization, but problematic for testability):
# pact_context.py (hypothesized — to be verified)
_CONTEXT_CACHE = {} # module-level state — survives between tests
def get_session_dir():
if "session_dir" not in _CONTEXT_CACHE:
_CONTEXT_CACHE["session_dir"] = _compute()
return _CONTEXT_CACHE["session_dir"]
staleness.py likely consumes pact_context and inherits the polluted state.
Proposal
Option A — explicit cache-reset hook for tests
# pact_context.py
def reset_for_testing():
"""Pytest fixture hook — clears module-level state."""
_CONTEXT_CACHE.clear()
Test fixtures call pact_context.reset_for_testing() in setup. No importlib.reload needed.
Option B — dependency injection
Refactor pact_context to accept context as a parameter rather than reading from module state. More invasive but eliminates the pollution class entirely.
Option C — pytest fixture autouse
# conftest.py
@pytest.fixture(autouse=True)
def reset_pact_context_cache():
pact_context._CONTEXT_CACHE.clear()
yield
pact_context._CONTEXT_CACHE.clear()
Cheapest fix; doesn't require changes to source modules.
Recommendation
Start with Option A (explicit reset hook) — least invasive, most discoverable. If the pattern recurs across other modules, escalate to Option B (dependency injection) as a broader refactor.
Acceptance criteria
Cross-references
Background
PR #641 TEST-phase surfaced a test-infra debt:
test_staleness.pyandpact_context.pyinteract through a module-level cache that bleeds across tests. The pollution requiresimportlib.reload(staleness)workarounds in test fixtures to isolate state, surfaced during the post-#628 coverage adversarial review.Secretary Pass-2 consolidation flagged this as outstanding test-infra debt (recommendation #4).
Symptom
When
test_staleness.pyruns in the same pytest session as a test that importspact_context.py, the module-level cache inpact_contextretains state from a prior test's setup. Tests that depend on a fresh cache must:Without reload, tests pass in isolation but flake when ordering changes.
Root cause hypothesis
pact_context.pylikely uses a module-level dict / singleton-ish pattern for context state (legitimate runtime optimization, but problematic for testability):staleness.pylikely consumespact_contextand inherits the polluted state.Proposal
Option A — explicit cache-reset hook for tests
Test fixtures call
pact_context.reset_for_testing()in setup. Noimportlib.reloadneeded.Option B — dependency injection
Refactor
pact_contextto accept context as a parameter rather than reading from module state. More invasive but eliminates the pollution class entirely.Option C — pytest fixture autouse
Cheapest fix; doesn't require changes to source modules.
Recommendation
Start with Option A (explicit reset hook) — least invasive, most discoverable. If the pattern recurs across other modules, escalate to Option B (dependency injection) as a broader refactor.
Acceptance criteria
pact_context.pyexposes areset_for_testing()hook that clears module-level cache state.test_staleness.pyfixtures use the explicit hook instead ofimportlib.reload.pytestwith--randomly-seedplugin produces stable results across multiple seeds.pact_context.pydocstring explaining the cache and the test-reset hook.Cross-references
pact-plugin/hooks/shared/pact_context.pypact-plugin/hooks/shared/staleness.pypact-plugin/tests/test_staleness.py