Writing Effective Test Cases
You now know four techniques for figuring out what to test — Equivalence Partitioning, Boundary Value Analysis, Decision Tables, and State Transition Testing. But knowing what to test in your head isn't the same as documenting it in a way that anyone on the team — a teammate, your future self three months from now, or a developer reproducing a bug — can follow exactly and get the same result. That's what a test case is for: a precise, repeatable, written recipe (no pun intended) for performing one specific check.
The Standard Test Case Template
Most test case formats — whether in a spreadsheet, TestRail, Zephyr, or Jira Xray — use some version of these fields:
| Field | Purpose |
|---|---|
| Test Case ID | A unique identifier (e.g. TC-ADD-001) so the case can be referenced from a bug report, a test plan, or a traceability matrix. |
| Title | A short, specific sentence describing exactly what's being verified. |
| Preconditions | What must already be true before you start — logged in, on a specific screen, existing data present. |
| Test Steps | The numbered, exact actions to perform, in order — specific enough that two different people would do the same thing. |
| Test Data | The concrete values used while executing the steps — not "a valid title," but the literal string you typed. |
| Expected Result | What should happen if the software is working correctly — written before you run the test, not after. |
| Actual Result | What actually happened when you ran the test — filled in during execution. |
| Status | Pass / Fail / Blocked / Not Run — the outcome, based on comparing Expected vs Actual. |
| Priority | How important this specific case is to run (High/Medium/Low) — helps decide what to run first when time is short. |
What Makes a Test Case Good
- Specific. "Test adding a recipe" is not a test case, it's a topic. "Add a recipe with a title exactly 100 characters long and verify it saves" is a test case.
- Repeatable by someone else. If a teammate who's never used RecipeBox follows your steps and test data exactly, they should land on the same result you did — no guessing about what "a recipe" or "valid data" means.
- One clear expected result. A test case that says "should probably save, or maybe show a warning" isn't testable — a case must have exactly one unambiguous expected outcome, decided in advance.
- Independent test data. Concrete values (an exact title string, an exact number) rather than vague placeholders, so the same steps produce the same result every time.
Worked Example 1: Add Recipe With Valid Data
| Test Case ID | TC-ADD-001 |
|---|---|
| Title | Add a new recipe with all fields filled in correctly and verify it saves |
| Preconditions | User is logged into RecipeBox; user is on the "Add Recipe" screen |
| Test Steps |
1. Enter the title. 2. Enter the ingredients. 3. Enter the steps. 4. Select a category from the dropdown. 5. Enter the prep time. 6. Tap "Save." |
| Test Data | Title: "Tomato Basil Pasta"; Ingredients: "200g pasta, 2 tomatoes, fresh basil, olive oil"; Steps: "Boil pasta. Sauté tomatoes and basil. Combine and serve."; Category: "Dinner"; Prep Time: 25 |
| Expected Result | Recipe saves successfully; a confirmation message is shown; the new recipe ("Tomato Basil Pasta") appears in the Recipe List with category "Dinner" and prep time "25 min" |
| Actual Result | (filled in during execution) |
| Status | (Pass / Fail / Blocked — filled in during execution) |
| Priority | High |
Worked Example 2: Prep Time Rejects an Invalid Value
| Test Case ID | TC-ADD-002 |
|---|---|
| Title | Add a recipe with Prep Time set to 0 and verify it is rejected |
| Preconditions | User is logged into RecipeBox; user is on the "Add Recipe" screen with title, ingredients, and steps already filled in validly |
| Test Steps |
1. Enter a valid title, ingredients, and steps. 2. Enter "0" in the Prep Time field. 3. Tap "Save." |
| Test Data | Title: "Iced Coffee"; Ingredients: "coffee, ice, milk"; Steps: "Combine and stir."; Prep Time: 0 |
| Expected Result | Form is not submitted; a validation error is shown on the Prep Time field (e.g. "Prep time must be at least 1 minute"); recipe is not added to the Recipe List |
| Actual Result | (filled in during execution) |
| Status | (Pass / Fail / Blocked — filled in during execution) |
| Priority | High |
Worked Example 3: Missing Title Blocks Submission
| Test Case ID | TC-ADD-003 |
|---|---|
| Title | Attempt to save a recipe with the Title field left blank and verify it is blocked |
| Preconditions | User is logged into RecipeBox; user is on the "Add Recipe" screen with ingredients and steps already filled in validly |
| Test Steps |
1. Leave the Title field empty. 2. Enter valid ingredients and steps. 3. Tap "Save." |
| Test Data | Title: (blank); Ingredients: "flour, sugar, eggs"; Steps: "Mix and bake at 180°C for 20 minutes." |
| Expected Result | Form is not submitted; a validation error "Title is required" is shown; recipe is not added to the Recipe List |
| Actual Result | (filled in during execution) |
| Status | (Pass / Fail / Blocked — filled in during execution) |
| Priority | High |
Notice how each of the three examples above traces back directly to a technique from earlier lessons: TC-ADD-001 exercises the valid equivalence partition on every field, TC-ADD-002 exercises the Prep Time boundary (0, the min-1 boundary value), and TC-ADD-003 exercises one row of the "Publish Recipe" style decision logic. Good test cases aren't invented from nothing — they come from systematically applying the design techniques you've already learned.
Common Mistakes When Writing Test Cases
- Vague steps like "fill in the form correctly" — correctly according to whom, with what data? Spell out the literal values.
- Missing preconditions — if the tester has to guess what state the app needs to be in first, the case isn't repeatable.
- Multiple unrelated checks crammed into one test case — if step 3 fails, you won't know whether steps 4 and 5 would also have passed. Split unrelated checks into separate cases.
- Writing the Expected Result after running the test. That's just describing whatever happened — it defeats the purpose of having an independent expectation to check against.