Coding Dojo #14: Rock, Scissors, Paper - TDD as if you meant it
We decided to have a second week of following Keith Braithwaite’s 'TDD as if you meant it' exercise which he led at the Software Craftsmanship Conference.
Our attempt a fortnight ago was around implementing a Flash Message interceptor, to hook into the Spring framework but this week was focused more around modeling, the goal being to model a game of Rock, Paper, Scissors.
The code is available on our bitbucket repository.
We used the Randori approach with four people participating for the whole session.
What We Learnt
It was interesting trying to work out what should be the first test that we should write - the instinct for me was to think about about the different objects that we would need to model a game but Halvard suggested it would be simpler to start off with a test where rock should beat scissors. What I also found interesting was that we edited and then ran this test at least 3 times, adding more test setup and then implementation details each time. It felt much more iterative than the normal TDD approach where much more time would be spent up front writing the test before writing the code to make it past.
One thing Nick was helping us to drive was 'safe refactoring' when refactoring various parts of the code. The idea here was to try and drive the refactorings from the IDE without having to do too much of it manually which can lead to mistakes. We also tried to keep the code compiling the whole time while keeping the time that the tests were failing to a minimum. For example we started off with rock as a string and our goal was to get it to be Throw.ROCK as it is on the repository.
We started off by making "rock" a constant.
We then introduced the enums by converting from the strings to enums using Throw.valueOf("rock")
Then the twoPlayerRsp method that took an enum was called from the old one that took a string
Finally we updated the tests to call the enum method directly and removed the old twoPlayerRsp that took the string.
This type of refactoring proved to be a bit harder when trying to refactor the return result of the twoPlayerRsp method since you cannot overload on return types in Java. There was therefore a little bit of time when we couldn’t compile the code while doing this refactoring. It felt quite slow refactoring this way but I think this style of refactoring was new to most people so we would probably get quicker at it from doing it a few times. The fact that we are more certain that we haven’t broken anything while refactoring this way makes it a useful approach from my point of view.
For next time
An idea that Phil and I were discussing was running an open dojo where anyone who wants to come is welcome. At the moment we’ve had it as an internal dojo but if anyone is interested in coming to code with us then let me know by replying to this post or messaging me on twitter. We normally run the dojo on Wednesday nights for a couple of hours in the ThoughtWorks Sydney office.
We’ve used the Randori approach for the majority of our dojos so far and while I think it works really well I’m interested in seeing what other setups we can try. I’ve been reading about the Uber/Ultra Dojo on Hugo Corbucci’s blog so either of those might be something that we try out in one session.
Another quite interesting idea that was suggested to me by Dan North is to make a commit to Mercurial after each pair’s go at the computer so that you have a history of how the code has progressed through the session - I think this would probably be quite interesting to read and maybe more useful than just having the code as it was when the session finished.
About the author
I'm currently working on real-time user-facing analytics with Apache Pinot at StarTree. I publish short 5 minute videos showing how to solve data problems on YouTube @LearnDataWithMark. I previously worked on graph analytics at Neo4j, where I also I co-authored the O'Reilly Graph Algorithms Book with Amy Hodler.