Effective exercises for teaching TDD
At the Goosgaggle event last month, David Harvey and I ran an open space session on teaching TDD through exercises effectively. My goal with this session was to learn what are the good exercises, what’s common for them, and why they are effective. There were roughly 20 people in the room so we had a good discussion and lots of great ideas. As with any other open space session, it’s hard to remember who suggested what first so I’m sorry about the rest of this post being more or less anonymous, but here are the ideas we discussed:
Early on we started breaking down the exercises designed to teach basic ideas (such as test first and unit testing tool usage) and exercises designed to teach design or technique subtleties. There wasn’t much interest in discussing basic exercises apart from the idea that they should be as simple as possible, so that people don’t get confused by the problem itself. Someone suggested the String Calculator exercise as a good example of this.
As examples of good exercises that teach advanced TDD techniques and subtleties, the group suggested the following:
- Robocode competitions seem to be good in teaching evolutionary design. Using Google, I found a reference to a TDD Robocode workshop from XPDay 2 organised by Paul Simmons and Duncan Pierce with detailed instructions on how to run the exercise.
- TDD as if you meant it, conceived by Keith Braithwaite and ran for the first time during the Software Craftsmanship 09 conference, is a great way to expose design presumptions and make people think hard about actually driving the design by tests.
- I use the Roulette Wheel exercise during my TDD In Practice workshops to make people run into the trap of trying to apply TDD with temporal constraints and random events. There is no write-up of this exercise online yet, but generally the problem is to describe a simple rule such as “the wheel will spin for twenty seconds and the ball will stop on a random number” using unit tests and design the wheel functionality with TDD. Solving the problem is a good way make people think what actually they need to describe in a test, where the context of that particular unit ends, to teach hexagonal architecture principles and using mocks for design.
- Refactoring Golf, an exercise suggested for Software Craftsmanship 2010, teaches refactoring techniques by giving participants the code “before” and “after” and they have to refactor it to get from one shape to another in a disciplined way, using IDE tools as much as possible. While discussing this exercise, someone said that it was particularly effective when done on real project code for in-house workshops. In-house coaches can use this exercise to teach team members why the code they wrote is suboptimal and how to fix it. “Bottling code smells” was mentioned as a really good idea to facilitate this: if a class needs to be refactored, team members should capture a class before the refactoring and use that as a starting point for later exercises.
- Pairing Roulette, where participants frequently switch pairs to work on the same problem over and over, such as in Corey Haines’ code retreat events, is a great way to learn how other people are doing TDD and to see the value of naming conventions and learn different techniques for that.
Analysing further these exercises, we tried to identify as what makes a good TDD exercise. These are the ideas we identified as common for all of them:
- All of them require participants to do something in a very constrained and disciplined way. This helps focus the exercise on a particular thing and make it possible to do a meaningful piece of work with lots of people in a short time. Some further ideas how this could be applied was to impose a constraint that setters or getters cannot be used (for example, to teach Tell Don’t Ask)
- All of them provide relatively instant feedback. Further ideas on how this can be applied to improve other exercises, mostly coming from Jason Gorman’s work on pair-coaching TDD, are to work against checklists, get pairs to asses themselves (Gorman advises still having a principle coach review this to avoid the problem of blind leading blind and also to switch pairs to get more objective assessments) and playing the role of a teacher (which makes participants think harder about something because they have to explain it). Another great idea coming from the Software Craftsmanship 2010 submission process is to record yourself doing an exercise and watch the video - this technique has been used for a long time by public speakers to “step out of the box” and see their flaws more objectively.
- All of them start with a full context that is easy to understand. Simple tasks, more or less already known to the participants, such as the Convay’s game of life, work best because they allow participants to focus on the goal of the workshop and not waste time understanding the problem to be solved. For me, the Tic Tac Toe variant of TDD As If You Meant It worked much better than the original Go version for that same reason. Having a full context is also very important because it allows people to get on with the exercise without spending time setting up external dependencies. This is why the temporal constraints work better for a short exercise than trying to demonstrate mocks and hexagonal architecture by making people run into a problem of using an external context or a database or a queue.
- Longer exercises start out small and allow participants to build up a model
- They all focus on building habits, not giving participants a list of rules to follow in day to day work
See also David Harvey’s post about this session.