There’s a category of bug that doesn’t live in the failing test. It lives in some other test, one you’re not even looking at, which reached out from beyond and quietly rearranged the furniture for everyone else. Ours was a single line in test_monitor_engine.py:

sys.modules['boto3'] = MagicMock()

Innocent-looking. Reasonable, even. “I don’t want the real boto3 in this test, so I’ll swap in a mock.” Sensible instinct. Catastrophic blast radius.

Why it haunts

sys.modules is the global registry of imported modules for the entire Python process. When you assign sys.modules['boto3'] = MagicMock() at module level, that line runs the moment pytest collects the file — not when the test runs, not in a fixture that tears down afterward. Just... permanently, for the rest of the session.

So now every other test that does import boto3 doesn’t get boto3. It gets a MagicMock that says “yes” to everything, returns more mocks when you call it, and never, ever raises. Your AWS scanner test “passes.” Your claim-filing test “passes.” They pass because they’re talking to a hallucination that agrees with everything.

It’s a poltergeist. The file that summoned it has long since finished running, but the haunting lingers in sys.modules for every test that comes after.

The debugging experience

The maddening signature: a test passes alone and fails in the suite — or worse, passes in the suite and fails alone. Order-dependent failures are the ghost stories of testing. You run the one test, it’s fine. You run all of them, chaos. The test itself is innocent; it’s just standing where a previous test left a banana peel.

What we actually did

We didn’t exorcise the global mock (it had... reasons, and untangling it was its own quest). Instead we stopped fighting the ghost and patched precisely where each test actually imports, so each test brings its own controlled fake instead of relying on the global one:

# claim_filing tests — patch where it's used, not the global module
patch("sla_monitoring.claim_filing.boto3")

# onboarding tests — same idea, local to the consumer
patch("app.services.onboarding_service.boto3")

The principle: patch the name in the namespace that uses it, scoped to the test, torn down afterward. A with patch(...) or @patch decorator cleans up after itself. sys.modules['boto3'] = MagicMock() cleans up after nobody.

The moral

  • Module-level side effects in test files are global, permanent, and invisible. They run at collection and outlive every test in the file.
  • sys.modules assignment is a process-wide change with no undo. If you must mock an import, scope it with patch so teardown reverses it.
  • When a test’s pass/fail depends on what ran before it, you don’t have a flaky test — you have a haunted one. Look for state leaking across the boundary: sys.modules, module globals, class attributes, singletons.

The call is coming from inside the suite.


Amit Jethva is the CTO and co-founder of Nuvika Technologies Pvt Ltd, makers of Fintropy, a multi-cloud FinOps platform. Learn more at nuvikatech.com.