
Issue #8 — “The Retry That Hid a Real Bug”
Issue #8 — “The Retry That Hid a Real Bug”

🌼 Lady Daisy Bug: A QA & Test Automation Digest with Personality
Welcome to Lady Daisy Bug — your new favorite corner of the internet where quality assurance meets charm, code, and character. Whether you’re debugging tests in the moonlight or strategizing a flawless regression suite before your first coffee, this newsletter’s for you.
I’m your host, Lady Daisy Bug — part test whisperer, part bug wrangler, and full-time believer in thoughtful testing. Each issue will blend bite-sized insights, automation tips, and a little QA storytelling to brighten your day (and your pipelines).
Let’s squash some bugs — and do it in style.
🌟 Bug of the Week: The Retry That Hid a Real Bug
🕵️ The Mystery
It started like a win. My automation suite was stable. Zero failures. Smooth builds. Everything green. 🌱
Except… something felt off.
One particular test case — the account creation flow — always passed. But it only passed on the second try. Consistently.
No variance. No randomness. Just a silent skip over the first failure.
🔍 Symptoms
The test would:
- Launch the app
- Fill out the account form
- Tap “Create Account”
- Validate success toast & redirected screen
But behind the scenes:
- First click failed silently — the toast never appeared
- Retry logic kicked in
- Second click always worked
To the test runner? All good. To me? A bad feeling in my QA bones.
🧠 Root Cause
After peeling back the logs and sprinkling some strategic print() statements, I found the culprit:
A race condition between UI render and backend binding.
The “Create Account” button was visually present… …but not logically interactable when the first tap occurred.
The automation was too fast. The app wasn’t ready. Retrying worked — but it masked the real bug: poor UI state readiness.
🛠️ How I Found It
- Disabled retries temporarily → test failed 💥
- Took screenshots between steps → noticed no loading spinner 🤔
- Reviewed Appium logs → click happened before input validation loaded
- Added Sentry breadcrumbs → confirmed backend hadn’t completed initialization
✅ The Fix
In the app:
- Updated UI to disable the “Create Account” button until the backend binding completed
- Added an explicit loading state
In the test:
- Replaced retry with a smart wait:
WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.ID, "create_button"))
)
No retries needed. Just respect for async boundaries.
🧪 Test Garden Tip: Smart Retries, Not Blind Ones
Retrying isn’t bad — but make it intentional. Use tools like tenacity to retry just the flaky call, not the whole test.
from tenacity import retry, stop_after_attempt, wait_fixed
@retry(wait=wait_fixed(2), stop=stop_after_attempt(3))
def tap_create_button():
create_button = driver.find_element(By.ID, "create_button")
create_button.click()
✅ Why this is better: It isolates the flaky step and keeps your logs clean. You’ll spot true failures faster — without hiding the root cause under layers of green lies.
💬 Lady’s Log
“Retrying a flaky test is like slapping duct tape on a leaky pipe. It might hold — but you’ll miss the flood forming behind it.”
Flaky tests don’t just waste time — they erode trust. And worse, they can normalize fragility in your system.
Sometimes the best fix isn’t a retry. It’s a magnifying glass 🔍
Keep testing with curiosity. And don’t let “green” fool you.
— 𝓛𝓪𝓭𝔂 𝓓𝓪𝓲𝓼𝔂 𝓑𝓾𝓰 🐞🌼
📚 Petal Picks
- 🌼 “Test Flakiness in Automation” — Lana Begunova
- 🐞 “Test Flakiness in Automation — Continued” — Lana Begunova
- 💥 “Handling Race Conditions in Real-Time Apps” — Matt Lewandowski
- 🛠 Tool of the Week: Sentry.io — with breadcrumbs enabled for async clues
💌 Coming Up Next
The button worked too well. Instead of a single action, it fired twice — purchases doubled, forms submitted twice, chaos everywhere.
Was it a debounce issue, a race condition, or something sneakier? Find out in the next bug tale.