Reproduction Steps
Artifact
A written sequence that causes a defect again, so whoever receives it can bring up the same screen with their own hands.
Why it exists
Reports used to arrive as "it's not working." With no account of what isn't working and how, the only available move is asking back, and an answer routed through the customer takes a day to return. In that day the customer finds another way around it or leaves. The report was honest and completely unusable, which is a combination that recurs.
It got worse when the answer still didn't produce the screen. An engineer walks the same sequence on their own laptop, sees normal behavior, and the ticket closes as "works for me." The problem didn't disappear; it moved somewhere invisible, and the same report arrives again two weeks later.
Causes also got blended together. Five tickets about payment failing sit under one item, when in fact a card limit, a browser extension, and a genuine bug of ours are mixed among them. Writing the sequence down separates the five, and separating them leaves only what we can fix. Reproduction steps finish that separation at the reporting stage instead of the debugging stage.
What goes in it
Six things have to be there for the recipient not to ask back.
- The environment. Browser and version, device, operating system, and what kind of account was logged in. Plenty of behavior differs between a free account and an enterprise one, which makes account type an unusually frequent cause. It costs one line to write and rules out a whole class of cause.
- The preconditions. What had to be true to arrive at that state. Data volume is often the condition — "an account with more than 300 documents" — and without that line the recipient tries it on a fresh account and concludes it's fine.
- The numbered actions, one action per line. "Open settings" has several routes and isn't enough; "click the account photo at the top right" names the place that got clicked, which is what makes two people walk the same path.
- The expected result. This is the most commonly omitted line. Without knowing what the user expected, the recipient can't even judge that the current behavior is wrong, and intended behavior sometimes gets "fixed" as a bug. Writing one sentence about what should have happened costs less than either side spends guessing.
- The actual result. Paste error messages verbatim rather than summarizing, and attach a screenshot and the time it happened. A timestamp lets someone open just that window in the server logs, which cuts the hunt down sharply.
- The reproduction rate. How many times out of five attempts it appeared. Every time and one in five are different classes of cause, and being intermittent is itself a clue that points first at timing or concurrent load.
With all six filled in, the recipient reads it and brings up the same screen. With any one missing, a round trip gets added at that spot, and a round trip is usually half a day. The round trip also leaves no trace on the ticket, so nobody counts how many the missing form is costing.
Who writes it and who reads it
The writer is whoever hit the problem; the reader is whoever fixes it. The distance between them sets the shape of this document. The person who hit it just saw the screen and therefore omits the obvious; the person fixing it doesn't know the obvious. Without a form, the same lines go missing every time.
Three routes bring them in. Customer reports get received by Sofia and transcribed into step form; internal discoveries get written by Noa or Mia directly; and failures caught by automated checks are already steps, since the test code is a list of actions written one per line. The third route is the most precise for exactly that reason.
The reader reproduces before fixing. Once the screen appears the hunt for the cause begins; if it doesn't, the missing lines get requested. The reason for that order is that there's no way to confirm a fix for something never reproduced. A fix shipped against an unreproduced report is a guess with a deploy attached.
The size of a defect's impact on the service is its severity, and that value also gets decided here. The reproduction rate and the range of affected users are the inputs, and both sit in the six lines above.
The record gets used once more after the fix. Transcribe it into a scenario for an E2E test, which drives a real browser the way a user would, and the next occurrence gets caught by a machine before a person sees it.
How it sounds at work
"There are no reproduction steps, so I couldn't start. Just tell me the account type."
One missing line is the whole blocker.
"It shows up once in five tries. It isn't every time."
Handing over the intermittence as a clue.
"The expected result isn't written here. This might be intended behavior."
Whether it's even a bug can't be judged yet.
Pagedeck built the report form with the six lines as empty fields. The change came after learning that people fill in blanks and write one line when there are none. In the first month after the form changed, round trips halved. The form did the work that asking people to write better reports never did.
The record once pointed straight at the cause. A set of steps came in saying search stalled only on accounts with more than 300 documents, and Theo read that line and found the code loading the whole list at once. Without the precondition written down, the answer would have been that a fresh account works fine.
What people get wrong
The most common belief is that longer is better. More information seems helpful, so the whole screen gets described along with all the background. But what the recipient does is not read; it's bring up the same screen. Three lines of actions buried in twenty lines of background costs time to extract. The bar is not length but whether anything has to be asked back. One or two lines per item across the six is enough, and anything longer is usually explanation nobody needed. Trimming is a service to the reader rather than a loss of information.
The other frequent view is that something not reproducible isn't a bug. You can't fix what you can't observe, so this is half right. But a failure to reproduce can mean two things: there's no problem, or the steps are missing a condition. Defects that only appear under a particular time of day, data volume, or level of concurrency are hard to write down, and closing those tickets means they come back. When the same report arrives twice, stop closing it for non-reproduction and go looking for that timestamp in the server logs instead. A second identical report is evidence about the steps, not about the product.
Where to go next
Last updated 2026-09-16