Skip to main content

Test Case Design

A test case is a set of conditions under which a tester determines whether a feature works correctly. Well-written test cases are the backbone of effective testing.

Anatomy of a Test Case

Every test case should include:

FieldDescription
Test Case IDUnique identifier (e.g., TC-LOGIN-001)
TitleShort description of what's being tested
PreconditionsWhat must be true before the test runs
StepsExact actions to perform
Test DataSpecific inputs to use
Expected ResultWhat should happen
Actual ResultWhat actually happened (filled during execution)
StatusPass / Fail / Blocked / Skipped

Example Test Case

Test Case ID: TC-LOGIN-001
Title: Successful login with valid credentials
Preconditions: User account exists with email test@example.com
Steps:
  1. Navigate to /login
  2. Enter "test@example.com" in the email field
  3. Enter "ValidPass123!" in the password field
  4. Click the "Sign In" button
Test Data: email=test@example.com, password=ValidPass123!
Expected Result: User is redirected to the dashboard

Test Design Techniques

Equivalence Partitioning

Divide inputs into groups (partitions) where the system should behave the same way. Test one value from each partition instead of every possible value.

Example: An age field that accepts 18–65.

PartitionValuesExpected
Below range0–17Rejected
Valid range18–65Accepted
Above range66+Rejected

You only need three tests instead of testing every number from 0 to 100.

Boundary Value Analysis

Bugs love boundaries. Test the exact edges of each partition:

  • 17 (just below valid) → Rejected
  • 18 (lower boundary) → Accepted
  • 65 (upper boundary) → Accepted
  • 66 (just above valid) → Rejected

Decision Tables

When a feature has multiple conditions that combine to produce different outcomes, use a decision table:

ConditionRule 1Rule 2Rule 3Rule 4
Valid emailYesYesNoNo
Valid passwordYesNoYesNo
ActionLogin successError: wrong passwordError: wrong emailError: invalid credentials

State Transition Testing

For features with distinct states, map the transitions:

[Logged Out] --login--> [Logged In] --timeout--> [Session Expired]
[Logged In] --logout--> [Logged Out]
[Session Expired] --refresh--> [Logged In]
[Session Expired] --ignore--> [Logged Out]

Test each transition to verify the system moves between states correctly.

Positive vs Negative Testing

  • Positive testing: Verify the system works with valid inputs ("happy path").
  • Negative testing: Verify the system handles invalid inputs gracefully (empty fields, SQL injection, oversized files).

Both are essential. A system that only works on the happy path is fragile.

Writing Tips

  • Be specific: "Enter a valid email" is vague. "Enter test@example.com" is testable.
  • One thing per test case: Don't test login and password reset in the same case.
  • Independent tests: Each test should work without relying on another test's outcome.
  • Cover edge cases: Empty strings, max length, special characters, Unicode.