A test case is a description of a single check: what steps to take and what result to expect. It exists to make the check repeatable — anyone on the team can run it, even a month later, and get the same verdict.
A good test case is like a recipe: clear enough that a new team member can follow it without any questions. Let's look at what goes into one and what makes it good.
What a test case contains
A test case typically has these parts:
- Title — short and to the point: what the check is about. Not "test 1" but "Login with correct username and password."
- Preconditions — what must be in place BEFORE you start. For example: "the user is registered", "there is one item in the cart." This saves steps and removes confusion.
- Steps — numbered actions, one per item. "Open the login page", "Enter the username", "Enter the password", "Click Log in."
- Expected result — what should happen. "The home page opened, the user's name is visible at the top."
Sometimes test data (a specific username/password), a priority, and a link to the requirement are added too. But the core is always steps + expected result.
Example: logging in
Title: Login with correct credentials
Precondition: a user exists with email anna@example.com and password Test1234.
Steps:
- Open the login page.
- Enter
anna@example.comin the "Email" field. - Enter
Test1234in the "Password" field. - Click the "Log in" button.
Expected result: the user lands on the home page, and "Anna" is displayed in the top-right corner.
Notice: the steps are specific (what we enter is written out explicitly), and the expected result is verifiable (you can say unambiguously whether it matched or not). "Everything works" cannot be an expected result — it's unverifiable.
Positive and negative test cases
Any given feature needs several test cases — at least one positive and several negative ones.
- Positive: "Login with correct credentials" (above) — everything is right, the system should let the user in.
- Negative: "Login with wrong password" (we expect an "invalid username or password" error), "Login with empty fields" (we expect the button to be disabled or a hint to appear), "Login with an unregistered email."
Beginner rule: for every positive test case, come up with two or three negative ones. Negative cases catch the most bugs, because developers often don't think through "what if it's entered incorrectly" scenarios.
What makes a test case good
A few markers that separate a good test case from a bad one:
- Unambiguous. Different people will understand it the same way and get the same result. "Enter a valid email" — bad (which one?). "Enter
anna@example.com" — good. - Verifiable result. The expectation can be compared to reality without debate.
- Independent. The test case should not depend on whether you ran another test case first. If it does — move the dependency into the preconditions.
- One check — one case. Don't try to check login, the cart, and checkout all in one test case. Otherwise it's impossible to tell what exactly broke.
- No unnecessary steps. Anything that can be moved into the preconditions, move there. The case should be about the check itself, not ten warm-up clicks.
Where this applies
Test cases are your main working tool and the artifact you leave behind. Written once, they are reused: during regression, when handing a task to a colleague, when returning to a feature six months later. A team with clear test cases doesn't depend on one person's memory.
Where beginners stumble:
- Writing vaguely: "check payment." A week later even the author won't remember what that meant. Be specific in your steps and test data.
- Making the expected result unverifiable: "all ok", "it works." Write exactly what should appear on the screen.
- Cramming everything into one case. One check — one case; otherwise you won't know what broke.
- Writing only positive cases. Without negative test cases you're only testing the ideal user, who doesn't exist.
What to learn next. On a large product there can be hundreds of test cases. To avoid drowning in them, they are organized using test plans and test suites. And to come up with test cases intelligently rather than at random, there are test design techniques.