is a programming technique that moves unit tests to the front row, making them the primary entry point of production code
- better testability
- cleaner interfaces
- improved developer confidence
- ensures that a system will never contain code that is not executed
- Write a test
- Run tests; watch them fail
- Make the test pass
- Refactor to remove duplication
- A good unit test should be short and focused on a single behavior of a function/method.
- A new test should never duplicate assertions that have already been found to work
- Inputs:
- Direct (passed by arguments)
- Indirect (global scope)
- Outputs:
- Direct (returned by the function)
- Indirect (global scope modified by the function)
- Test must fail at first before writing production code, if they don't then something might be wrong.
- Running the test with an expectation on what is going to happen greatly increases the chance of catching bugs in the tests themselves.
- If there is an obvious solution to a test, we can go ahead and implement it. But we must remember to only add enough code to make the test pass, even when we feel that the greater picture is just as obvious. Don’t fear hard-coding.
- YAGNI: “you ain’t gonna need it,”. We should not add functionality until it is necessary.
- Some good advice when refactoring code is to never perform more than one operation at a time, and make sure that the tests stay green between each operation.
- Once refactoring is completed, and there is no more duplication to remove or improvements to be made to design, we are done. Pick a new task off the to do list and repeat the process.
- When you are done for the day, leave one test failing so you know where to pick up the next day.
Tests need to run fast and they should be easy to run, a tool to automate tests every time a test file is changed.
- Code that Works
- Honors the Single Responsibility Principle
- Forces Conscious Development (think about code before writing it)
- Productivity Boost