Implementing Testing Strategies
1. Designing Unit Tests
Example: JUnit 5 + AssertJ
@Test
void placesOrderWithCorrectTotal() {
var cart = Cart.of(Item.of("sku1", 2, money(10_00)));
var order = service.place(cart);
assertThat(order.total()).isEqualTo(money(20_00));
assertThat(order.status()).isEqualTo(PLACED);
}
2. Implementing Integration Tests
| Tool | Detail |
|---|---|
| @SpringBootTest | Full context |
| Testcontainers | Real Postgres/Kafka in Docker |
| @DataJpaTest | JPA slice; in-memory or Testcontainers |
| @WebMvcTest | Controller slice |
3. Implementing End-to-End Tests
| Tool | Use |
|---|---|
| Playwright / Cypress | Browser flows |
| REST Assured / Karate | API E2E |
| k6 / Gatling | Performance E2E |
| Run against staging | Closest to prod |
4. Implementing Mock Objects
Example: Mockito
@ExtendWith(MockitoExtension.class)
class OrderServiceTest {
@Mock InventoryClient inventory;
@InjectMocks OrderService service;
@Test void reservesInventory() {
when(inventory.reserve("sku1", 2)).thenReturn(reservation("r1"));
service.place(Cart.of(Item.of("sku1", 2, money(100))));
verify(inventory).reserve("sku1", 2);
}
}
5. Implementing Test Doubles
| Type | Use |
|---|---|
| Dummy | Filler args, not used |
| Stub | Returns canned values |
| Spy | Real + records calls |
| Mock | Verifies interactions |
| Fake | Working impl, simpler (in-memory repo) |
6. Implementing Test Data Builders
Example: Builder for tests
public class OrderTestBuilder {
private UUID id = UUID.randomUUID();
private List<Item> items = List.of(Item.of("sku1", 1, money(10_00)));
public static OrderTestBuilder anOrder() { return new OrderTestBuilder(); }
public OrderTestBuilder withItems(Item... it) { this.items = List.of(it); return this; }
public Order build() { return new Order(id, items); }
}
// Usage: anOrder().withItems(item("sku2", 5)).build();
7. Implementing Database Test Strategies
| Approach | Detail |
|---|---|
| Testcontainers Postgres | Real DB, isolated per test class |
| @Sql / Flyway | Seed data deterministically |
| @Transactional rollback | Auto-cleanup |
| Truncate between tests | For non-transactional tests |
8. Implementing Performance Tests
| Type | Goal |
|---|---|
| Load | Sustained expected traffic |
| Stress | Find breaking point |
| Spike | Sudden traffic surge |
| Soak | Long-running for leaks |
| Tools | k6, Gatling, JMeter |
9. Implementing Security Tests
| Type | Tool |
|---|---|
| SAST | SonarQube, Snyk Code |
| DAST | OWASP ZAP, Burp |
| SCA | OWASP Dependency-Check, Snyk, Dependabot |
| Secrets scan | gitleaks, trufflehog |
| Pen test | Periodic third-party |
10. Implementing Contract Tests
| Tool | Detail |
|---|---|
| Pact | Consumer-driven contracts |
| Spring Cloud Contract | Producer publishes contracts |
| OpenAPI diff | Detect breaking changes |
| Schema registry | Avro/Protobuf compat checks |
11. Implementing Test Coverage Goals
| Pyramid Level | Share |
|---|---|
| Unit | ~70% of tests; fast |
| Integration | ~20% |
| E2E | ~10%; slowest |
/\
/E2E\ few, slow, brittle
/------\
/ Integ \ some, medium speed
/----------\
/ Unit \ many, fast, isolated
/--------------\
12. Implementing Test Automation in CI/CD
| Stage | Run |
|---|---|
| Pre-commit | Lint, format, fast unit subset |
| PR build | Unit + integration + SAST |
| Merge to main | Full suite + contract tests |
| Pre-deploy | Smoke tests |
| Post-deploy | Synthetic monitors, canary checks |
| Nightly | Performance, soak, full E2E |