Keyboard shortcuts

Press ← or β†’ to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Choosing Your Pattern

πŸ—ΊοΈ NAVIGATION | Find the right pattern for your testing problem

This guide helps you choose the right pattern(s) based on your testing situation.


Quick Pattern Finder

What's your challenge? Find it in the table below:

Your ChallengePattern FamilyPattern NameGo To
How do I structure a test?TestingPattern 1: AAA PatternLearn
How do I test error cases?TestingPattern 2: Error Path TestingLearn
How do I test edge cases?TestingPattern 3: Boundary ConditionsLearn
How do I clean up resources?TestingPattern 4: Resource CleanupLearn
Should I use mocks?TestingPattern 5: Real CollaboratorsLearn
How do I organize my code?ArchitecturePattern 6: Generic Base LayerLearn
How do I extend without duplicating?ArchitecturePattern 7: Extension LayerLearn
How do I avoid code duplication?ArchitecturePattern 8: Composition Over DuplicationLearn
How do I avoid data inconsistency?ArchitecturePattern 9: Single Source of TruthLearn
How do I organize large modules?ArchitecturePattern 10: Capability GroupingLearn
How do I optimize for performance?DesignPattern 11: Zero-Cost AbstractionsLearn
How do I prevent type errors?DesignPattern 12: Type Safety with GATsLearn
How do I prevent API misuse?DesignPattern 13: Sealed TraitsLearn
How do I validate at compile-time?DesignPattern 14: Compile-Time ValidationLearn
How do I enforce state machines?DesignPattern 15: Type State EnforcementLearn
How do I manage fixture lifecycle?DesignPattern 16: Fixture Lifecycle ManagementLearn
How do I build test data easily?DesignPattern 17: Builder-Driven Test DataLearn
How do I prevent timeouts?DesignPattern 18: Timeout DefenseLearn
How do I manage feature flags?DesignPattern 19: Feature Gate SlicesLearn
How do I enforce patterns with macros?DesignPattern 20: Macro Pattern EnforcementLearn

By Category

Testing Patterns: "How Do I Write Better Tests?"

These patterns solve fundamental testing problems:

PatternProblemSolution
Pattern 1: AAATests are hard to readStructure: Arrange, Act, Assert
Pattern 2: Error PathsI don't test failuresTest both success and error cases
Pattern 3: BoundariesI miss edge casesSystematically test limits
Pattern 4: Resource CleanupTests leak resourcesAutomatic fixture cleanup
Pattern 5: Real CollaboratorsMocks hide integration bugsTest with real implementations

When to use: All the time. These are foundational.

Learning Path: Testing Patterns Learning Sequence


Architecture Patterns: "How Do I Organize Code?"

These patterns solve structural problems:

PatternProblemSolution
Pattern 6: Generic BaseCode is duplicateExtract generic abstractions
Pattern 7: Extension LayerI can't extend without modifyingAdd layers for extensions
Pattern 8: CompositionDRY violations everywhereCompose instead of duplicating
Pattern 9: Single SourceData gets out of syncOne canonical source of truth
Pattern 10: Capability GroupsModule is too largeOrganize by capability, not type

When to use: During architecture phase and refactoring.

Learning Path: Architecture Patterns Learning Sequence


Design Patterns: "How Do I Make Code Safer?"

These patterns solve design and safety problems:

PatternProblemSolution
Pattern 11: Zero-CostAbstractions are slowZero-cost abstractions via generics
Pattern 12: Type SafetyType errors at runtimeUse GATs for safety
Pattern 13: Sealed TraitsAPI is too easy to misuseSeal traits to prevent misuse
Pattern 14: Compile-TimeErrors caught at runtimeValidate at compile-time
Pattern 15: Type StateState machines are error-proneEncode states in types
Pattern 16: Fixture LifecycleTest setup is complexManage lifecycle with traits
Pattern 17: Builder Test DataBuilding test data is tediousFluent builders for test data
Pattern 18: Timeout DefenseTests hang foreverTimeout defense in depth
Pattern 19: Feature GatesFeature flags are unreliableGate slices across codebase
Pattern 20: Macro EnforcementPatterns are easy to violateUse macros to enforce patterns

When to use: During design and implementation.

Learning Path: Design Patterns Learning Sequence


Decision Trees

"I'm writing a test. Which pattern do I need?"

β”Œβ”€ Start: Writing a test
β”‚
β”œβ”€ What am I testing?
β”‚  β”œβ”€ Normal behavior ──→ Pattern 1: AAA Pattern
β”‚  β”œβ”€ Error behavior ──→ Pattern 2: Error Path Testing
β”‚  β”œβ”€ Edge cases ──→ Pattern 3: Boundary Conditions
β”‚  └─ Setup/teardown ──→ Pattern 4: Resource Cleanup
β”‚
β”œβ”€ What should I test against?
β”‚  β”œβ”€ Mock/fake ──→ Consider Pattern 5: Real Collaborators
β”‚  └─ Real implementation ──→ Pattern 5: Real Collaborators βœ“
β”‚
└─ How do I build test data?
   └─ Complex data ──→ Pattern 17: Builder-Driven Test Data

"I'm designing an architecture. Which patterns apply?"

β”Œβ”€ Start: Designing architecture
β”‚
β”œβ”€ How do I organize modules?
β”‚  β”œβ”€ By type (models, handlers, etc.) ──→ Consider Pattern 10: Capability Groups
β”‚  └─ By capability ──→ Pattern 10: Capability Groups βœ“
β”‚
β”œβ”€ How do I reuse code?
β”‚  β”œβ”€ Copy-paste ──→ NO! Use Pattern 8: Composition Over Duplication
β”‚  └─ Abstract base ──→ Pattern 6: Generic Base Layer
β”‚
β”œβ”€ How do I extend without modifying?
β”‚  └─ Pattern 7: Extension Layer
β”‚
└─ Where is the source of truth?
   └─ Pattern 9: Single Source of Truth

"I'm designing APIs. Which patterns keep them safe?"

β”Œβ”€ Start: Designing public API
β”‚
β”œβ”€ Can downstream code misuse my API?
β”‚  └─ YES ──→ Pattern 13: Sealed Traits
β”‚
β”œβ”€ Should errors be compile-time or runtime?
β”‚  β”œβ”€ Compile-time ──→ Pattern 14: Compile-Time Validation
β”‚  └─ Runtime ──→ Less safe, but sometimes necessary
β”‚
β”œβ”€ Does state machine matter?
β”‚  β”œβ”€ YES (auth states, connection states) ──→ Pattern 15: Type State Enforcement
β”‚  └─ NO ──→ Continue
β”‚
β”œβ”€ Are lifetimes complex?
β”‚  └─ YES ──→ Pattern 12: Type Safety with GATs
β”‚
└─ Should this be in macros?
   └─ Pattern 20: Macro Pattern Enforcement

Learning by Difficulty

Beginner (Start Here)

  1. Pattern 1: AAA Pattern - Foundation
  2. Pattern 2: Error Path Testing - See what not to do
  3. Pattern 3: Boundary Conditions - Edge cases matter
  4. Pattern 4: Resource Cleanup - Don't leak resources
  5. Pattern 5: Real Collaborators - Test with real code

Time: ~3 hours | Content: Testing fundamentals

Intermediate (Build on Basics)

  1. Pattern 6: Generic Base Layer - Code organization
  2. Pattern 8: Composition Over Duplication - DRY principle
  3. Pattern 10: Capability Grouping - Module organization
  4. Pattern 17: Builder-Driven Test Data - Practical testing
  5. Pattern 14: Compile-Time Validation - Type safety

Time: ~4 hours | Content: Architecture and safety

Advanced (Master the Craft)

  1. Pattern 11: Zero-Cost Abstractions - Performance
  2. Pattern 12: Type Safety with GATs - Advanced types
  3. Pattern 15: Type State Enforcement - State machines
  4. Pattern 13: Sealed Traits - API design
  5. Pattern 18: Timeout Defense - Robustness

Time: ~5 hours | Content: Advanced design and optimization


Pattern Combination Guide

"I want to write production-quality tests"

Use these patterns together:

  1. Pattern 1: AAA - Structure your tests
  2. Pattern 2: Error Paths - Test failures
  3. Pattern 3: Boundaries - Test edge cases
  4. Pattern 4: Resource Cleanup - Clean automatically
  5. Pattern 5: Real Collaborators - Use real dependencies
  6. Pattern 17: Builder Test Data - Build complex test data

Expected outcome: Comprehensive, maintainable test suite

"I want to build a safe, extensible API"

Use these patterns together:

  1. Pattern 6: Generic Base - Reusable abstractions
  2. Pattern 7: Extension Layer - Allow extensibility
  3. Pattern 13: Sealed Traits - Prevent misuse
  4. Pattern 14: Compile-Time Validation - Validate early
  5. Pattern 15: Type State - Enforce state machines
  6. Pattern 20: Macro Enforcement - Enforce usage patterns

Expected outcome: Safe, extensible, hard-to-misuse API

"I want maximum performance"

Use these patterns together:

  1. Pattern 11: Zero-Cost Abstractions - Generic dispatch
  2. Pattern 12: Type Safety with GATs - Type-safe lifetimes
  3. Pattern 14: Compile-Time Validation - Zero runtime checks
  4. Pattern 8: Composition Over Duplication - Avoid copies

Expected outcome: Fast code with safety guarantees


FAQ

Q: How many patterns should I learn? A: Start with Testing Patterns (5), then Architecture (5) for production code. Advanced designers learn all 20.

Q: Do I need to learn them in order? A: No, but the beginner patterns are prerequisites for understanding advanced ones.

Q: Can I use just one pattern? A: Yes, but patterns work together. Combine related patterns for best results.

Q: Where do I go from here? A: Choose a Learning Sequence or pick a pattern you need right now.

Q: How do patterns relate to the application guide? A: Application guide shows how to apply patterns in practice. Cookbook explains why patterns exist. Use both together.


Next Steps

Choose your learning path:

Or jump directly to the pattern you need from the Quick Finder above.


Remember: Patterns work together. As you learn each one, you'll recognize them appearing in others. That's the power of a pattern language.