How to Write Test Cases Like a QA Professional: Complete Guide + Examples
Learn how to write professional test cases with clear steps, test data, expected results, preconditions, and reusable templates. Includes practical examples every QA tester should know.
Most test cases fail long before they are executed. They are vague, they mix five checks into one, or they describe what the tester clicked without saying what should happen. The result is a test suite that takes hours to run and still lets serious bugs through.
This guide shows you how to write test cases that are clear, repeatable and good at finding defects, with real examples, a template you can copy, and the design techniques senior testers use every day.
What is a test case?
A test case is a documented set of preconditions, steps, test data and expected results used to verify that one specific behaviour of a system works as required. A good test case can be executed by any tester on the team and will always produce the same pass or fail verdict for the same build.
The key word is specific. One test case checks one behaviour.
Test case vs test scenario vs test script
These terms are often confused in job interviews and in real projects.
| Term | What it is | Example |
|---|---|---|
| Test scenario | A high-level idea of what to test, usually one line | Verify the login functionality |
| Test case | Detailed steps, data and expected result for one check | Login fails with a valid email and a wrong password |
| Test script | An automated version of a test case, written in code | A pytest or Selenium script that runs the login check |
One test scenario usually produces several test cases. Several test cases can later be automated as test scripts.
The fields every test case needs
Tools like Jira with Xray, TestRail or Zephyr name these fields differently, but the content is the same.
| Field | Purpose | Example |
|---|---|---|
| ID | Unique reference for tracking and reporting | TC-LOGIN-003 |
| Title | One-line summary of the behaviour being checked | Login fails with wrong password |
| Preconditions | What must be true before you start | User account [email protected] exists and is active |
| Test data | Exact input values | Email [email protected], password Wrong123 |
| Steps | Numbered actions, one action per step | Open login page, enter email, enter password, click Sign in |
| Expected result | The observable outcome that defines a pass | Error "Invalid email or password" is shown, user stays on login page |
| Priority | How important this check is for regression | High |
| Requirement link | The story or requirement it covers | AUTH-142 |
If you only remember one field, make it the expected result. A test case without a precise expected result is not a test. It is a suggestion.
How to write test cases step by step
- Read the requirement and list its rules. Every condition, limit and error message in the requirement is a candidate test case.
- Write the test scenarios first. Keep them to one line each so you can review coverage quickly with the product owner.
- Break each scenario into test cases. Cover the positive path, the negative paths and the boundaries.
- Define preconditions and test data. Use exact values, never "a valid user".
- Write steps as single actions. Each step should be something a tester can do without interpretation.
- Write an observable expected result. Describe what appears on screen, in the database, in the API response or in the email.
- Peer review. A colleague who did not write the case should be able to execute it without asking you a question.
Test case example: a login page
Requirement: users log in with email and password. The password must be 8 to 64 characters. After 5 failed attempts the account is locked for 15 minutes.
| ID | Title | Test data | Expected result |
|---|---|---|---|
| TC-LOGIN-001 | Login succeeds with valid credentials | Valid email, valid password | User is redirected to the dashboard |
| TC-LOGIN-002 | Login fails with unregistered email | [email protected], any password | Generic error shown, no hint that the email does not exist |
| TC-LOGIN-003 | Login fails with wrong password | Valid email, Wrong123 | Generic error shown, attempt counter increases |
| TC-LOGIN-004 | Password with 7 characters is rejected | Abc1234 | Validation error, request not sent |
| TC-LOGIN-005 | Password with 8 characters is accepted | Abc12345 | Field passes validation |
| TC-LOGIN-006 | Account locks after 5 failed attempts | 5 wrong passwords in a row | Account locked message shown, valid login blocked for 15 minutes |
| TC-LOGIN-007 | Email field is case-insensitive | [email protected] | Login succeeds |
Notice that TC-LOGIN-002 checks a security rule, not just functionality. Telling attackers which emails exist is a real vulnerability, and good test cases catch it.
A test case template you can copy
Paste this header into a spreadsheet or your test management tool and you have a working template.
| ID | Title | Preconditions | Test data | Steps | Expected result | Priority | Requirement | Status |
|---|---|---|---|---|---|---|---|---|
| TC-001 | High | Not run |
Test design techniques that find more bugs
Writing test cases is not about quantity. These four techniques help you find the most defects with the fewest cases.
Equivalence partitioning. Group inputs that the system should treat the same way and test one value from each group. For an age field accepting 18 to 65, test one value below 18, one between 18 and 65, and one above 65.
Boundary value analysis. Bugs cluster at the edges. For the same field, test 17, 18, 65 and 66. Most off-by-one errors are found here.
Decision tables. When the result depends on combinations of conditions, list every combination in a table. This is ideal for discount rules, shipping fees and permissions.
State transition testing. When a feature moves through states, such as an order going from created to paid to shipped to delivered, test every valid transition and at least the most likely invalid ones, such as shipping an unpaid order.
Best practices from real projects
- One test case, one behaviour. If the title needs the word "and", split it.
- Write for someone new to the team. Avoid internal shorthand.
- Keep test data explicit and reusable.
- Link every test case to a requirement so coverage can be measured.
- Review and retire test cases regularly. An outdated case is worse than no case.
- Mark regression candidates clearly. These are your first automation targets.
Common mistakes that make test cases useless
- Vague expected results such as "works correctly" or "page loads fine".
- Too many checks in one case, so a failure does not tell you what broke.
- Only testing the happy path. Most production bugs come from negative and boundary inputs.
- Hidden dependencies between cases, where TC-005 only passes if TC-004 ran first.
- Copying the requirement word for word instead of turning it into concrete, testable checks.
When should a test case be automated?
Automate test cases that are stable, repeated on every release and based on predictable data. Login, checkout and core API flows are classic candidates. Keep exploratory, usability and one-off checks manual. To see where automated cases run once they are scripted, read where QA fits in a CI/CD pipeline.
When an executed test case fails, the next step is a clear defect report. Our guides on how to write a bug report engineers act on and bug severity vs priority cover exactly that.
How many test cases should one requirement have?
There is no fixed number. A simple requirement may need three cases, while a rule with several conditions may need twenty. Use equivalence partitioning and boundary value analysis to find the minimum set that covers every rule, every boundary and every error path.
Should test cases include test data?
Yes. Exact test data makes a test case repeatable. If two testers use different data, they may get different results and argue about whether a bug exists.
Who writes test cases?
QA engineers usually write them, ideally while the feature is still being designed. Reviewing test cases with developers and product owners before coding starts is one of the cheapest ways to catch requirement gaps.
What is the difference between a test case and a bug report?
A test case describes what should happen. A bug report describes what actually happened when the system did not meet that expectation. A failed test case is often the starting point of a bug report.
Key takeaways
- A test case checks one behaviour with exact data and an observable expected result.
- Write scenarios first, then break them into positive, negative and boundary cases.
- Use equivalence partitioning, boundary values, decision tables and state transitions to find more bugs with fewer cases.
- Link cases to requirements and retire outdated ones.
- Stable, repeated cases are your first automation candidates.
Want to practise writing test cases on real applications with feedback from senior engineers? Explore the QAOpsCareer courses.
- software testing
- test cases
- QA testing
- manual testing
- test case template
- test case examples
- software QA
- quality assurance
- QA engineer
- software testing career