Guide
Steps to reproduce a bug: how to write them, with examples
A developer who can make the bug happen can start fixing it; one who cannot sends questions back and waits for answers. Here is how to write the steps so they can, the first time.
What “steps to reproduce” means
Steps to reproduce (often shortened to “repro steps”) are the shortest list of actions that makes a bug happen again, from a starting point anyone on the team can reach. Somebody else follows them, sees the same wrong result, and from then on the bug is a fact rather than a report.
They are one part of a bug report, next to the title, what you expected, what happened, and where it happened. The bug report template has the rest.
Before you write them
Make it happen twice
Go back and do it again. If it happens every time, say so. If it happens once in a few tries, count the tries: “3 out of 10” tells the developer how long to keep trying before deciding it works for them.
Find the shortest path
You may have met the bug twenty clicks into a session. Start again from a fresh page and remove whatever the bug does not need. A developer follows five steps carefully and skims twenty, and the one they skim may be the one that mattered.
Write down the starting point
Anything that has to be true before step one is a precondition, not a step: signed in as an admin, an item in the cart, an invoice that is unpaid, a phone rather than a laptop. Often, “cannot reproduce” means the developer started from a different place than you did.
How to write the steps
- Number them. The order is the point, and “after step 3” is easier to say than “after you change the filter”.
- One action per step: “Log in, open settings and change the plan” is three steps, and the bug may be in the second.
- Use the words on the screen: write “Press Create account” rather than “submit the form”. The developer searches the code for that label.
- Give the exact values you typed: the email with a “+” in it, the quantity 2, the date in February. Many bugs live in one value and not the others.
- Leave out why you think it broke. A guess in the steps sends the developer to check the guess first.
- End with the expected and the actual result: what should have happened after the last step, and what did instead, as two separate lines.
Preconditions: - Signed in as: (role or account type) - Starting page: https://… - Data needed: (an item in the cart, an unpaid invoice…) Steps to reproduce: 1. 2. 3. Expected result: Actual result: How often: every time / 3 out of 10 / once When: (date and time, with the time zone) Browser and device:
Examples: weak and strong
A form that refuses a valid email
Title: Sign-up form broken Steps to reproduce: 1. Go to sign-up. 2. Fill in the form. 3. Submit. Expected: it works Actual: it doesn't
Title: Sign-up refuses an email with a "+" in it Preconditions: signed out, on https://example.com/signup Steps to reproduce: 1. Type "anna+test@example.com" in Email. 2. Type any password of 8 characters or more in Password. 3. Press "Create account". Expected result: the account is created and the welcome page opens. Actual result: the form says "Enter a valid email" under Email. How often: every time, with any address containing "+" Browser and device: Firefox 131 on Windows 11
The strong version names the exact value that fails and says it fails for every address like it. The developer can reproduce it in ten seconds and already suspects the email check.
A cart total that is wrong
Title: Cart is wrong Steps to reproduce: 1. Add stuff to the cart. 2. Look at the total.
Title: Cart total ignores the discount code after the quantity changes Preconditions: one "Linen shirt" (€40) in the cart, code SPRING10 applied, total shows €36. Steps to reproduce: 1. Open the cart page. 2. Change the quantity of "Linen shirt" from 1 to 2. Expected result: total €72 (2 × €40, minus 10%). Actual result: total €80. The line "SPRING10 −10%" is still shown. How often: every time Browser and device: Safari 18 on iPhone 15
The precondition matters here more than the steps: without the discount code applied first, nobody reproduces it. And the expected result is a number, with the sum written out, so nobody has to argue about what “wrong” means.
When it only happens sometimes
Intermittent bugs usually come from timing or state, such as a slow request the page did not wait for, or a session that expired while the tab sat open. Write the steps you took anyway, then add:
- How often: “2 out of 10 tries”.
- The exact time it happened, with the time zone. The developer can look up that minute in the server’s logs.
- What was different on the tries that failed: a slow connection, a long time on the page, a second tab, a phone.
What steps cannot tell a developer
Steps describe what you did. They cannot describe what the page did between your clicks: the request that came back with a 500, the script that threw an error and stopped. The cause is often there, and nobody sees it unless the browser’s developer tools were open at that moment.
So a strong report has the steps and, next to them, the browser and device, the console errors, and the failed requests. In the cart example above, a line like POST /api/cart/recalculate → 500 would tell the developer where to look before they reproduce anything.
Questions
What does “steps to reproduce” mean?
The shortest list of actions that makes the bug happen again, from a starting point anyone can reach: a page, an account type, some data. If a developer follows them and sees the same thing, the bug is reproducible.
How do you write steps to reproduce a bug that only happens sometimes?
Write the path that triggered it, then say how often it happens (“3 times out of 10”) and what was different when it did: a slow connection, a second tab, a long session. Include the exact time it happened, so the developer can find it in the server logs.
What is the difference between steps to reproduce, expected result and actual result?
The steps are what you did. The expected result is what should have happened after the last step. The actual result is what happened instead. The gap between the last two is the bug.
Do steps to reproduce need to be technical?
No. Use the words on the screen: the button's label, the page's name, the value you typed. The technical part (browser, console errors, failed requests) goes in its own fields next to the steps.
What if I cannot reproduce the bug?
Report it anyway, say it happened once, and write down exactly what you did and when. A bug seen once is still evidence, and the console errors and failed requests from that moment can be enough to find it.
The steps are the part only the reporter can write. The rest should not depend on them opening developer tools. Broken Here puts a button on your site: the reporter clicks what is broken and writes what they did, and the ticket arrives with the page, the browser, the console errors and the failed requests from that moment, and a screenshot. Try it on the demo.