Feb 27 2009
Thought-provoking TDD exercise at the Software Craftsmanship conference
Yesterday I attended Keith Braithwaite’s workshop titled ”TDD as if you meant it” at the Software Craftsmanship 2009 conference, and I found it truly thought provoking. At the start of the workshop I thought that the exercise is plain silly but I publicly take it back: Keith – you really thought me something yesterday and I thank you for that.
Attendees were split into pairs who were working on the task together, using TDD practices with very strict rules:
- write exactly ONE failing test
- make the test from (1) pass by first writing implementation code IN THE TEST
- create a new implementation method/function by:
- doing extract method on implementation code created as per (2), or
- moving implementation code as per (2) into an existing implementation method
- only ever create new methods IN THE TEST CLASS
- only ever create implementation classes to provide a destination for extracting a method created as per (4).
- populate implementation classes by doing move method from a test class into them
- refactor as required
- go to (1)
The exercise involved writing a piece of code to evaluate whether a stone in the Go game can be taken or not. The definition of whether a stone can be taken was given as it having only one ‘liberty’, with liberties defined as free horizontal or vertical places adjacent to the stone. For example, the white stone in the picture below has two liberties (diagonals don’t count) and it cannot be taken.

The picture above was the first example we had to implement. The rules were designed to strictly let the domain code evolve from the test code in baby steps, which I though was the way I’m doing unit testing anyway, so it did not feel challenging at all. My first attempt started like this:
[Test]
public void StoneHasTwoLibertiesIfTwoCornersAreCovered()
{
GoGrid grid=new GoGrid(3,3);
grid.Place(1,1,Piece.WHITE);
Keith came over and said “Wow! Where did that GoGrid come from?” The rules of the workshop were that we had to let domain code evolve from the test code, and I tried to explain that the class doesn’t yet exist and I’m using the test to drive it’s design, so in my mind I was following the rules of the game but Keith was having none of it, so we had to delete that and start over. As we weren’t allowed to use domain classes, even presumed domain classes, my next attempt was to store it in a char array and then possibly later move that out:
[Test]
public void StoneHasTwoLibertiesIfTwoCornersAreCovered()
{
char grid[][]=new char[][]{
new char[]{' ', ' ', ' '},
new char[]{'B', 'W', ' '},
new char[]{' ', 'B', ' '},
}
int liberties=0;
for (int x=0; x<3; x++)
//
Keith came over again and complained against that. At this point, I was a bit lost. I guess that my pair partner was lost as well. Keith kept asking why we were writing this code, I was explaining that I was describing the example that he gave but again he was not accepting it. Then we came to the point of what exactly we were testing and I said “well the test name says it – if the stone has two corners covered, its liberty is 2”, and Keith asked why haven’t we specified that in the test rather than starting with a grid. So we changed the test to this:
[Test]
public void StoneHasTwoLibertiesIfTwoCornersAreCovered()
{
int cornersCovered=2;
int liberties=4- cornersCovered;
Assert.AreEqual(2,liberties)
}
Finally he seemed happy with this, but to me it looked plain silly. It was not any closer to the end goal and I was just testing subtraction. Encouraging us to stick with it for a while, Keith left to help others and we continued writing other examples. After a couple more similar cases implemented as tests, we were allowed to refactor and move the code to calculate liberties to a new method in the test class. Then we started implementing cases with groups of stones, and things sort of fell into place.
Operations on groups of stones would be a lot more complicated to handle with the grid directly. The exercise was pushing us towards a design that treated groups as a whole rather than individual pieces and not having the grid as a matrix of stones defined at all. Of course the same functionality can be implemented directly on a grid but it would mean much more code and it would be much more complex.
The exercise was very interesting, although I initially thought that it is silly and too simplistic. It showed me how much hidden assumptions can affect my work if I don’t really try to express them and of course I fell into the classic trap of restating the problem and solving the restated problem first. I was thinking about something that I’ll probably need in the future and jumping too much ahead instead of just focusing on the task that I really was supposed to solve.
My counter-argument is that in real projects, not in workshop labs, I would typically have a bigger chunk of requirements and domain explored and we would try out a few designs to see which one fits the problem space best before we started coding, so unit tests will be used to flesh out the APIs but the design ideas would probably be there in some form. Nevertheless, I think that it would be really interesting to try this technique out on a real project as well. According to Keith after the exercise, classes developed like this tend to have very little or no state, very little code and end up with methods with long parameter lists, coming much closer to the functional programming paradigm. The code ends up with lots of small classes.
![]() |
![]() |



Gojko, nice write-up . I’m glad you found the workshop stimulating.
As far as using this technique on a real project goes, I wouldn’t do it all the time but I have learned that when I get into a tricky spot of coding it’s good practice go slower, and slower again; use smaller steps, and smaller again, be more explicit, more concrete and more simple-minded.
It can seem with this technique that you just aren’t getting anywhere. I learned that the peak feeling of frustration that I’m not “getting anything done” comes just before the sudden snap! where all these little bits of code that don’t seem to do any work suddenly turn themselves inside out and beautifully simple design emerges. One has to push past that feeling, put in that last example, and wait for the magic.
Lastly, let me say here what I said at the top of the session yesterday: to quote Allan Watts (badly), I came not as a salesman but as an entertainer. I want you to enjoy these ideas because I enjoy them.
[...] Gojko Adzic » Thought-provoking TDD exercise at the Software Craftsmanship conference. [...]
I guess I’m missing something, but it seems to me the lesson has more to do with the benefits of functional programming than it does with TDD.
“I get into a tricky spot of coding it’s good practice go slower, and slower again; use smaller steps, and smaller again, be more explicit, more concrete and more simple-minded.”
This is how most functional programs are written and how most functional programmers work.
“According to Keith after the exercise, classes developed like this tend to have very little or no state, very little code and end up with methods with long parameter lists, coming much closer to the functional programming paradigm. The code ends up with lots of small classes.”
One thing you’ve made me realize though is that TDD is a lot like programming in a functional language with a repl…just not as good
Bertrand, you have uncovered the hidden agenda!
I’m firmly convinced that sincere TDD leads one towards a functional style. In corporate settings where one can’t sensibly talk about functional programming but can talk about TDD that’s a useful property
Well, I at least don’t see the benefit. You /say/ that code ends up nice & stateless etc but, this post sure doesn’t get you there.
TDD, vapor benefit 4-ever.
[...] Three Paradigms: Taking An Extreme Position on Code Style in a Safe Environment e.g. “remove all setters and getters”, “remove all conditional statements, and then remove them from where you’ve hidden them”. This would have been better if he’d handed out the code examples pre-conf as most people spent the first 15-20 minutes getting the fekker working, but a fun and worthwhile exercise nonetheless. Keith is clearly a man of high standards (“any language with curly braces makes you stupid”) and whilst I admire this I have much bigger issues than “pointless DTO objects” to refactor… TDD As If You Meant It Thankfully this was a little less challenging then the previous session, but a fantastic exercise in TDD discipline. We were given the task of identifying whether a “Go” piece was “captureable” (surrounded on more than 2 sides by opposing pieces) TDD style following rigorous rules. There were some really interesting results and a lot of people really struggled not to try and solve the problem that was in their heads rather than doing the simplest thing possible to get the test to pass. Most people found that being really disciplined resulted in the creation of a lot less objects holding state and instead more functional style. Gojko has done a brilliant write up on his experiences here. [...]
“According to Keith after the exercise, classes developed like this tend to have very little or no state, very little code and end up with methods with long parameter lists, coming much closer to the functional programming paradigm. The code ends up with lots of small classes.”
I can see the benefit of having very little state and small classes but would we not want to avoid having methods with long parameter lists?
Sounds like a cool idea though – we’ve tried something similar in coding dojos here and it’s really hard to keep to those rules and sometimes seems too simplistic.
@mark: I’m not claiming that every consequence of this technique is beneficial in every case.
As it happens long method argument lists can be a way to discover new objects–if we see the same long parameter list in several places. If the contents of those argument lists are hidden way in object fields then this might not be so obvious. Expand to contract.
[...] out Keith Braithwaite’s TDD exercise in one of our dojos, an idea which I came across from reading Gojko Adzic’s blog entry about the Software Craftsmanship Conference held in London last [...]
[...] We decided to follow Keith Braithwaite’s ‘TDD as if you meant it’ exercise which he led at the Software Craftsmanship Conference and which I originally read about on Gojko Adzic’s blog. [...]
I’d be really interested in seeing the evolution of a piece of code like this. Know of any examples I might look at?
Same here, the technique looks fascinating but to grasp it I think one would need to see the evolutionary steps.
For me, the writeup stops be concrete exactly where things get interesting – we see a couple of failed attempts, then an example of where Keith apparently thought they should start, then very high-level, uninstructive description of the subsequent process.
As Andrew noted – it would be interesting to see the rest of the steps, because what’s there doesn’t really give me a feeling of what happened.
[Also, I thought the TDD mantra was to start with a test that fails. The example of the test that Keith liked is a test that doesn't fail. Huh?]
I’m giving this a try, using the bowling game problem, and I’ve run up against an issue I’m not sure how to solve. I created my first three tests (the score after a single roll is the value of that roll, after the second roll when there’s no strike the score is the two added together, after the third roll when there’s no strike or spare the score is the three added together), which provided me with enough duplication to extract a method (getScore()) and a domain object (RollHistory) that I then moved getScore() to… but now I’m not sure how to continue. My next test would naturally be to calculate the score after the third roll when there’s a spare in the first frame, but all the implementation changes would go in the existing method. Is this how this technique is supposed to work?
Jules, try contacting Keith (@keithb_b on Twitter) directly and post that question to him.
See http://gojko.net/2009/08/02/tdd-as-if-you-meant-it-revisited/ for a repeat of this exercise, more information on exercise dynamics and some example code.
I find the idea to be interesting. The procedure is not all that unfamiliar with the way I usually work apart from 2 points (which I think are the main points of this exercise).
That is points no 1 and 4. I can understand the need for point 1 to make the solution evolve from something really simple to a working but still simple solution. I cannot however see the great benefits of point 4. To write the code in the test and then move it. I have not yet tried it myself, so I would not rule out it, but I would like to hear some comments on why it is good/not good.
[...] TDD As If You Meant It: Go – This writeup of an excercise done at the SC 2009 conference demonstrates how to really take small steps. [...]