· coding-dojo

Coding Dojo #13: TDD as if you meant it

We decided to follow Keith Braithwaite’s 'http://www.parlezuml.com/softwarecraftsmanship/sessions/tdd_as_if_you_meant_it.htm[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.

We worked on implementing a Flash Message interceptor, to hook into the Spring framework, that one of my colleague’s has been working on - the idea is to show a flash method to the user, that message being stored in the session on a Post and then removed on a Get in the 'http://en.wikipedia.org/wiki/Post/Redirect/Get[Post-Redirect-Get]' cycle. It’s similar to the ':flash' messages that get passed around in Rails.

The Format

We used the Randori approach with five people participating for the whole session.

What We Learnt

  • We were following these rules for coding :

    1. write exactly ONE failing test

    2. make the test from (1) pass by first writing implementation code IN THE TEST

    3. create a new implementation method/function by:

      1. doing extract method on implementation code created as per (2), or

      2. 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)

          </ol> Despite having read about Gojko’s experiences of this exercise I still found it amazingly frustrating early on taking such small steps and the others pointed out a couple of times that the steps we were taking were too big. The most difficult thing for me was the idea of writing the implementation in the test and working out what counts as implementation code and what counts as test setup. The line seemed to be a little bit blurred at times.

    4. We worked out after writing 5 or 6 tests that we had overcomplicated things - we originally started out using a map to represent the session and then called the get and put methods on that to represent putting the flash message into and taking it out from the session. We decided to redo these tests so that the flash message was just represented as a string which we manipulated. This second approach guided us towards the idea of having a FlashMessageStore object with a much simpler API than a Map.

    5. We started off only extracting methods when there was duplication in our tests which forced us to do so. As a result of doing this I think we ended up having the implementation details in the test for longer than the exercise intended. We didn’t introduce a class to hold our methods for quite a while either - the idea we were following was that we wouldn’t create a class unless we had three methods to put on it. Once we got the hang of the exercise we started creating those methods and classes much earlier.

    6. Dave pointed out an interesting way of writing guard blocks which I hadn’t seen before - the idea is that if you want to exit from a method it’s fine not to have the {} on the if statement as long as you keep the whole statement on one line. Roughly something like this: ~java public void clearFlashMessageIfRequestTypeIsGet(Request request) { if(!"get".equalsIgnoreCase(request.GetType()) return; // do other stuff } ~

    7. It seemed like following these rules guided us towards tiny/micro types in our code and the methods we extracted were really small compared to the ones we would have written if we’d started off writing the test and implementation separately.

    8. We had an interesting discussion towards the end of the dojo about the merits of wrapping framework libraries with our own types. For example we might choose to wrap the HttpServletRequest in our own Request object so that we can control the API in our code. Although I think this might initially be a bit confusing to people who expect to see a certain set of methods available when they see they are using a Request object, this approach seems to be following Steve McConnell’s advice in Code Complete of 'coding into a language' rather than in a language - we are moulding the framework to our system’s needs.

      == For next time * I really enjoy the dojos where we experiment with an approach which is slightly different than what you do on projects. Although the language (Java) was familiar to everyone it was still challenging to code a very different way than what we’re used to. We’ll probably try this exercise again the next time with another problem.

  • LinkedIn
  • Tumblr
  • Reddit
  • Google+
  • Pinterest
  • Pocket