Test Design Techniques: The Art of Finding Bugs Before They Find You 🔍
The Story of the Bug Detective
Imagine you’re a detective. But instead of solving crimes, you’re hunting for bugs hiding in software! Your job is to test everything before users find problems.
But here’s the thing: you can’t test everything forever. That would take a million years!
So, test design techniques are your secret detective tools. They help you find the right places to look—the sneaky corners where bugs love to hide.
🎯 What is a Test Basis?
Think of it Like a Recipe Book
Before you bake a cake, you need a recipe. The recipe tells you:
- What ingredients to use
- How much of each ingredient
- What the cake should look like when done
Test Basis is like that recipe—but for testing!
It’s any document or source that tells you:
- What the software should do
- How it should behave
- What “correct” looks like
Examples of Test Basis
| Document Type | What It Tells You |
|---|---|
| Requirements | “The login button should turn green when clicked” |
| User Stories | “As a user, I want to reset my password” |
| Design Docs | “The page should load in 2 seconds” |
| Code Comments | “This function calculates tax” |
Simple Example
Test Basis: "Password must be 8-20 characters"
From this, you know to test:
✓ Exactly 8 characters (minimum)
✓ Exactly 20 characters (maximum)
✓ Less than 8 (should fail)
✓ More than 20 (should fail)
🧱 Equivalence Partitioning: The Smart Grouping Trick
The Fruit Basket Analogy
Imagine you have a basket with 100 apples. Do you need to taste every single apple to know they’re all sweet?
Nope! You taste ONE apple. If it’s sweet, you assume the whole group is sweet.
That’s Equivalence Partitioning!
How It Works
You divide inputs into groups (partitions) where:
- Everything in the same group behaves the same way
- You only test ONE value from each group
Real Example: Age Validation
The rule: “Users must be between 18 and 65 years old”
graph TD A[All Ages] --> B[Under 18<br>INVALID] A --> C[18 to 65<br>VALID] A --> D[Over 65<br>INVALID] B --> E["Test: Age 10"] C --> F["Test: Age 30"] D --> G["Test: Age 80"]
Instead of testing ages 1, 2, 3, 4… 100, you test just 3 values!
The Groups:
| Partition | Values | Test 1 Value | Expected Result |
|---|---|---|---|
| Too Young | 0 - 17 | 10 | ❌ Reject |
| Valid | 18 - 65 | 30 | ✅ Accept |
| Too Old | 66+ | 80 | ❌ Reject |
📏 Boundary Value Analysis: Testing the Edges
The Fence Analogy
Bugs LOVE hiding at boundaries—like sneaky cats hiding at the edge of a fence!
Why? Because programmers often make mistakes at the “edges”:
- Is it
< 18or<= 18? - Is it
> 65or>= 65?
Boundary Value Analysis focuses on testing these tricky edges.
The Rule: Test the Edges + Neighbors
For any boundary, test:
- Just before the boundary
- Exactly at the boundary
- Just after the boundary
Real Example: Age 18-65 Rule
graph LR A["17<br>❌ Invalid"] --> B["18<br>✅ Valid"] B --> C["19<br>✅ Valid"] D["64<br>✅ Valid"] --> E["65<br>✅ Valid"] E --> F["66<br>❌ Invalid"]
The Test Cases:
| Boundary | Test Values | What We’re Checking |
|---|---|---|
| Lower (18) | 17, 18, 19 | Does 18 get accepted? Does 17 get rejected? |
| Upper (65) | 64, 65, 66 | Does 65 get accepted? Does 66 get rejected? |
Why 6 Tests?
- 17 → Should be rejected (just below minimum)
- 18 → Should be accepted (exact minimum)
- 19 → Should be accepted (just above minimum)
- 64 → Should be accepted (just below maximum)
- 65 → Should be accepted (exact maximum)
- 66 → Should be rejected (just above maximum)
📊 Decision Table Testing: When Rules Get Complicated
The Restaurant Menu Analogy
Imagine a restaurant with special rules:
- Kids under 12 get a free toy
- Seniors over 65 get 20% off
- Members get free dessert
What if someone is a 65-year-old member? They get BOTH the discount AND the dessert!
Decision Tables help you test all these combinations.
How It Works
You create a table with:
- Conditions (inputs) at the top
- Actions (outputs) at the bottom
- Every possible combination
Real Example: Shipping Discount
Rules:
- Order over $100? → Free shipping
- Premium member? → 10% discount
- Both? → Free shipping + 15% discount
| Rule | R1 | R2 | R3 | R4 |
|---|---|---|---|---|
| Order > $100 | No | No | Yes | Yes |
| Premium Member | No | Yes | No | Yes |
| Free Shipping | ❌ | ❌ | ✅ | ✅ |
| Discount | 0% | 10% | 0% | 15% |
Test Cases from the Table:
- R1: $50 order, non-member → No shipping, no discount
- R2: $50 order, member → No shipping, 10% off
- R3: $150 order, non-member → Free shipping, no discount
- R4: $150 order, member → Free shipping, 15% off
You found 4 test cases by looking at combinations!
🔄 State Transition Testing: Testing the Journey
The Traffic Light Analogy
A traffic light doesn’t just show colors randomly. It follows a journey:
🔴 Red → 🟢 Green → 🟡 Yellow → 🔴 Red
Each state (color) leads to the next state based on events (time passing).
State Transition Testing tests these journeys!
The Key Parts
graph TD A[State<br>Where you are now] -->|Event/Trigger| B[State<br>Where you go next] C["🔴 RED"] -->|"Timer: 60 seconds"| D["🟢 GREEN"] D -->|"Timer: 45 seconds"| E["🟡 YELLOW"] E -->|"Timer: 5 seconds"| C
Real Example: User Account States
States: Inactive → Active → Locked → Closed
| Current State | Event | Next State |
|---|---|---|
| Inactive | User verifies email | Active |
| Active | 3 failed logins | Locked |
| Locked | Admin unlocks | Active |
| Active | User closes account | Closed |
Test Cases:
- Create account → Verify email → Should be Active ✅
- Active account → Enter wrong password 3 times → Should be Locked ✅
- Locked account → Admin clicks unlock → Should be Active ✅
- Active account → Click “Close Account” → Should be Closed ✅
Invalid Transitions to Test:
- Can a Closed account become Active? (Should fail!)
- Can you Lock an already Inactive account? (Should fail!)
📖 Use Case Testing: Testing Real Stories
The Movie Script Analogy
A movie has a script. The script tells actors:
- Who does what
- In what order
- What happens if something goes wrong
Use Case Testing is like testing the movie script of your software!
What’s in a Use Case?
- Actor → Who’s using the system (customer, admin)
- Goal → What they want to achieve
- Main Flow → The happy path (everything works)
- Alternative Flows → What if something different happens?
- Exception Flows → What if something goes wrong?
Real Example: Online Purchase
Use Case: Buy a Product
Actor: Customer
Main Flow (Happy Path):
- Customer searches for product
- Customer adds to cart
- Customer enters payment info
- System processes payment
- System confirms order
Alternative Flow:
- Step 2a: Product is out of stock → Show “Out of Stock” message
Exception Flow:
- Step 4a: Payment fails → Show “Payment Declined” message
Test Cases from Use Case:
| Test # | Scenario | Expected Result |
|---|---|---|
| 1 | Complete purchase with valid payment | Order confirmed ✅ |
| 2 | Add out-of-stock item | “Out of Stock” shown |
| 3 | Use expired credit card | “Payment Declined” shown |
| 4 | Empty cart, try to checkout | “Cart Empty” error |
🎯 Putting It All Together
When to Use Each Technique
graph TD A[What are you testing?] --> B{Type of Testing} B -->|Simple ranges| C["Equivalence Partitioning<br>+ Boundary Values"] B -->|Complex rules| D["Decision Tables"] B -->|System journeys| E["State Transition"] B -->|User stories| F["Use Case Testing"]
Quick Reference
| Technique | Best For | Example |
|---|---|---|
| Equivalence Partitioning | Grouping similar inputs | Age ranges, price tiers |
| Boundary Value Analysis | Edge cases | Min/max values |
| Decision Table | Multiple conditions | Discount rules |
| State Transition | System states | Login status, order status |
| Use Case | User journeys | Checkout process |
🌟 Key Takeaways
- Test Basis = Your testing recipe (requirements, specs)
- Equivalence Partitioning = Test ONE from each group (saves time!)
- Boundary Values = Test the EDGES (where bugs hide!)
- Decision Tables = Test all COMBINATIONS of rules
- State Transitions = Test the JOURNEY through states
- Use Cases = Test the USER’S STORY (happy + sad paths)
🎉 You’re Now a Bug Detective!
These techniques are your detective toolkit. With them, you can:
- Find bugs before users do
- Test smartly (not everything, just the right things)
- Feel confident your software works
Remember: Good testers don’t test everything. They test the right things.
Now go find those bugs! 🔍🐛