Pick a depth. Each prompt opens in your AI pre-loaded with the lesson. Click a row to preview the prompt.
A bug report that says 'the login doesn't work' is useless. A bug report that says 'Login with valid credentials returns HTTP 500 on Chrome 124/macOS when the email contains a + character — reproduces 100% of the time, HAR file and screen recording attached' gets fixed the same day. Great bug reports save developer time, reduce back-and-forth, and build your credibility as a QA engineer. Poor reports waste everyone's time and cause bugs to be closed as 'cannot reproduce.' The anatomy of a great bug report is learnable and consistent: title, steps, expected, actual, severity, priority, environment, and evidence.
Bug report quality directly predicts fix time — a report with clear steps, environment, and expected vs actual result gets fixed in hours; a vague one spends three days in 'cannot reproduce.' The template enforces the fields that convert a developer's mental model of 'what could cause this?' into a testable hypothesis. Validation catches the anti-patterns (vague titles, missing environment, circular expected/actual) before the report reaches the queue.
validate(). Did it pass? Fix any validation failures.severity_vs_priority_check() validator: a Critical severity bug must be P1 or P2 — flag it if it's P3/P4. Also flag P1 priority bugs that have severity 'low'. This enforces the distinction: severity = impact on the system, priority = urgency of fix.estimated_impact: str field (e.g., '100% of users trying to register with + in email are blocked'). Write 3 bug titles — then rewrite each to include this impact. Compare the two versions for clarity.from dataclasses import dataclass, field
from typing import List, Optional
import re
@dataclass
class BugReport:
title: str
steps: List[str]
expected: str
actual: str
severity: str # critical | high | medium | low
priority: str # P1 | P2 | P3 | P4
environment: str # browser, OS, version
reproducibility: str # always | intermittent | once
attachments: List[str] = field(default_factory=list)
def validate(self):
errors = []
if len(self.title) < 20:
errors.append("Title too vague — be specific about what fails and where")
if len(self.steps) < 2:
errors.append("Need at least 2 steps to reproduce")
if self.expected == self.actual:
errors.append("Expected and actual results are identical — not a valid bug")
vague_words = ["doesn't work", "broken", "not working", "fails", "error"]
if any(w in self.title.lower() for w in vague_words) and len(self.title) < 50:
errors.append("Title uses vague language — describe the specific symptom")
return errors
def render(self):
print(f"TITLE: {self.title}")
print(f"SEVERITY: {self.severity} | PRIORITY: {self.priority}")
print(f"REPRODUCIBILITY: {self.reproducibility}")
print(f"ENVIRONMENT: {self.environment}")
print(f"STEPS:")
for i, s in enumerate(self.steps, 1):
print(f" {i}. {s}")
print(f"EXPECTED: {self.expected}")
print(f"ACTUAL: {self.actual}")
if self.attachments:
print(f"EVIDENCE: {', '.join(self.attachments)}")
bad_report = BugReport(
title="Login broken",
steps=["Go to login"],
expected="Works",
actual="Doesn't work",
severity="high", priority="P1",
environment="Chrome",
reproducibility="always",
)
good_report = BugReport(
title="Login returns HTTP 500 when email contains a + character",
steps=["Navigate to /login", "Enter email: user+tag@example.com", "Enter valid password", "Click Login"],
expected="Redirect to /dashboard with 200 OK",
actual="HTTP 500 Internal Server Error — 'Invalid email format' in response body",
severity="high", priority="P2",
environment="Chrome 124 / macOS 14.4 / App v2.3.1",
reproducibility="always",
attachments=["screen-recording.mp4", "network-har.json"],
)
print("\n=== BAD REPORT ===")
errors = bad_report.validate()
if errors:
for e in errors: print(f" ⚠ {e}")
print("\n=== GOOD REPORT ===")
errors = good_report.validate()
if errors:
for e in errors: print(f" ⚠ {e}")
else:
print(" ✓ Passes all validation checks")
good_report.render()python3 main.py