How I Write Bug Reports

Early in my QA journey, I used to write bug reports that were either too vague or too long. Both extremes cause the same problem — developers lose time figuring out what actually went wrong. Over time, I developed a consistent template and mindset that makes my reports easier to act on. A good bug report isn't about writing a lot, it's about writing the right things. This article walks through the template I use and the thinking behind each field.
the implementation
Write a Title That Speaks for Itself
The title is the first thing a developer reads, so it needs to be specific. Instead of writing "Login doesn't work", I write "Login button does nothing when password field is empty on mobile Safari". A good title includes what broke, under what condition, and where. Anyone reading it should immediately understand the scope of the issue without opening the full report.
Always Include the Environment
The same bug might only appear on a specific browser, device, or app version. Without environment details, a developer might spend hours unable to reproduce it simply because they're testing on the wrong setup. I always include the browser and version, operating system, device type, and the app or build version being tested.
Steps to Reproduce
This is the most critical part of any bug report. The steps need to be numbered, ordered, and precise enough that anyone — including someone unfamiliar with the feature — can follow them and land on the same bug. If a bug only happens under a specific condition, that condition needs to be part of the steps. Vague steps are the number one reason bug reports get bounced back.
Expected vs Actual Result
These two fields turn a vague complaint into a clear problem statement. The expected result describes what the system should do based on requirements or common sense. The actual result describes exactly what it does do instead. Keeping these two separate forces you to think precisely about the gap between intended and broken behavior.
Severity vs Priority
These two are often confused but they mean different things. Severity is about how much damage the bug causes — a broken payment flow is more severe than a misaligned button. Priority is about how urgently it needs to be fixed relative to everything else on the team's plate. A high severity bug might have lower priority if it affects only 0.1% of users. Being clear about both helps the team make better decisions about what to fix first.
Write the Expected Result Clearly
A test case without a clear expected result is just a checklist of steps. I always define exactly what "pass" looks like — the specific response, status code, UI state, or data that should appear. This also makes it much easier when someone else needs to execute or review the test.
Always Attach Evidence
A screenshot or screen recording is worth a hundred words. Whenever possible, I attach visual evidence of the bug, along with browser console errors or network logs if relevant. This removes all ambiguity and dramatically speeds up the reproduction and debugging process on the developer's side.
A good bug report is clear, complete, and reproducible. Start with a specific title, document the exact environment, and write numbered steps that reliably trigger the issue. Always separate expected from actual results, distinguish severity from priority, and attach screenshots or recordings whenever possible. When a bug report is written well, developers spend less time asking questions and more time fixing problems — and that benefits the entire team.
the testing stack
Every tool chosen with purpose — from feature to assertion.
Linear
for linking failed test cases to bug reports and tracking them through the resolution process.
Google Sheets
for quick, lightweight documentation especially in early project stages where a full test management tool feels like overkill.
Jam
for instantly capturing bugs with one click, automatically recording the screen, console logs, and network requests all at once