What Are TDD Scaffolding Tests, And Why Do We Need Them?

Olaf Thielke
4 min readNov 7, 2022

--

Photo by Paul Becker on Unsplash

Three rules govern Test-Driven Development (TDD). The first rule asserts, ‘Only write production code to make a failing unit test pass. ‘. Here we have the central tenet of TDD — that we hold off writing behavioural code we have a unit test demanding the behaviour. And this test must be failing. Only then do we make the test pass by creating the appropriate behaviour in the implementation code.

Frequently, it’s fairly straightforward to produce a failing unit test mandating specific behaviour when we already have the class and method definitions in place.

In the example below (written in C# using XUnit), a SalesTaxSelector instance throws an appropriate exception when the test calls its Select() method on a country identifier for which it hasn't got the corresponding SalesTax:

Nice. Yet, the only reason we can run this unit test in the first place is because

  1. We have a SalesTaxSelector class, including a default constructor, and
  2. SalesTaxSelector possesses a public Select() method.

That’s great, but how do we get these?

Scaffolding Tests

Let’s start from the top; the most basic requirement — how do we obtain the SalesTaxSelector class? What possible unit test could we write — and this is the crux — to drive us to defineSalesTaxSelector?

Would this test do it?

Just a minute; that won’t work. The unit test won’t compile; we don’t have a definition for SalesTaxSelector!

Does this failure to compile not encourage us to create the SalesTaxSelector class?

It certainly does.

Therefore, once we write a simple class definition, the failing unit test will pass:

You’ll have noticed we only generate an implementation, an empty class definition for SalesTaxSelector, as specified by Rule 3 of the Three Rules of TDD.

So, to follow the TDD rules, we needed a unit test driving us to implement the SalesTaxSelector definition-a Scaffolding Test.

The construction industry uses prepared scaffolds to shape poured concrete until it is dry. Once the concrete has hardened, workers remove the scaffolding, and the concrete structure will stand firm.

Similarly, we only require scaffolding tests to establish the necessary programming infrastructure — class or methods — afterwards, they are of no further use to us.

OK, we’ve encountered a scaffolding test for a . Let’s use the scaffolding unit test approach to produce the SalesTaxSelector's Select() :

Once again, the unit test confronts us with a compilation error for the unknown Select() method, quickly remedied by implementing a basic version on our SalesTaxSelector:

Again, notice how we represent the Select() method in the simplest terms:

The Select() method's required implementation specifics will result from further unit tests. Scaffolding tests exist to generate class definitions and public methods.

Furthermore, notice how there are no assertions in Scaffolding Tests. We are not testing for concrete behaviour, as we would normally do with unit tests, but here we wish only to produce classes and methods by counteracting compilation errors with class and method implementations.

Is This Necessary?

On the face of it, defining Scaffolding Tests and then making them pass with trivial class and method definitions appears like make-work. Why bother with scaffolding tests when we understand the class or method we want to define?

I hear such objections regarding scaffolding tests all the time. Here is my reason for keeping them:

Avoiding The Slippery Slope

Moving from a strict application of TDD, where we religiously follow The Three Rules and therefore write all implementation code only when we have a breaking test, is fraught with problems. In my experience, new TDD practitioners who abandon scaffolding tests tend to quickly revert to writing too much code without unit tests to the point where they are no longer practising TDD. Applying the Three Rules consistently and trusting the TDD process, rather than seeking shortcuts, is more likely to lead to TDD success.

Conclusion

Unit tests that drive us to create the classes under test and their public methods are called Scaffolding Tests. This particular type of TDD test helps us stay true to the rule that we should not write code unless we have a failing test. Scaffolding tests do not encode expected program behaviour; therefore, we can remove them once they have done their job.

If you enjoyed this article, please leave some claps — and a bunch of claps if you loved it! :) Thank you kindly.

Join my email list to fast-track your software engineering career.

When signing up, you’ll get my guide, ‘The Road to Master Progammer’, containing 3 powerful ideas to help you shorten your journey to expert programmer.

--

--

Olaf Thielke
Olaf Thielke

Written by Olaf Thielke

'The Code Coach'. Software Simplifier & Craftsman

No responses yet