Q8 of 38 · Test design

Walk through equivalence partitioning for an age field that accepts 18-65.

Test designMidequivalence-partitioningage-fieldwalkthroughmid

Short answer

Short answer: Partition into Below valid (<18), Valid (18-65), Above valid (>65), plus invalid input classes (non-numeric, negative, missing, decimal). Pick one value per class. Pair with BVA at the boundaries (17, 18, 65, 66) for off-by-one coverage.

Detail

A complete walkthrough of EP for an age field requires identifying every meaningful equivalence class, not just "valid vs invalid".

Step 1: List the input classes.

Class Range Representative
Below valid < 18 12
Valid 18 ≤ age ≤ 65 35
Above valid > 65 80
Negative number < 0 -5
Zero 0 0
Decimal / non-integer 25.5 25.5
Non-numeric "abc" "abc"
Empty / null (no value) null
Numeric overflow > 2^31 2147483648

Some teams collapse "negative" and "zero" into the "below valid" class; others split because the system might handle them differently (clamp to zero vs reject). The honest answer in interview: "I'd ask the spec, and if there's no answer, I'd treat them as separate classes until told otherwise."

Step 2: Pair with BVA for the boundaries: 17 (just below valid lower), 18 (lower boundary — valid), 19 (just above), 65 (upper boundary — valid), 66 (just above upper).

Final test set combining EP and BVA: ~9 EP representatives + 5 BVA = ~14 well-chosen tests covering the input space. A naive "test every value 0–100" is 101 tests for less coverage.

Edge cases worth flagging in interview:

  • Localisation — does the field accept "18 years" or just "18"?
  • Internationalisation — does it accept Arabic / Devanagari numerals?
  • Inclusive vs exclusive boundaries — is 65 valid or does the spec say "under 65"?
  • Date-derived ages — if computed from DOB, what about leap-day-born users approaching their birthday?

// EXAMPLE

test_age.py

import pytest
from validator import classify_age

EP_CASES = [
    (-5,           "negative"),
    (0,            "zero"),
    (12,           "below_valid"),
    (35,           "valid"),
    (80,           "above_valid"),
    (25.5,         "decimal"),
    ("abc",        "non_numeric"),
    (None,         "missing"),
    (2_147_483_648, "overflow"),
]

BVA_CASES = [
    (17, "below_valid"),
    (18, "valid"),
    (19, "valid"),
    (65, "valid"),
    (66, "above_valid"),
]

@pytest.mark.parametrize("age,expected", EP_CASES)
def test_age_ep(age, expected):
    assert classify_age(age) == expected

@pytest.mark.parametrize("age,expected", BVA_CASES)
def test_age_bva(age, expected):
    assert classify_age(age) == expected

// WHAT INTERVIEWERS LOOK FOR

A complete class list (not just valid/invalid), pairing with BVA, and flagging spec ambiguities like inclusive boundaries.

// COMMON PITFALL

Listing only 'valid' and 'invalid' as the two classes — that's the most common junior shortcut.