When learning Test Driven Development eventually you’ll discover there are two different schools of thought on what those tests should look like. At that point you probably already have a favourite style (only now you have a name for it) and will go to war against the other style as clearly inferior. Indeed there are lots of blog posts out there on Chicago vs London and I did my tour of duty on that war too. But I’m calling an armistice as there’s no need to fight. We need to do both as both serve specific needs. So even if you have a favourite you need to learn the other approach and think about where it better applies. You can still have a favourite – I have a favourite screwdriver – but you should be comfortable working with either.
Also known as Classical style or Detroit style. This is the style started with the Kent Beck in Extreme Programming Explained that was published in 1999. There are a few traits about this type:
- Rarely uses mocks
- Tends to assert on outcomes rather than interactions
- Tests tend to focus on behaviours rather than function names
Also known as Mockist style. This took off with a presentation at XP 2000 conference by Tim Mackinnon, Steve Freeman, and Philip Craig. And it tries to reduce the scope of what is being test. It’s often tied to a strong concept that a “unit” should be a class or a function. So by definition a “unit test” should not test more than one class and probably not more than one function call.
- Uses mocks to limit tests to just one class
- May assert on interaction with mocks rather than outcomes
- May focus on class function rather than system behaviour
So clearly the key difference in the two styles is the way London style reduces the scope of what is being tested by mocking out other parts of the code. Everything else has to including some careful wording of “tends to” or “may”.
Reading this you probably already have a preference. Maybe because it’s the style you first learned. Maybe because it just “sounds logical” to you and you want to apply what you consider the best approach. But I want everyone to learn both approaches because there will be times when you will get the best results by switching.
When to apply which method
I did some workshops with the software engineers at my work to help learn and discuss when to apply each method and when. I gave them some well tested but poorly refactored code and asked them to do some exercises. However I had two versions of the tests on the code. One version used Chicago style tests and relied a lot on some high level tests that ran through the whole code as well as some low level leaf tests. The other set used mocks to test different levels of the system independently. Here is what they found through the exercises.
When London Style works better
London style tests allowed teams to more easily pick and choose their approach. It was easier to make a high level or low level change without having a wide impact on the passing tests and get back to a passing point quickly. It gave a strong impression of the different parts of code working independently.
In practice I would find London style works well when I’m dealing with 3rd party code or integrating with something I don’t want to change for some reason. It allows me to define a clear seam between be and the other code. It also allows me to build some defensive programming between my code and a source that I may not want to trust completely. It’s also great when I have a very small change I want to implement, perhaps a one-line bug fix, so I want tests already tightly focused on the code.
When Chicago Style works better
The people who did my exercises found that while they could quickly get to a “green” point in London style it could be misleading as the integration of code was still not functional. Having those high level tests that ran all the way through to the leaf level functions gave a high confidence that passing code meant finished code. However it made it difficult to make small changes without it rippling through tests possibly far removed from the change you’re trying to apply.
In practice I find Chicago style gives me higher confidence I have tested my code fully and don’t need any separate integration tests in place. I’m able to quickly and easily make sweeping changes across my code. But I do need to be aware I’m in-effect building a big system where I need to carefully decide where I introduce London style seams so that the next programmer doesn’t find them having to read and adjust dozens of tests due to a small code change.
The best code will use both
When I first learned TDD I was taught to mock only when I needed to. Typically that meant something like touching a database, network or time. This led to me having a strong preference for Chicago style TDD and avoiding mocks much of the time. But I still found it useful to map out a high level control or facade using London style TDD where I had some idea of the interfaces but didn’t have that lower level implementation yet. The London style gave me the flexibility and another way to break up the code but I needed to recognise it came with another cost too.