At SoCraTes this year, Xavier did a session on Test && Commit || Revert (you can find a talk that covers most of what we talked about here). And I finally read Kent Beck’s TDD By Example a few weeks ago. So I thought I should really do a Learning Hour on TDD, mainly for two reasons: Talk about this weird TCR thingy and get some ideas on how I can get more into test-driven development.
I prepared some quick slides about what Test-Driven Development means, different approaches to it and how the classic TDD approach differs from TCR and from Xavier’s variant of TCR (for this and many more Testing Workflows, see Rachel Carmena’s great diagrams here) and then we started talking.
Some things we talked about that I found interesting and will think about some more:
- yes, test && commit || revert really does mean that you reset to the last thing you committed when your tests are red. It does not mean “go back and fix things”. It means throw everything, including your test, away and start again.
- what is the diagnostic value of different types of tests? Only acceptance tests really tell you something about the feature you are developing. How much do you test in an acceptance test then? Only the Happy Path? Or some errors?
- on the other hand: How quickly do you want feedback from your tests? (running the whole unit testing suite vs. just one acceptance test)
- using code coverage tools as a cue for finding untested code branches you might have missed accidentally instead of as metrics for how thoroughly your whole application is tested
- where to note down edge cases that you think about while coding/testing that you want to test later
- where to start: with an assertion? Sometimes you can use test setups to get into the situation that you want to test/develop and then iteratively develop the right assertions.
- starting with the test title by describing the problem space, not (only) only the solution space (like commit messages and comments)
- starting with the most critical stuff first, the rest will show itself (maybe?)
- the whole “your tests will guide your code / the design will just emerge during the refactoring stage” might be very difficult to understand at first and won’t even work for experienced devs all the time (calm down, you’re not just too dumb to get it!)
- outside-in does not mean you need to test from the UI layer, it does not even mean you need to write an integration test first, maybe just thinking about all the different components from the outside in and then unit-testing them is kind of outside-in alread?
- “the least amount of code to pass the test” does not mean making the least effort possible when writing tests and production code, maybe think more about how to get the maximum amount of feedback with the least effort possible?
I really liked this Learning Hour. Lots of people with different experiences and views on TDD came together to talk about their understandings and the best practices they have gathered so far. I hope we can have many more like this!
Some resources I used while preparing this Learning Hour:
- Kent Beck: Test-Driven Development: By Example
- Kent Beck: test && commit || revert
- Kent Beck: Limbo on the Cheap
- Rachel Carmena: Test-Driven Programming Workflows
- Xavier Detant: Test && Commit || Revert
- Robert C.Martin: The Cycles of TDD
- Ian Cooper: TDD, Where Did It All Go Wrong
- Xavier Pigeon: Du Test First Design au Test-Driven Development
- Juke: Experiences in Outside In Test-Driven Development