1---2name: testing3description: BDD-style test writing rules including unit testing patterns, integration testing with Testcontainers, contract testing for microservices (Pact, Spring Cloud Contract), E2E testing (Playwright, Cypress, visual regression), and performance testing strategies (k6, Gatling). Use when writing or modifying test code.4license: MIT5---6# BDD-Style Unit Test Rules78## 1. BDD Style Required910- Always use BDD style (Describe - Context - It)11- Use English naming for test blocks with Korean descriptions1213## 2. Naming Conventions1415| Block | Pattern | Example |16| --- | --- | --- |17| `describe` (class) | `{ClassName} 클래스의` | `AuthFacade 클래스의` |18| `describe` (method) | `{methodName}() 메서드는` | `login() 메서드는` |19| `context` | `~하면`, `~이면` | `유효한 토큰이 주어지면` |20| `it` | `~한다`, `~반환한다` | `사용자 정보를 반환한다` |2122---2324## 3. Qualities of a Good Unit Test2526Every test must satisfy all five criteria:2728- **Accurate damage detection**: Tests MUST fail when code is broken. A passing test must provide confidence that the code works correctly29- **Implementation-independent**: Tests MUST still pass after refactoring internals. Test the public API behavior, not implementation details30- **Well-explained failure**: Failure messages alone must be sufficient to identify the problem31- **Readable test code**: Tests serve as documentation. Other developers must understand the intent immediately32- **Fast execution**: Unit tests must complete quickly since they are run frequently3334---3536## 4. Test Behaviors, Not Functions3738- ❌ Do NOT mechanically create one test case per function39- ✅ Write separate test cases for each behavior a function performs40- A single function may exhibit different behaviors under different conditions — test each behavior individually41- NEVER skip error scenarios — test invalid inputs, boundary values, and exception cases alongside happy paths4243---4445## 5. Test One Behavior at a Time4647- Testing multiple behaviors in a single test case makes failure diagnosis difficult48- ❌ Bundling multiple behaviors into one test49- ✅ Each test case verifies exactly one behavior independently50- Test case names must clearly describe the specific behavior being verified5152---5354## 6. Test Through Public APIs5556- NEVER change private functions to public just for testing57- Test private function behavior indirectly through the public API58- Directly testing private functions couples tests to implementation — refactoring breaks tests even when behavior is unchanged59- If code is too complex to test through its public API, consider splitting it into smaller units6061---6263## 7. Test Double Guidelines6465### Mock and Stub6667- Mocks and stubs simplify tests by replacing real dependencies, but risk coupling to implementation details68- Tests using mocks/stubs may break during refactoring even when behavior is unchanged6970### Fake7172- Fakes are simplified implementations of real dependencies, providing more realistic tests than mocks/stubs73- Fakes decouple tests from implementation details74- Trade-off: fakes require their own maintenance7576### Selection Criteria7778| Situation | Recommended |79| --- | --- |80| Isolating from external systems (DB, API) | Fake or mock |81| Only need to control return values | Stub |82| Need to verify call count/args/order | Mock |83| Real dependency is lightweight and side-effect-free | Use the real dependency |8485---8687## 8. Shared Fixture Usage8889- **State sharing (BeforeAll)**: Runs once before all test cases. Suitable for expensive dependencies, but shared mutable state between test cases can cause problems90- **Config sharing (BeforeEach)**: Runs before each test case. Guarantees isolation between test cases91- Mutable state MUST be reset via BeforeEach — sharing mutable state between test cases causes flaky tests92- Important setup values must be visible within each test case — hiding them in shared fixtures obscures test intent93- Shared constants are acceptable, but critical input values must be explicit in each test case9495---9697## 9. Use Appropriate Assertion Matchers9899- Failure messages alone must be sufficient to diagnose the issue100- ❌ Poor assertion: failure shows only `Expected: true, But was: false` — no context101- ✅ Good assertion: failure clearly shows the difference between expected and actual values102- For collection assertions where order doesn't matter, use flexible matchers like `containsExactlyInAnyOrder`103- Leverage framework-provided matchers (e.g., AssertJ `containsAtLeast`, Jasmine `arrayContaining`)104105---106107## 10. Use Dependency Injection for Testability108109- Hard-coded dependencies can make testing impossible110- Constructor injection allows replacing dependencies with fakes or mocks during tests111- Dependency injection improves not only testability but also modularity and flexibility112- Combine static factory methods with constructor injection to maintain both production convenience and testability113114## 11. Anti-Patterns115116- **Deploying Without Tests**: Deploying to production without test coverage is risky. At minimum, test core business logic117- **Testing Implementation Details**: Tests coupled to internal implementation break on refactoring. Write behavior-based tests118- **Inter-test Dependencies**: Tests that depend on execution order create unstable test suites. Each test must be independent119- **Excessive Mocking**: Mocking all dependencies diverges from real behavior. Supplement with integration tests120- **Magic Numbers**: Using meaningless numbers/strings in test data. Use intention-revealing constants or factories121- **Ignoring Flaky Tests**: Tolerating intermittently failing tests erodes overall test suite reliability. Fix or quarantine immediately122123## Additional References124125- For integration testing patterns, see [references/integration.md](references/integration.md)126- For contract testing patterns, see [references/contract.md](references/contract.md)127- For performance testing strategies, see [references/performance.md](references/performance.md)128- For E2E testing patterns (Playwright, Cypress, visual regression), see [references/e2e.md](references/e2e.md)129130## Related Skills131132- For load testing with k6 and Gatling, see `load-testing` skill