Chapter 10 introduced Equivalence Partitioning and Boundary Value Analysis as individual techniques. In practice, you never use them in isolation — they form a two-step workflow where EP divides the input space into partitions and BVA selects the most defect-prone values from each partition. Mastering this combined workflow is what transforms a list of requirements into a lean, high-coverage test suite that catches the maximum number of defects with the minimum number of test cases.
The EP + BVA Workflow — Step by Step
For any input field, follow this sequence: identify partitions (EP), then select boundary values within each partition (BVA), then add special-case values for non-standard inputs. The result is a prioritised list of test values that covers every distinct behaviour and probes every known defect hotspot.
# Combined EP + BVA workflow for a product quantity field
# Requirement: Quantity must be 1-999. Free shipping for orders of 100+.
# ── Step 1: Equivalence Partitioning ──
partitions = [
{"id": "EP1", "range": "qty < 1", "valid": False, "behaviour": "Error: minimum 1"},
{"id": "EP2", "range": "1 <= qty <= 99", "valid": True, "behaviour": "Standard shipping ($5)"},
{"id": "EP3", "range": "100 <= qty <= 999","valid": True, "behaviour": "Free shipping"},
{"id": "EP4", "range": "qty > 999", "valid": False, "behaviour": "Error: maximum 999"},
{"id": "EP5", "range": "empty input", "valid": False, "behaviour": "Error: required field"},
{"id": "EP6", "range": "non-numeric", "valid": False, "behaviour": "Error: enter a number"},
{"id": "EP7", "range": "decimal (e.g. 5.5)","valid": False,"behaviour": "Error: whole numbers only"},
{"id": "EP8", "range": "negative number", "valid": False, "behaviour": "Error: minimum 1"},
]
# ── Step 2: BVA — select boundary values for numeric partitions ──
boundary_values = [
# EP1 ↔ EP2 boundary (lower edge)
{"value": 0, "partition": "EP1/EP2", "type": "Boundary", "expected": "Error: minimum 1"},
{"value": 1, "partition": "EP2", "type": "Boundary", "expected": "Standard shipping"},
{"value": 2, "partition": "EP2", "type": "Boundary", "expected": "Standard shipping"},
# EP2 ↔ EP3 boundary (shipping tier change)
{"value": 99, "partition": "EP2", "type": "Boundary", "expected": "Standard shipping ($5)"},
{"value": 100, "partition": "EP3", "type": "Boundary", "expected": "Free shipping"},
{"value": 101, "partition": "EP3", "type": "Boundary", "expected": "Free shipping"},
# EP3 ↔ EP4 boundary (upper edge)
{"value": 998, "partition": "EP3", "type": "Boundary", "expected": "Free shipping"},
{"value": 999, "partition": "EP3", "type": "Boundary", "expected": "Free shipping"},
{"value": 1000,"partition": "EP4", "type": "Boundary", "expected": "Error: maximum 999"},
]
# ── Step 3: Representative values for non-numeric partitions ──
special_values = [
{"value": "", "partition": "EP5", "type": "Special", "expected": "Error: required field"},
{"value": "abc", "partition": "EP6", "type": "Special", "expected": "Error: enter a number"},
{"value": "5.5", "partition": "EP7", "type": "Special", "expected": "Error: whole numbers only"},
{"value": -3, "partition": "EP8", "type": "Special", "expected": "Error: minimum 1"},
]
all_tests = boundary_values + special_values
print("Combined EP + BVA — Product Quantity Field")
print("=" * 70)
print(f"\nStep 1: {len(partitions)} equivalence partitions identified")
print(f"Step 2: {len(boundary_values)} boundary values selected")
print(f"Step 3: {len(special_values)} special-case values added")
print(f"Total: {len(all_tests)} test values\n")
print(f"{'Value':<8} {'Partition':<12} {'Type':<10} {'Expected Result'}")
print("-" * 70)
for t in all_tests:
print(f"{str(t['value']):<8} {t['partition']:<12} {t['type']:<10} {t['expected']}")
Common Mistakes
Mistake 1 — Applying EP without following up with BVA
❌ Wrong: Selecting one representative value from each partition (e.g., 50 for the valid range) and stopping. No boundary values are tested.
✅ Correct: Using EP to identify partitions, then applying BVA to select values at every boundary between partitions. The representative value 50 confirms the partition works; the boundary values 99, 100, 101 catch the off-by-one errors that hide at the edges.
Mistake 2 — Forgetting non-numeric partitions for numeric fields
❌ Wrong: Applying EP only to the numeric range (below min, valid, above max) and not considering empty input, text input, special characters, or decimal numbers.
✅ Correct: Including partitions for every input type the user could enter — empty, text, decimals, negative numbers, extremely large numbers, and special characters. These "type error" partitions frequently reveal unhandled exceptions.