Test Driven Development (TDD) in LEGO®
Demonstrate the concepts behind TDD. How we write the test before we write code and how that forces our design to emerge.
Everyone works in pairs. One person in the pair will write a test, in the form of a question, on a sticky note and place it on the table. For example "Is there a person?". The other person will then implement something in LEGO that passes that test. They might put down a single brick to represent that person. When the first person is satisfied that the test is passing, they switch positions. Now the second person writes a test and puts it on the table and the first person implements in LEGO.
For the first couple of tests, the facilitator may provide the tests. "Is there a person?", "Is there an animal?", "Is the person larger than the animal?" etc.
Once people understand the flow, we let them make up their own tests to expand on the whole model. This continues until everyone has a collection of tests and their associated implementation.
- There may only be one "broken" test at a time. All previous tests must continue to pass.
- Nothing must be built in LEGO if there wasn't a failing test that forced that to exist.
- The business requirement is to include a person, an animal, a plant, a vehicle and a building.
- After each test is passing, the people switch roles.
What did you observe? How did that feel?
People will often observe that the test had forced their implementation to be a certain way. That it had "driven" their design.
Did everyone complete the five base requirements listed above?
Generally not everyone will have done this. They'll be so busy creating interesting requirements that they don't have time to build the five things that the customer actually asked for. Discuss this.
Are all tests currently passing?
Sometimes people will build something new that breaks an existing test and they either won't have noticed or won't have cared. If this is the case then discuss why tests must always be passing.
Have each pair demo two or three of their features. Have them read out the test first and then point out how that was implemented in their model. Stress the fact that if there isn't a test for a given feature, we don't care about it.
Many times people will have built cool things that they didn't have tests for. We stress again that in TDD, we don't build anything until the test has forced us to do that.
If we have time, we'll now do the "big build" in which each pair will now be forced to integrate with the work from other pairs.
Group people into tables.
If this is being done with a single team then have everyone at the same table. If this is a conference style then each table will work independently.
Each table will pick a project to build. Projects should be something complex that has lots of different kinds of things in it.
- A zoo would be a good project as it has a variety of different kinds of exhibits along with concessions and ticket counters and parkings. Lots of things that all connect and yet are different.
- A traditional apartment building would be a poor project as it's the same on each floor, over and over again
- We normally let the table decide what their project will be, although we do encourage complexity and uniqueness. Examples we've seen include zoo, shopping mall, robot cowboy, and spaceship.
Each pair now builds something using the TDD style from above. Write the test on a sticky note and their partner implements. What's different this time is that the implementation has to be integrated with the main project in the center of the table.
Note that all tests at the table must continue to pass at all times, regardless of which pair wrote them.
- To get maximum effect, we want to let this stage continue for a while. We want to give them enough time to have conflicts between pairs and that might take 10 or 15 minutes to get to that point.
What did you observe?
A wide open question like this will often bring out observations we didn't anticipate.
Look around your table. Are all the tests still passing? If not, discuss.
Often people will now realize that something is broken and they hadn't noticed. This can lead into a discussion of continuous integration servers.
Are there tests that you should have that are missing?
Once a team built a zoo and then didn't complete the fencing around the lion enclosure. Perhaps they'd needed a test to ensure the lions couldn't get out to eat all the other animals.
- Did you have any conflicts where a new feature from one pair broke a test from another? What did you do about that?
- Was your final design different than you expected? Discuss.