--- name: writing-unit-test description: "Guide for writing a unit test. Use when writing a unit test for functions or components, and when fixing a bug in existing code." --- # Writing Unit Tests ## Philosophy **Core principle**: Tests should verify behavior through public interfaces, not implementation details. Code can change entirely; tests shouldn't. **Good tests** are integration-style: they exercise real code paths through public APIs. They describe _what_ the system does, not _how_ it does it. A good test reads like a specification - "user can checkout with valid cart" tells you exactly what capability exists. These tests survive refactors because they don't care about internal structure. **Bad tests** are coupled to implementation. They mock internal collaborators, test private methods, or verify through external means (like querying a database directly instead of using the interface). The warning sign: your test breaks when you refactor, but behavior hasn't changed. If you rename an internal function and tests fail, those tests were testing implementation, not behavior. ## Rules - One test at a time - Don't anticipate future tests - Keep tests focused on observable behavior - When fixing a bug, write a test for the expected behavior before any code changes > **Important**: For test-driven development, follow the `tdd` skill's guidance instead. ### Before writing any code - [ ] Confirm with user which behaviors to test (prioritize) - [ ] List the behaviors to test (not implementation steps) - [ ] Get user approval on the plan Ask: "What should the public interface look like? Which behaviors are most important to test?" **You can't test everything.** Confirm with the user exactly which behaviors matter most. Focus testing effort on critical paths and complex logic, not every possible edge case.