๐ Series Navigation:
โ Previous: Part 1 - Requirement Analysis
๐ You are here: Part 2 - Equivalence Partitioning & BVA
Next: Part 3 - Decision Tables & State Transitions โ
Introduction: The Exhaustive Testing Trap
Welcome back to the QA Codyssey! In Part 1, we learned how to analyze requirements and avoid ambiguity traps. Now you have clear requirements and you're ready to write test cases.
So you sit down, crack your knuckles, and think: "I'll just test every possible input!"
Let's do some quick math on that idea, shall we?
Scenario: You're testing a simple password field for TaskMaster 3000.
- Requirements: 8-128 characters, must include at least one number and one special character
- Possible characters: 26 lowercase + 26 uppercase + 10 numbers + 32 special chars = 94 options
- For an 8-character password: 94^8 = 6,095,689,385,410,816 possible combinations
At one test per second, that would take... 193 million years.
Spoiler alert: The heat death of the universe happens before you finish testing.
There has to be a better way. And there is! Today you'll learn two powerful techniques that will help you reduce test cases by 60-70% while maintaining excellent coverage:
- Equivalence Partitioning (EP) - Smart grouping to avoid redundant tests
- Boundary Value Analysis (BVA) - Testing where bugs love to hide
By the end of this article, you'll understand:
- โ Why testing everything is impossible (and unnecessary)
- โ How to identify equivalence classes in any requirement
- โ Where boundaries are and why they matter
- โ How to combine EP and BVA for maximum efficiency
- โ Real test cases you can adapt for your own projects
Let's get started! ๐
๐ฒ Equivalence Partitioning: The Art of Smart Grouping
The Core Concept
Equivalence Partitioning (also called Equivalence Class Testing) is based on a simple but powerful idea:
If one value in a group behaves a certain way, all values in that group will behave the same way.
Think of it like taste-testing ice cream flavors. You don't need to eat an entire tub of chocolate to know it tastes like chocolateโone spoonful tells you everything. The rest of the tub is in the same "equivalence class" (delicious chocolate).
The Science Behind It
Software typically divides inputs into ranges or categories where:
- All values in a valid range are processed the same way
- All values in an invalid range are rejected the same way
Example from our TaskMaster 3000 password requirement:
Requirement: Password must be 8-128 characters long
Instead of testing all 121 possible lengths (8, 9, 10... 128), we can create three equivalence partitions:
0-7 characters
(Invalid)"] A --> C["โ Just Right
8-128 characters
(Valid)"] A --> D["โ Too Long
129+ characters
(Invalid)"] B --> E["Test with: 5 chars"] C --> F["Test with: 64 chars"] D --> G["Test with: 150 chars"] style B fill:#fca5a5 style C fill:#86efac style D fill:#fca5a5 style E fill:#fecaca style F fill:#bbf7d0 style G fill:#fecaca
Magic achieved: We reduced 121 tests to just 3 tests! That's a 97.5% reduction while still covering all scenarios.
How to Identify Equivalence Partitions
Follow this simple process:
Step 1: Identify the input or condition
- Example: Email address, password length, age, subscription tier
Step 2: Look for ranges, categories, or rules
- Numeric ranges (0-100, 101-200)
- Categories (Bronze/Silver/Gold, Low/Medium/High)
- Boolean states (enabled/disabled, true/false)
- Format requirements (email format, phone format)
Step 3: Divide into partitions
- One partition for each valid group
- One partition for each invalid group
Step 4: Select one representative value from each partition
- Pick a typical value (not a boundaryโwe'll cover those next!)
- Document your choice
๐ Real Example: TaskMaster Registration (REQ-001)
Let's apply Equivalence Partitioning to the registration requirement we analyzed in Part 1.
Input 1: Email Address
Requirement: Email must be valid format
Equivalence Partitions:
| Partition ID | Type | Description | Representative Value | Expected Result |
|---|---|---|---|---|
| EP-E1 | Valid | Standard email format | user@example.com |
โ Accept |
| EP-E2 | Valid | Email with subdomain | user@mail.example.com |
โ Accept |
| EP-E3 | Valid | Email with plus addressing | user+tag@example.com |
โ Accept |
| EP-E4 | Invalid | Missing @ symbol | userexample.com |
โ Reject |
| EP-E5 | Invalid | Missing domain | user@ |
โ Reject |
| EP-E6 | Invalid | Missing local part | @example.com |
โ Reject |
| EP-E7 | Invalid | Multiple @ symbols | user@@example.com |
โ Reject |
| EP-E8 | Invalid | Empty string | "" |
โ Reject |
| EP-E9 | Invalid | Special chars in wrong place | user name@example.com |
โ Reject |
Test Cases Generated: 9 (instead of testing hundreds of email variations!)
Input 2: Password Length
Requirement: Password must be 8-128 characters
Equivalence Partitions:
| Partition ID | Type | Length Range | Representative Value | Expected Result |
|---|---|---|---|---|
| EP-P1 | Invalid | 0-7 characters | Pass1! (6 chars) |
โ Reject |
| EP-P2 | Valid | 8-128 characters | SecurePass123! (15 chars) |
โ Accept |
| EP-P3 | Invalid | 129+ characters | A * 130 |
โ Reject |
Test Cases Generated: 3
Input 3: Password Composition
Requirement: Password must contain at least one number AND one special character
Equivalence Partitions:
| Partition ID | Has Number? | Has Special? | Representative Value | Expected Result |
|---|---|---|---|---|
| EP-C1 | โ Yes | โ Yes | Password123! |
โ Accept |
| EP-C2 | โ No | โ Yes | Password!!!! |
โ Reject |
| EP-C3 | โ Yes | โ No | Password1234 |
โ Reject |
| EP-C4 | โ No | โ No | PasswordOnly |
โ Reject |
Test Cases Generated: 4
Sample Test Case Using EP
TC-001-EP-01: Registration with valid email (Standard format partition)
Classification: Functional, Positive
Technique: Equivalence Partitioning
Partition: EP-E1 (Valid standard email)
Precondition:
- User not previously registered
- Registration page loaded
Test Data:
- Email: user@example.com (from EP-E1)
- Password: SecurePass123! (from EP-P2 + EP-C1)
Steps:
1. Navigate to registration page
2. Enter email: "user@example.com"
3. Enter password: "SecurePass123!"
4. Click "Register" button
Expected Result:
โ
Account created successfully
โ
Confirmation message displayed: "Registration successful! Check your email."
โ
Confirmation email sent to user@example.com
โ
User record created in database with hashed password
โ
User redirected to login page OR dashboard
Priority: High
Estimated Time: 2 minutes
๐ Boundary Value Analysis: Where Bugs Live
The Bug Magnet Effect
Here's a truth that will save you countless debugging hours:
Bugs love boundaries like moths love lamps.
Why? Because boundaries are where:
- Developers use
<instead of<= - Off-by-one errors hide
- Integer overflows happen
- Edge cases get forgotten
Research shows: 70% of defects occur at or near boundaries. This isn't a coincidenceโit's where the logic changes, and logic changes are where bugs breed.
The BVA Principle
Boundary Value Analysis tests the edges of equivalence partitions. For any boundary, test:
- The value just below the boundary (invalid side)
- The value at the boundary (minimum valid)
- The value just above the boundary (valid side)
- The value at the upper boundary (maximum valid)
- The value just above the upper boundary (invalid side)
Min-1"] --> B["โ
Min"] B --> C["โ
Min+1"] C --> D["... valid range ..."] D --> E["โ
Max-1"] E --> F["โ
Max"] F --> G["โ
Max+1"] style A fill:#fca5a5 style B fill:#86efac style C fill:#bbf7d0 style E fill:#bbf7d0 style F fill:#86efac style G fill:#fca5a5
๐ฏ Real Example: Task Title Length (REQ-002)
Let's tackle a new requirement from TaskMaster 3000:
REQ-002: Task Creation
Acceptance Criterion: Task title must be between 1-200 characters
Step 1: Identify Boundaries
- Lower boundary: 1 character (minimum)
- Upper boundary: 200 characters (maximum)
Step 2: Define Boundary Values to Test
| Test Point | Characters | Value | Expected Result |
|---|---|---|---|
| Below Min | 0 | "" (empty) |
โ Error: "Title required" |
| At Min | 1 | "A" |
โ Accept |
| Just Above Min | 2 | "AB" |
โ Accept |
| Mid-Range | 100 | "A" * 100 |
โ Accept |
| Just Below Max | 199 | "A" * 199 |
โ Accept |
| At Max | 200 | "A" * 200 |
โ Accept |
| Above Max | 201 | "A" * 201 |
โ Error: "Title too long" |
Test Cases Generated: 7 (covering all critical boundaries)
Step 3: Write Boundary Test Cases
TC-002-BVA-01: Create task with empty title (Below minimum boundary)
Classification: Functional, Negative, Boundary
Technique: Boundary Value Analysis
Precondition:
- User logged in
- Task creation form displayed
Test Data:
- Title: "" (0 characters)
- Description: "This is a valid description"
Steps:
1. Leave title field empty
2. Enter description: "This is a valid description"
3. Click "Create Task" button
Expected Result:
โ Task NOT created
โ Error message displayed: "Title is required"
โ Title field highlighted in red
โ Form remains on screen with data preserved
โ No database entry created
Priority: High
TC-002-BVA-02: Create task with 1-character title (Minimum boundary)
Classification: Functional, Positive, Boundary
Technique: Boundary Value Analysis
Test Data:
- Title: "A" (1 character)
- Description: "Valid description"
Expected Result:
โ
Task created successfully
โ
Task appears in task list with title "A"
โ
Database record created
โ
Success message displayed
Priority: High
TC-002-BVA-03: Create task with 200-character title (Maximum boundary)
Test Data:
- Title: "A" repeated 200 times (200 characters exactly)
- Description: "Testing maximum boundary"
Expected Result:
โ
Task created successfully
โ
Full title stored and displayed
โ
No truncation occurs
โ
UI handles long title gracefully (wraps or truncates display only)
Priority: High
TC-002-BVA-04: Create task with 201-character title (Above maximum)
Test Data:
- Title: "A" repeated 201 times (201 characters)
Expected Result:
โ Task NOT created
โ Error message: "Title must not exceed 200 characters"
โ Character counter shows "201/200" in red (if implemented)
โ "Create" button disabled OR shows error on submit
Priority: High
๐ Combining EP and BVA: The Power Duo
Here's where it gets really powerful. Use both techniques together:
- Use EP to identify partitions and reduce redundant tests
- Use BVA to test the boundaries of those partitions
Example: Password Requirements (Complete Analysis)
Requirement: Password must be 8-128 characters with at least one number and one special character
Step 1: Equivalence Partitions
- Valid: 8-128 chars with number + special
- Invalid: Too short
- Invalid: Too long
- Invalid: Missing number
- Invalid: Missing special
Step 2: Boundary Values
- Length boundaries: 7, 8, 9, 127, 128, 129
Step 3: Combined Test Matrix
| TC ID | Length | Has Number? | Has Special? | Test Value | Expected |
|---|---|---|---|---|---|
| TC-001 | 7 (below min) | โ | โ | Pass1! |
โ Too short |
| TC-002 | 8 (min) | โ | โ | Pass123! |
โ Accept |
| TC-003 | 9 (above min) | โ | โ | Pass1234! |
โ Accept |
| TC-004 | 64 (mid) | โ | โ | 64-char password | โ Accept |
| TC-005 | 127 (below max) | โ | โ | 127-char password | โ Accept |
| TC-006 | 128 (max) | โ | โ | 128-char password | โ Accept |
| TC-007 | 129 (above max) | โ | โ | 129-char password | โ Too long |
| TC-008 | 8 (min) | โ | โ | Password! |
โ No number |
| TC-009 | 8 (min) | โ | โ | Password1 |
โ No special |
| TC-010 | 8 (min) | โ | โ | Password |
โ Missing both |
Result: 10 test cases that cover:
- โ All equivalence partitions
- โ All boundary conditions
- โ All composition requirements
- โ Combinations of failure modes
Compare to exhaustive testing: From potentially thousands of tests down to 10 carefully chosen ones. That's efficiency! ๐ฏ
๐ ๏ธ Practical Tips for EP & BVA
Do's โ
For Equivalence Partitioning:
- โ Always test at least one valid partition
- โ Test ALL invalid partitions (they find different bugs)
- โ Document which partition each test represents
- โ Consider both input partitions AND output partitions
- โ Look for implicit partitions (e.g., null, empty, whitespace)
For Boundary Value Analysis:
- โ Test both boundaries (min AND max)
- โ Test the value just outside each boundary
- โ Consider off-by-one errors (developers' favorite bug!)
- โ Test boundaries of related systems (database limits, API limits)
- โ Remember: dates, times, and currencies have boundaries too!
Don'ts โ
- โ Don't test multiple values from the same partition (waste of time)
- โ Don't skip invalid partitions ("defensive testing" mindset!)
- โ Don't forget negative boundaries (minimum - 1)
- โ Don't assume boundaries are obvious (ask developers!)
- โ Don't ignore implicit boundaries (system limits, database constraints)
Common Pitfalls and How to Avoid Them
Pitfall 1: "I tested one value from each partition, but bugs still slipped through!"
Why it happens: You identified the wrong partitions. Review the requirement more carefully.
Solution: Go back to requirement analysis (Part 1!). Make sure you understand all the rules and constraints.
Pitfall 2: "My boundary tests keep failing because the boundary keeps changing!"
Why it happens: The requirement isn't stable yet.
Solution: Don't write detailed test cases until requirements are finalized. Use exploratory testing instead until things settle.
Pitfall 3: "I found a bug at the boundary, but it was marked 'working as intended'!"
Why it happens: Boundary behavior wasn't specified in requirements.
Solution: When you find boundary ambiguity, raise it immediately. Document the decision in your test case.
๐ Real-World Results: The Numbers
Let me show you the real impact of these techniques on TaskMaster 3000:
Without EP & BVA (Naive Approach)
REQ-001 (User Registration):
- Email testing: 50+ random test cases
- Password testing: 30+ random test cases
- Total: ~80 test cases
- Execution time: 4 hours
- Coverage: ???% (unmeasured chaos)
- Bugs found: 8
With EP & BVA (Smart Approach)
REQ-001 (User Registration):
- Email testing: 9 test cases (EP)
- Password testing: 10 test cases (EP + BVA)
- Boundary testing: 7 test cases (BVA)
- Total: 26 test cases
- Execution time: 1.5 hours
- Coverage: 100% of partitions, 100% of boundaries
- Bugs found: 12 (more bugs, less time!)
Results:
- ๐ 68% fewer test cases (80 โ 26)
- โฑ๏ธ 62% less execution time (4h โ 1.5h)
- ๐ 50% more bugs found (8 โ 12)
- ๐ Measurable coverage (can prove completeness)
Why we found MORE bugs with FEWER tests: Because we tested strategically instead of randomly. We hit the spots where bugs actually hide.
๐ Conclusion: Work Smarter, Not Harder
Let's recap what you've learned in this article:
Key Takeaways
- Exhaustive testing is impossible - and that's okay! Smart testing is about making informed choices.
- Equivalence Partitioning reduces redundancy - Group similar inputs, test one from each group, save 60-70% of your time.
- Boundaries are bug magnets - 70% of defects occur at or near boundaries. Test them thoroughly!
- EP + BVA are stronger together - Use EP to find partitions, use BVA to test their boundaries.
- Document your partitions - Future you (and your teammates) will thank you for showing WHY you chose those specific test values.
Before and After
Before learning EP & BVA:
- "I'll just test a bunch of values and hope I find bugs"
- Random test data
- Can't measure coverage
- Takes forever
- Misses obvious boundary bugs
After learning EP & BVA:
- "I'll systematically cover all partitions and boundaries"
- Strategic test data
- Measurable coverage
- Efficient and thorough
- Catches boundary bugs consistently
Your Action Plan
Next time you write test cases:
- โ Identify all inputs that need testing
- โ Find the equivalence partitions for each input
- โ Identify boundaries between partitions
- โ Select representative values from each partition
- โ Add boundary tests for each boundary
- โ Document your reasoning (which partition, which boundary)
- โ Review with team to ensure you didn't miss partitions
What's Next?
In Part 3, we'll tackle even more complex scenarios with Decision Tables and State Transition Testing. These techniques are perfect for:
- Complex business logic with multiple conditions
- Workflows with many states (like order processing)
- Features where "it depends on..." happens a lot
We'll learn how to:
- Map complex logic into testable tables
- Find missing scenarios in state machines
- Test workflows systematically
- Create visual test documentation with state diagrams
Coming Next Week:
Part 3: Decision Tables & State Transitions - Taming Complex Logic ๐
๐ Series Progress
โ
Part 1: Requirement Analysis
โ
Part 2: Equivalence Partitioning & BVA โ You just finished this!
โฌ Part 3: Decision Tables & State Transitions
โฌ Part 4: Pairwise Testing
โฌ Part 5: Error Guessing & Exploratory Testing
โฌ Part 6: Test Coverage Metrics
โฌ Part 7: Real-World Case Study
โฌ Part 8: Modern QA Workflow
โฌ Part 9: Bug Reports That Get Fixed
โฌ Part 10: The QA Survival Kit
๐งฎ Quick Reference Card
Save this for when you're writing test cases:
EP & BVA Cheat Sheet
EQUIVALENCE PARTITIONING:
1. Find the input
2. Identify valid ranges/categories
3. Identify invalid ranges/categories
4. Pick ONE representative from each partition
5. Test valid + ALL invalid partitions
BOUNDARY VALUE ANALYSIS:
For each boundary, test:
1. Min - 1 (below boundary)
2. Min (at boundary)
3. Min + 1 (above boundary)
4. Max - 1 (below upper boundary)
5. Max (at upper boundary)
6. Max + 1 (above upper boundary)
COMMON BOUNDARIES:
- String length: 0, 1, max, max+1
- Numeric ranges: min-1, min, max, max+1
- Date ranges: past, today, future
- Collections: empty, one item, many items, max capacity
- File size: 0 bytes, 1 byte, max allowed, too large
Remember: Every test case you DON'T need to write is time you can spend finding actual bugs! ๐ฏ
Have questions about EP or BVA? Share your experiences in the comments below!