One way to start coding when doing outside-in TDD is with a more or less system wide test that surrounds quite a bit of yet-to-be written code. For your basic web app it might be a test that calls a method in some kind of web controller class and asserts that that call results in a specific value being written to a database from a repository class.
Such test is a good starting point for the production code coding. Start with the method in the web controller class, perhaps notice that it needs a helper object, test drive that object, see the need for a new method in an existing service class, test drive that, and so on … until the initial system wide test finally goes green for the first time.
You then lean back in your chair, take a sip of your now cold coffee and prepare mentally for refactoring the code and tests. Ah! Good times!
So, you take a look at that first test again. Uh … that’s a quite involved set up … And quite many objects that get initialized in just the proper way to force the program flow like you intended … And all of this to check only one of the zillion possible code paths starting from the initial method call? Uhu? That’s no good, that’s not a good test! You panic! (Sorry, got a bit carried away there)
Deep inside you already knew that writing such high level tests is not a viable way to have your code checked for correctness. But on the other hand, it was a good way to get the coding started.
Should the test be deleted then? After all, while writing the code you have written a bunch of lower level tests that check the correctness of each code unit. And even tests that check that those units communicate as intended! But can you really delete a test? Is that even allowed?
Yes, It’s ok to delete it.
A test like the one above is something I would like to call a Scaffolding Test. Its purpose is to act like a scaffolding when you write your code. It is something that helps you to write a piece of production code, and when you’re done doing that … well, you take it away.
- A characteristic of a Scaffolding Test is that its scope is too wide to effectively check the code’s correctness. Or rather, you would have to write too many almost identical tests to cover all code paths.
- It’s not always a deliberate choice to write a scaffolding test. Sometimes you start with what you think is a unit test, covering only just enough yet-to-be-written production code. But then the code you write ends up being much more complex than you imagined, spanning multiple units with many code paths. And there you are.
- A Scaffolding Test can deliberately be written not just as the first system wide test above, but anytime you want a test to drive the coding. All you need is an idea where you want to start (the production code method to call in the test) and where you want to be at the end (what you would like to assert).
- Just like a real scaffolding, you don’t really care if it looks ugly, it’s not there to last anyway. Quite contrary, it would be a waste of time and money to make it look good!
- You don’t want to keep the scaffolding test, but perhaps it can be rewritten to act as a smoke test, or a “test” that merely act as documentation. In those circumstances, you probably should make that intention clear. Maybe use a custom annotation or move the “test” to a package/module/folder separated from “real” tests.
Google Testing Blog: Just Say No to More End-to-End Tests
The Code Whisperer: Integrated Tests Are A Scam