The Three Categories

Every feature needs test cases in three categories: positive tests that confirm the happy path works, negative tests that verify error handling, and boundary tests that check edge values. Skipping any category leaves dangerous gaps.

Positive Test Cases

Positive test cases verify that the system works correctly with valid input under expected conditions. They represent the paths most users will follow.

Characteristics:

  • Use valid, expected input values
  • Follow the intended workflow
  • Verify successful outcomes
  • Answer: “Does the feature work as designed?”

Example — Login form:

Positive TC-1: User logs in with valid email and password
Positive TC-2: User logs in with valid username and password
Positive TC-3: User logs in and "Remember Me" keeps session for 30 days

Example — Shopping cart:

Positive TC-1: Add a single product to empty cart
Positive TC-2: Add multiple quantities of the same product
Positive TC-3: Update quantity from 1 to 5
Positive TC-4: Apply valid coupon code and verify discount

Negative Test Cases

Negative test cases verify that the system handles invalid input gracefully — showing proper error messages, not crashing, and not exposing sensitive data.

Characteristics:

  • Use invalid, unexpected, or malicious input
  • Test error handling and validation
  • Verify appropriate error messages
  • Answer: “Does the feature fail safely?”

Example — Login form:

Negative TC-1: Login with incorrect password — error message shown
Negative TC-2: Login with non-existent email — generic error (no information leakage)
Negative TC-3: Login with empty email and password fields — validation error
Negative TC-4: Login with SQL injection in email field — input sanitized
Negative TC-5: Submit login form with XSS payload in email — input escaped

Example — Shopping cart:

Negative TC-1: Add product with quantity 0 — validation error
Negative TC-2: Add product with negative quantity — validation error
Negative TC-3: Apply expired coupon code — error: "Coupon has expired"
Negative TC-4: Add product that is out of stock — appropriate message
Negative TC-5: Apply coupon to cart below minimum order value — error message

Boundary Test Cases

Boundary test cases target the exact edges of valid input ranges. Most bugs live at boundaries — where the system transitions from accepting to rejecting input.

The boundary value rule: For a range [min, max], test:

  • One value below minimum (min - 1)
  • Minimum value (min)
  • One value above minimum (min + 1)
  • One value below maximum (max - 1)
  • Maximum value (max)
  • One value above maximum (max + 1)

Example — Age field (accepts 18-65):

ValueCategoryExpected Result
17Below boundaryRejected: “Must be at least 18”
18Lower boundaryAccepted
19Just above lowerAccepted
64Just below upperAccepted
65Upper boundaryAccepted
66Above boundaryRejected: “Must be 65 or under”

Example — Password field (8-64 characters):

ValueCategoryExpected Result
7 charsBelow minimumRejected: “Minimum 8 characters”
8 charsMinimum boundaryAccepted
9 charsJust above minimumAccepted
63 charsJust below maximumAccepted
64 charsMaximum boundaryAccepted
65 charsAbove maximumRejected: “Maximum 64 characters”

Common Boundary Types

String Length

Test empty string, 1 character, minimum length, maximum length, maximum + 1.

Numeric Ranges

Test minimum - 1, minimum, maximum, maximum + 1, zero, negative numbers.

Date Fields

Test yesterday vs today (for future-only dates), end of month, leap year (Feb 29), year boundaries.

Collections/Lists

Test empty list, one item, maximum items, maximum + 1 items.

File Uploads

Test empty file, minimum size, maximum size, maximum + 1 byte.

Designing Complete Test Coverage

For any feature, use this systematic approach:

  1. Identify all input fields and their valid ranges
  2. Write positive cases for the most common valid scenarios
  3. Write boundary cases for each input’s min and max values
  4. Write negative cases for each type of invalid input
  5. Add special cases for null, empty, special characters, Unicode

Exercise: Design a Complete Test Suite

Design positive, negative, and boundary test cases for a user registration form with these fields:

  • Username: 3-20 alphanumeric characters, must be unique
  • Email: Valid email format, must be unique
  • Password: 8-128 characters, must contain uppercase, lowercase, digit, special char
  • Age: 13-120, integer only
  • Profile bio: Optional, max 500 characters

Write at least 5 positive, 8 negative, and 6 boundary test cases.

Solution

Positive Test Cases:

  1. Register with valid username (8 chars), valid email, strong password, age 25, no bio
  2. Register with minimum username (3 chars), valid email, password with all required character types, age 30, bio of 100 chars
  3. Register with maximum username (20 chars), valid email, long password (50 chars), age 45, full 500-char bio
  4. Register with alphanumeric username containing digits, Gmail address, password with special chars (!@#), age 18, empty bio
  5. Register with valid data and verify confirmation email received

Negative Test Cases:

  1. Register with username already taken — error: “Username already exists”
  2. Register with email already registered — error: “Email already registered”
  3. Register with invalid email format (no @ symbol) — validation error
  4. Register with password missing uppercase — error: “Must contain uppercase letter”
  5. Register with password missing digit — error: “Must contain a digit”
  6. Register with password missing special character — error specifying requirement
  7. Register with non-integer age (25.5) — validation error
  8. Register with empty required fields — each shows “This field is required”

Boundary Test Cases:

  1. Username with 2 characters (below min) — rejected
  2. Username with 3 characters (minimum) — accepted
  3. Username with 20 characters (maximum) — accepted
  4. Username with 21 characters (above max) — rejected
  5. Age 12 (below minimum) — rejected: “Must be at least 13”
  6. Age 13 (minimum) — accepted
  7. Age 120 (maximum) — accepted
  8. Age 121 (above maximum) — rejected
  9. Password with 7 characters — rejected
  10. Password with 8 characters (all requirements met) — accepted
  11. Bio with 500 characters — accepted
  12. Bio with 501 characters — rejected or truncated

Pro Tips

Tip 1: The 80/20 rule applies — 80% of bugs are found at boundaries and in negative scenarios, not in happy paths. Invest testing time accordingly.

Tip 2: For every positive test case, ask “What could go wrong?” to generate negative cases.

Tip 3: Consider combinations — what happens when two boundary values are entered simultaneously? (Username at max length AND password at min length)

Tip 4: Do not forget null and empty values — they are the most overlooked boundary cases and source of NullPointerExceptions in production.

Key Takeaways

  • Three categories: positive (valid input, happy path), negative (invalid input, error handling), boundary (edge values)
  • Boundary testing checks min, max, and one step beyond each edge
  • Most bugs live at boundaries — invest your testing time there
  • For every input field, test: below min, min, min+1, max-1, max, above max
  • Negative testing protects against crashes, data exposure, and poor user experience
  • Combine categories for complete coverage: positive + negative + boundary for every feature