Although this course is usually run over 2 days codemanship occasionally run the course as a reduced price 1 day intensive format.
I had decided to attend because although I have been trying to do TDD for the past few years I have never had any formal training so wanted to check what I was doing was correct and see what else I could learn about TDD.
Once everybody was set up Jason told us what we could expect from the day starting from the most basic TDD techniques progressing through you use TDD to drive the design to using mocks/stubs and finally applying techniques to work out behaviour required from user stories.
Jason pointed out that when you first start doing TDD you need to be mindful of what you are doing to ensure you are following the practices we would be doing that day as it was easy to slip into bad habits, this will mean you will be slower until you become comfortable with the various practices but you would become faster the more you did them.
TDD Back to the beginning
After the introduction Jason took us right back to basics explaining the red-green-refactor cycle and stressing that the refactor part is just as important as the test to ensure you end up with good code.
Jason then had us pair up to write tests/code around transferring money between two bank accounts, in fact all activities during the day were done as a pair which was great as I also got to practice pairing with different people.
Jason didn’t give us any specific guidance about how we should do this, other than write a failing test, make it pass, refactor – not forgetting to refactor tests as well.
After you had created an object oriented way to handle the transfer Jason got us to go back to just doing it with variables and then refactor that to find and eliminate the duplication, teasing out methods where necessary and giving you insight into
More TDD Basics
After the first exercise Jason talked to us some more about the techniques you use in TDD to help drive the design of the code such as tests only having one reason to fail, always write the assertion first, triangulation, etc.
One thing he stressed was that the idea isn’t to do no design before you code but only do enough design to inform where you start your tests (something we came back to later).
Triangulation was something that really helps with this as Jason explained you want to be driving from a specific solution towards a more general solution, writing meaningful tests which are self explanatory using data that helps tells a story e.g. boundary values.
Another thing that was highlighted out was writing the assertion before you write the code isn’t just to ensure you have a failing test but to make you think about what it is the code needs to do to satisfy that assertion, and the assertion should be related to helping satisfy the requirement(s).
Armed with this new knowledge we tackled our second example of creating a Fibonacci generator.
Yet more TDD Basics
After the second exercise Jason talked to us about refining what we were doing, isolating tests, never refactor with a red test, test organisation, etc.
Another key point here was to pay attention to the requirements so that you didn’t needlessly create tests that you had to throw away later, this tied back to writing the assertion first to make sure you are writing a test that helps satisfy the requirements.
Jason stressed again the need to importance of maintaining the tests, this means refactoring the tests where necessary to try to ensure they are clear, easy to understand and testing what is necessary (circling round to not writing needless tests)
We then tackled are 3rd and final exercise of the morning having to create a FizzBuzz program with with some additional requirements. If we completed the initial work Jason challenged us to rewrite the generator so that it didn’t use any conditional statements when generating the sequence i.e. if, switch or tertiary operations.
The afternoon started with Jason touching on the London & Chicago schools of TDD and how the London school favoured the use of the various types of test doubles to allow testing of interaction between classes.
After discussing the various types of double we jumped into our first example of the afternoon creating a system (in the loosest terms possible) that could tell you if you were able to book a holiday for a specific week of a specific year.
Pulling it together
When we stopped the 4th exercise Jason started talking to us about how we pull all of this together to help design a system.
Users & goals
He talked about determining requirements and how a common way to capture this information was via user stories. What was stressed though is the user story should be seen only as the starting point for a discussion, hopefully with the user, to get more details around/about the functionality needed.
We utilized the Given…When…Then format to get this additional information with each of the then clauses becoming the requirements to be satisfied. Although this helped us gain further understanding about what was required Jason pointed out that they weren’t executable specifications, to understand specifics we needed concrete examples for each then to allow us to create tests that can satisfy them.
Class Responsibility Collaboration Cards
With this additional info could examine the stories to determine the roles, responsibilities & collaborations that we believe we need and to help us visualize the objects we used Class-Responsibility-Collaboration (CRC) cards where we have 1 card per role (object) listing its responsibilities (methods) and other objects it communicates with (collaborations).
This helps to enable a “tell don’t ask” design where you communicate by message passing which also identifies boundaries where you can mock the interactions when you come to writing the tests.
Testing the design
We then did an exercise where in a pair we took a user story, created expanded details and added specifics then Jason took our finished work and handed it to another pair to create the CRC’s for it.
Once everybody had completed the CRC’s Jason took one or two and showed us how we could test the design by running through the Given...when…then and seeing if the objects and interactions would successfully satisfy the criteria.
Jason re-iterated what he had said at the beginning that we needed to ensure we practiced the techniques we had learnt today as if we didn’t practice it was easy to slip into bad habits and asked us all to think about what we could do to practice.
We all then went to the pub to have a drink and discuss the day a bit further.
My thoughts on the day
Firstly I can see why this is billed as an intensive course, we really didn’t stop during the day. Ideally I would have liked a little extra time doing the exercises but in general I liked the pace, it kept you focused on what you needed to do without overloading you.
I really enjoyed the course, it reinforced my existing knowledge, highlighted areas where I have picked up bad habits and I came away having learnt more around triangulation and using CRC cards to test specifications.
Whether you are a complete beginner or have been doing TDD for a while I’d recommend this course, I’m sure you would get a lot out of it.