Reproducing Failures
Reproducing a failure means making it happen again on purpose, by recreating the conditions in which it first appeared. For example, during a test run selecting "Place order" shows "Something went wrong". You have reproduced the failure when you know which account, data, environment and steps make it appear again, ideally every time.
The ISTQB Foundation syllabus describes debugging as reproducing a failure, diagnosing it (finding its cause) and fixing the cause. Diagnosis and fixing are usually the developer’s work; reproduction is where the tester contributes most, because the tester saw the failure and knows its conditions. It builds on the lesson on test evidence: the screenshots, logs and timestamps you captured tell you where to start.
Why it matters
A failure that nobody can make happen again is hard to fix, and a fix for it cannot be confirmed by retesting. If the developer cannot reproduce it, the report often comes back as "cannot reproduce" and the defect stays in the product, where users may meet it. Precise conditions shorten diagnosis: "fails for any customer whose saved address has no postal code" points to one area of the code instead of the whole checkout.
For the tester, reproduction is also a check on your own observation: trying again under controlled conditions shows whether the failure is real or came from a slip of your own. And the steps that reproduce it are the basis of confirmation testing after the fix; without reliable steps, a passing retest proves little.
Start from the conditions of the first failure
When a test fails, do not start changing things. First write down everything that was true at that moment. Then repeat the failure exactly as it happened: same build, environment, account, data and steps. If it fails again, you have a reproducible failure and a baseline to compare against. If it does not, something differs from the first time, and that difference is your first clue.
Record more than the steps of the test case:
- Build and environment: build number, environment, configuration and feature flags (switches that turn a feature on or off without a new build).
- Client: browser and version, operating system, device, screen size, language and direction; an Arabic right-to-left page can fail where the English page passes.
- User: role, permissions and account state, such as new, locked or with an expired subscription.
- Data: the exact input values, files and records involved, such as the cart contents and the coupon.
- State: what happened earlier in the session, cookies and cache.
- Time, with the time zone, so the failure can be matched with the server logs.
Isolate the variables: change one thing at a time
Once the failure reproduces, find out which conditions matter. Treat each condition as a variable and change exactly one between attempts, keeping the rest fixed. If the failure disappears when you switch the browser, the browser is part of the trigger; if it stays, the browser is not a factor: leave it out of the steps and note in the report that you ruled it out. Change two things at once and you cannot tell which one made the difference.
To find candidates, compare a failing case with a working one: two accounts, two requests or two sets of data side by side. The difference is often a single field, such as an empty address line, a long name or another currency. Start with the variables most likely to matter and cheapest to change: data, user, browser, environment.
Answer: Every time
Question 2: Change one variable. Does the failure disappear?Browser, user, data or environment: one per attemptAnswer: Yes
Outcome: Part of the triggerKeep it in the report; compare the failing and the working valueAnswer: No, it still fails
Outcome: Not a factorDrop it from the steps, note it as ruled out, change the next variable
Answer: Sometimes
Question 3: Repeat a fixed number of times. Does changing one condition move the rate to 0 or to every attempt?For example 3 of 20 before the change, 0 of 20 after itAnswer: Yes
Outcome: Hidden variable foundPart of the trigger: add it to the conditions, then measure the rate againAnswer: No
Outcome: Still intermittentTry the next condition, or report it with the rate, timestamps and evidence
Answer: Never
Question 4: Do today’s conditions differ from the evidence?Build, account state, data, timeAnswer: Yes
Outcome: Recreate the original conditionsRestore the data, state or build of the first failure, then repeatAnswer: No
Outcome: Not reproducedReport it with the evidence and the attempts you made
Once the trigger is known, remove steps one at a time to reach a minimal reproduction.
- Fails for one user only: compare that user’s data, role and settings with a user for whom it works.
- Fails in one browser only: read that browser’s console and repeat in another version of it.
- Fails only after an earlier action: the state that action leaves behind is a variable too.
Reduce it to a minimal reproduction
The first reproduction usually carries steps that have nothing to do with the failure: you were at step 17 of a long test case. A minimal reproduction is the smallest set of preconditions and steps that still produces the failure. Remove one step or precondition at a time and run again: if the failure still happens, leave it out; if it stops, put it back. Stop when every remaining step is needed.
The result is a report a developer can follow in a minute and a ready-made confirmation test for the fix, often a future regression test case too. State its reliability as a number, such as "5 of 5 attempts", not as "always".
Worked example: an order that fails for one customer
During a regression run on staging, test case TC-214 "Place an order with a saved card" fails: after "Place order" the page shows "Something went wrong" and the network panel shows POST /api/orders returning 500. The tester notes build 4.12.0, account cust-07, a cart of three items with a coupon, the browser and the time, then changes one thing per attempt. Each line below is a round of attempts and what it showed; the report after them is the result.
- Same conditions, twice: fails both times. The failure is reproducible.
- Firefox instead of Chrome: fails. The browser is not a factor.
- Account cust-09 instead of cust-07: the order is created. The account matters, and comparing the two shows one difference: the saved address of cust-07 has an empty postal code.
- Postal code added to cust-07: passes. Removed from cust-09: fails. The empty postal code is the trigger.
- Removing steps one at a time: the coupon, two of the items and the saved card can all go; one item paid by cash on delivery fails too.
- The minimal steps, run 5 times: 5 failures; with a postal code: 0 of 5. The requirement does not say what should happen with an empty postal code, so the report gives both acceptable outcomes and the tester asks the product owner which one is intended.
Title: Placing an order returns 500 when the saved address has no postal code
Build: 4.12.0, staging Browsers: Chrome and Firefox (both fail)
Precondition: signed-in customer whose saved address has an empty postal code
Steps: 1. Add any in-stock product to the cart.
2. Open the cart and select "Checkout".
3. Keep the saved address, choose "Cash on delivery", select "Place order".
Expected: the order is created, or the form asks for a postal code
Actual: "Something went wrong"; POST /api/orders returns 500
Rate: 5 of 5 attempts; with a postal code: 0 of 5
Ruled out: browser, coupon, number of items, payment method (saved card fails too)Intermittent failures: reproduce by repetition
Some failures appear on only some attempts with the same steps. An intermittent failure still has a cause, a variable you have not found or cannot yet control: timing, two users changing the same data at once, state left by an earlier test, caches, the time of day, or which of several servers handled the request.
An automated test that behaves like this is called a flaky test; the cause can be in the test, the environment or the product, and the same method applies. Do not call it random. Measure it:
- Repeat the same steps a fixed number of times, for example 20, and count the failures: "3 of 20" is a reproduction rate.
- Note the time of each failing attempt so it can be matched with the server logs, and compare the log of a failing attempt with the log of a passing one.
- Change one condition and repeat the same number of times. A condition that moves the rate to 0 of 20, or to 20 of 20, is very likely part of the trigger.
- If it stays unreliable, report it with the evidence, the conditions and the rate, marked as intermittent, and never accept one passing run as proof of a fix.
Common mistakes
- Changing several things between attempts, so you cannot tell which change mattered.
- Reporting the first long sequence of steps as it is, including steps that have nothing to do with the failure.
- Writing "always" or "random" instead of the observed rate, or calling a failure intermittent after a single attempt.
- Not recording the conditions of the first failure, so they cannot be recreated later.
- Closing an intermittent failure as "cannot reproduce" after one or two passing attempts.
- Reproducing with real customer data or in production without agreement, instead of recreating data of the same shape in a test environment.
The QA perspective
On a real team, reproduction starts the moment you see an unexpected result: capture the evidence, note the conditions and try once more before moving on. Agree with your lead how long to spend isolating a failure during a run; when the time is up, report what you have and continue. Say what you ruled out ("fails in Chrome and Firefox, for any user whose address has no postal code"), so the developer does not repeat your attempts.
Stay available to the developer, who may reproduce the failure at a lower level, through the API or in a unit test, starting from your minimal steps; offer request ids and timestamps so they can find the server logs. Keep the minimal reproduction with the report: it is the confirmation test after the fix and a candidate for the regression suite.
Practice exercise
Isolate a profile photo upload failure
A report says that changing the profile photo fails with the message "Upload failed". The requirement allows JPG or PNG files of up to 5 MB. The attempts so far are in the table, all on the same build in the same test environment.
Work out what the attempts show and what they do not, decide what to try next and write a minimal reproduction.
# User Browser File Format Size Network Result
1 sara01 Chrome team.png PNG 4.8 MB office Upload failed
2 sara01 Chrome team.png PNG 4.8 MB office Upload failed
3 sara01 Firefox team.png PNG 4.8 MB office Upload failed
4 omar02 Chrome team.png PNG 4.8 MB office Upload failed
5 sara01 Chrome team.jpg JPG 4.8 MB office Upload failed
6 sara01 Chrome team.png PNG 1.9 MB office photo saved
7 omar02 Firefox badge.jpg JPG 0.2 MB office photo saved- Find the attempts that repeat the same conditions and say what they establish.
- For each attempt that changes exactly one thing, name the variable and say whether it matters.
- Find the attempt that cannot be interpreted and explain why.
- Name a condition that never changed, then plan the next attempts and write the minimal reproduction.
Show the model answer
Attempts 1 and 2 repeat the same conditions and both fail: the failure is reproducible.
Attempts 3, 4 and 5 each change one thing (browser, user, format) and all still fail, so none of these is a factor. Attempt 6 changes only the file size (the same picture exported again, smaller) and succeeds: size is a factor, although 4.8 MB appears to be within the 5 MB limit.
Attempt 7 changes five things at once. It passes, but you cannot say which change mattered, so it adds nothing.
The network never changed, so it is not ruled out. Next: the same picture between 1.9 and 4.8 MB (for example 3 and 4 MB) to find where the failure starts, a file of exactly 5 MB and one just above it, and one 4.8 MB upload from another network. Record each file’s exact size in bytes: tools differ on whether 1 MB is 1,000,000 or 1,048,576 bytes, so a "4.8 MB" file may already exceed a limit of 5,000,000 bytes.
Minimal reproduction, to be refined after those attempts: any signed-in user on the office network; open the profile page, select "Change photo", choose a 4.8 MB PNG or JPG file (give its size in bytes) and select "Save". Expected: the photo is saved, since the requirement allows up to 5 MB. Actual: "Upload failed". Rate: 5 of 5 attempts with 4.8 MB files, in two browsers, for two users and in both formats; files of 1.9 MB and 0.2 MB are saved.
Frequently asked questions
Is reproducing a failure the tester’s job or the developer’s?
Both contribute. The ISTQB syllabus describes debugging as reproduction, diagnosis and fixing. In practice the tester supplies a reliable reproduction and its conditions, because the tester saw the failure, and the developer often reproduces it again in a debugger or at a lower level. Finding the defect in the code and fixing it is usually the developer’s work.
What should I do if I cannot reproduce a failure at all?
Report it anyway if the evidence shows that it happened: attach the evidence, the conditions and the attempts you made, and say clearly that you could not reproduce it. Some teams close reports with a "cannot reproduce" resolution, but that closes the report; it does not show that the product is correct. Keep an eye on related tests and logs: a second occurrence gives you new conditions to compare.
How many times should I repeat an intermittent failure?
There is no fixed number. Repeat often enough for the rate to mean something given how often it fails: if it fails about once in ten attempts, three passing attempts prove little. Use the same number of repetitions before and after a change so the rates can be compared; for automated tests, the test runner can repeat a test for you.
Is an intermittent failure the same as a flaky test?
Not quite. "Flaky" usually describes an automated test whose result changes between runs without a code change; the cause may be in the test, the environment or the product. An intermittent failure is product behaviour observed by any means, manual or automated. The diagnosis is the same in both cases: repetition, a rate, and one changed condition at a time.
References
- ISTQB Certified Tester Foundation Level (CTFL) v4.0The foundation syllabus of software testing: test levels and types, test design techniques, test management and tools.
- ISTQB GlossaryThe standard definitions of testing terms — test case, regression testing, severity, priority, boundary value analysis and the rest.
- Eradicating Non-Determinism in Tests (Martin Fowler)Why flaky tests destroy a suite's value, their common causes (isolation, asynchrony, remote services, time, resource leaks) and quarantine as a response.
Practise with Mutqan tools
Compare two JSON documents semantically and highlight added, removed and changed values.
Compare two API responses (e.g. staging vs production) and list every structural and value difference.
Compare two texts line by line or word by word and highlight differences.
Parse User-Agent strings into browser, version, engine, OS, device type and bot detection.
Convert timestamps (seconds, milliseconds, microseconds) to human dates and back, in any timezone.
Go deeper
Your progress on this topic
Not started
Mark the topic complete when you have studied it and done the exercise.
Sign in to track your progress
Mark topics complete, continue where you left off and unlock specialisation exams.