Q25 of 38 · Manual & exploratory
What's the difference between equivalence partitioning and boundary value analysis? Give a real-world example.
Short answer
Short answer: Equivalence partitioning groups inputs into classes that should behave the same and tests one representative per class. Boundary value analysis tests at the edges of each class (just inside, exactly on, just outside). They're complementary — most test design uses both.
Detail
Equivalence partitioning says "if 18 and 35 are both valid ages, you don't need to test both — they're in the same equivalence class." So you partition the input space (valid, below valid, above valid, wrong type, missing) and pick one value per class.
Boundary value analysis says "off-by-one errors are common at the edges of classes, so test the edges specifically." For an age field accepting 18–65, the boundaries are 17 (just below), 18 (on lower), 65 (on upper), 66 (just above).
A worked example for a discount engine — 10% off orders ≥ £50, free shipping ≥ £100. EP partitions on order total: below £50, £50–£99.99, £100+. Pick one per class: £30, £75, £150. Three tests cover the three behavioural classes.
BVA at the boundaries: £49.99, £50.00, £50.01, £99.99, £100.00, £100.01. Six BVA tests catch off-by-one errors that EP alone wouldn't (developer wrote > 50 instead of >= 50). Most teams write both: 3 EP + 6 BVA = 9 well-chosen tests instead of 100 random values.
Where it breaks down: continuous numeric boundaries are easy; categorical boundaries (strings, enums) are harder, and EP/BVA blur into other techniques like decision tables.
// EXAMPLE
test_discount.py
import pytest
from discount import compute
# Equivalence partition representatives
@pytest.mark.parametrize("total,expected", [
(30, {"discount_pct": 0, "free_shipping": False}), # below £50
(75, {"discount_pct": 10, "free_shipping": False}), # £50–£99.99
(150, {"discount_pct": 10, "free_shipping": True}), # £100+
])
def test_discount_ep(total, expected):
assert compute(total) == expected
# Boundary value analysis
@pytest.mark.parametrize("total,expected", [
(49.99, {"discount_pct": 0, "free_shipping": False}),
(50.00, {"discount_pct": 10, "free_shipping": False}),
(50.01, {"discount_pct": 10, "free_shipping": False}),
(99.99, {"discount_pct": 10, "free_shipping": False}),
(100.00, {"discount_pct": 10, "free_shipping": True}),
(100.01, {"discount_pct": 10, "free_shipping": True}),
])
def test_discount_bva(total, expected):
assert compute(total) == expected