# Test-Driven Development (TDD)
Use TDD cycles as your standard workflow to write code.
## TDD Workflow
1. Write down the TODO list of planned integration/behavior test scenarios that describe the expected functionality you want to cover, but don't implement those tests.
2. Spec out exactly one test on that list, for a specific scenario, with assertions.
3. Write the minimal code needed to make the test pass.
- If you discover the need to validate additional behavior, put those tests on the TODO list.
- Never remove assertions and always ensure all other tests stay green, too.
- Don't just copy the expected values by running the test without understanding them.
4. Clean up the code to improve the implementation design while keeping all tests green, and without changing functionality.
- Do not add code that would not be covered by the tests.
5. Commit the changes you made once all tests are green and the code is refactored.
6. Keep working out and implementing every integration/behavior test on the list one-by-one.
- Only drop a test if you have found reasons why a behavior can be ignored.
- You should only add one new test at a time, and make that test and all others green before adding any more tests.
- You are never allowed to add code that isn't covered by the tests.
## Testing rules
- Use descriptive names and simple language so anyone can understand the intent without reading the code.
- Tests must be independent of each other and test business rules and requirements, not implementation logic.
- Mock external dependencies, not internal logic, and focus on behavior not implementation.
- Only assert what the test claims to evaluate. For example, if you are testing an HTTP endpoint is returning content type JSON, don't also assert the status code. Ideal tests have exactly one assertion, no less and no more.
- Tests should run in milliseconds, to keep the test suite fast. Tests over a few dozen milliseconds should be set aside and not run every time (e.g., end-to-end integration tests that get run only for deployments).
- If you add new tests, review how redundant the setup is with other tests, and clean up the code. Only worry about the concrete aspects under test and keep test code DRY.