TDD – Comparing Outside In vs Inside Out Approaches

designtddunit testingweb-development

What is the difference between building an application Outside In vs building it Inside Out using TDD?

These are the books I read about TDD and unit testing:
Test Driven Development: By Example
Test-Driven Development: A Practical Guide: A Practical Guide
Real-World Solutions for Developing High-Quality PHP Frameworks and Applications
Test-Driven Development in Microsoft .NET
xUnit Test Patterns: Refactoring Test Code
The Art of Unit Testing: With Examples in .Net
Growing Object-Oriented Software, Guided by Tests—>This one was really hard to understand since JAVA isn't my primary language 🙂

Almost all of them explained TDD basics and unit testing in general, but with little mention of the different ways the application can be constructed.

Another thing I noticed is that most of these books (if not all) ignore the design phase when writing the application. They focus more on writing the test cases quickly and letting the design emerge by itself.

However, I came across a paragraph in xUnit Test Patterns that discussed the ways people approach TDD. There are 2 schools out there Outside In vs Inside Out.

Sadly the book doesn't elaborate more on this point. I wish to know what is the main difference between these 2 cases.
When should I use each one of them?
To a TDD beginner which one is easier to grasp?
What is the drawbacks of each method?
Is there any materials out there that discuss this topic specifically?

Best Answer

Inside-Out and Outside-In are fairly rare terms, more often I have heard/read about Classic school and London school.

  • Inside-Out (Classic school, bottom-up): you begin at component/class level (inside) and add tests to requirements. As the code evolves (due to refactorings), new collaborators, interactions and other components appear. TDD guides the design completely.

  • Outside-In (London school, top-down or "mockist TDD" as Martin Fowler would call it): you know about the interactions and collaborators upfront (especially those at top levels) and start there (top level), mocking necessary dependencies. With every finished component, you move to the previously mocked collaborators and start with TDD again there, creating actual implementations (which, even though used, were not needed before thanks to abstractions). Note that outside-in approach goes well with YAGNI principle.

Neither of the approaches is the one and only; they both have their place depending on what you do. In large, enterprise solutions, where parts of the design come from architects (or exists upfront) one might start with "London style" approach. On the other hand, when you face a situation where you're not certain how your code should look (or how it should fit within other parts of your system), it might be easier to start with some low-end component and let it evolve as more tests, refactorings and requirements are introduced.

Whichever you use, more often than not it is situational.

For further reading, there's Google group post with rather interesting discussion on how this distinction (might have) originated and why London might not be the most appropriate name.

Related Topic