| name | test-case-writing |
| description | Skill for test case design — equivalence partitioning, boundary value analysis, test data builders, and test coverage strategy. |
| stage | testing |
| type | delivery-skill |
| version | 3.0 |
| category | delivery |
| scope | platform |
| tags | ["methodology","testing","test-design"] |
Test Case Writing Skill
Purpose
Guides systematic test case design to maximize defect detection with a manageable number of test cases.
Equivalence Partitioning
Divide input domain into classes where all values produce the same behavior. Test at least one value from each partition.
Process
- Identify input parameters
- For each parameter, define valid and invalid partitions
- Select one representative value from each partition
- Combine partitions — one test case per interesting combination
Example: Order Quantity (valid range: 1-999)
| Partition | Values | Expected | Test Value |
|---|
| Below minimum | < 1 | Validation error | 0 |
| Valid range | 1-999 | Accepted | 50 |
| Above maximum | > 999 | Validation error | 1000 |
| Null/missing | null | Validation error | null |
| Negative | < 0 | Validation error | -1 |
Multi-Parameter Strategy
- Each-choice (minimum): one test per partition, ensuring each partition appears at least once
- Pairwise (thorough): all 2-way combinations of partitions
Boundary Value Analysis
Bugs cluster at partition boundaries. Test exact boundary values and adjacent values.
For each boundary, test:
- Value just below the boundary
- The boundary value itself
- Value just above the boundary
Boundary Types
- Numeric ranges: min-1, min, min+1, max-1, max, max+1
- String lengths: empty, 1, max-1, max, max+1
- Collection sizes: empty, 1, max-1, max, max+1
- Date ranges: day before start, start, end, day after end
- State transitions: just before trigger, at trigger, just after
Test Coverage Strategy
Required Tests per Feature
- Happy path: primary use case with typical input — verify return value, side effects, response format
- Error paths: one test per exception type in the error hierarchy, one per HTTP error status
- Edge cases: empty/null optionals, max values, unicode, concurrent access, timezone boundaries
Edge Case Categories
Test Data Builders
Use the Builder pattern for test data with sensible defaults:
class OrderTestDataBuilder {
private var id: UUID = UUID.randomUUID()
private var status: OrderStatus = OrderStatus.PENDING
private var items: MutableList<OrderItem> = mutableListOf()
fun withStatus(status: OrderStatus) = apply { this.status = status }
fun confirmed() = apply { this.status = OrderStatus.CONFIRMED }
fun withSingleItem(
quantity: Int = 1,
unitPrice: BigDecimal = BigDecimal("9.99")
) = apply {
items.add(OrderItem(quantity = quantity, unitPrice = unitPrice))
}
fun build(): Order = Order(id = id, status = status, items = items)
}
Guidelines
- Every field has a sensible default
- Named factory:
anOrder(), aCustomer(), aProduct()
- Scenario methods:
.confirmed(), .withExpiredPayment()
- Each test creates its own data — avoid shared mutable state
- Use UUIDs, not auto-increment IDs