The book is organised into 3 parts. Firstly, Kent takes the reader through an example of using TDD to drive a simple few classes for dealing with money in different currencies, secondly, in a fun bit of meta-ness, he takes the reader through test-driving a unit testing framework from scratch, using the framework he is writing to test itself! The final chapter consists of a large number of patterns for TDD.
The book is written in a very casual, conversational style which makes for easy reading. There are a few times in the book where the author states that he cannot think of something or a better way "at the moment" though I would guess these were more a way of suggesting exercises for the reader than placeholders left over from the editorial process.
Some of the more interesting points I found in the book were:
- Eliminate duplication, including duplication in tests of things in the production code
- First make tests compile with stubs
- When writing a test, invent the interface you would like to have
- First make a test pass, then refactor bit by bit, keeping the test passing until the code is clean
- 2 ways to quickly get to "green" (tests passing) - Return constants and gradually replace with variables until you have real code - use the real implementation straight away
- Value Objects - represent a value, value never changes, operations return new value objects
- Letting a test of 1 function depend on another function working is an educated risk
- TDD cycle:
- Write a test
- Make it compile
- Run it to see that it fails
- Make it run
- Remove duplication (clean code)
- you can entertain a brief interruption but never interrupt an interruption ( use a to do list to stop forgetting things)
- "Sometimes you should just ask the computer" - make a change and run the tests
- Sometimes write tests not to test external functionality but to inform future readers
- After you've finished your todo list, review the code
- 3 A's of tests: Arrange - create objects, Act - invoke methods on them, Assert - check results are as expected
- If a test you write requires lots of changes to be made to pass, write smaller test cases and then reintroduce the big test
- Isolating tests from each other encourages orthogonality in your code
- Write the asserts in a test first and work backwards
- Try to avoid mirrored data, eg 2 / 2 won't notice if arguments are wrong way round
- First tests can be extremely simple but allow to decide where the function belongs and what inputs and outputs it should have step by step
- Leave a broken test case at the end of a session so that you have something to work on next time, which will get you back into the same frame of mind
- Abstract (ie return more than constants) only when you have 2 or more examples (tests)
- If the obvious implementation is really obvious then just use that but fall back to faking and triangulation if you get red bars
- Composite Object - treat collection of objects as if it were a single one of the objects
- Seeing more than one message sent to another object in a method is a smell
- "In TDD the tests are a means to an end - the end being code in which you have great confidence"
- Keep tests that exercise the same path through the code is they convey different information to the reader
- TDD leads to "just-enough" design
A point often made against TDD is that much time is spent writing test code as opposed to production code, and whilst the author believes that it is time well spent, he does also suggest that if you do start using TDD you should measure your productiveness so that you can see for yourself whether it works for you and your organisation.
In summary, the books serves as a very useful introduction to TDD and inspires in the reader the want to try it out. I would have liked to see more patterns about how to write code that is easy to test but that was not within the main aim of the book.
Link to buy the book at Amazon.com