The road to Hell is paved with untested code.

I watched an interesting YouTube recently:

I get what he’s saying, and I totally disagree.

Testing against “behaviors” while ignoring implementation details (classes and methods) is a great way to leave a significant fraction of your code uncovered.

It also lets you get away with designing crap that’s good for the “behavioral test” but which will break when you want to implement a new “behavior.” This is because your low-level details are being driven by one high-level use case, rather than being made generally useful for many use cases.

Ultimately, what he is telling you to do is write integration tests only. He is telling you specifically not to test classes and methods, especially if the methods are hidden (protected, internal, etc.)

Integration tests are what I did when I started with TDD, and hadn’t yet realized what a total drag it is to skip the unit tests.

Integration tests do not give you good coverage. You can easily have 20-30% of your code not covered at all. What’s hiding in that uncovered percentage? I’ll tell you: The exact same kinds of bugs and design problems you would find anywhere else. These things should be fixed for the same reason you’d fix anything anywhere else in your code.

You’re going to save time by not writing real unit tests! Of course.

You’re going to “ship faster” (like the “duct tape” guy in his examples)! Of course.

It’s going to work okay for awhile! Of course.

And then you’re going to come across some bug you left in the uncovered code. Of course.

And then you’re going to find design problems that make it harder to move forward. Of course.

And then all that time you saved by not writing unit tests, you’re going to have to spend anyway; and on top of that, you’re going to have to spend MORE time to fix all the junk you wrote that depends on the bad design.

Of course.

How many times do you have to go through this cycle before it’s enough?

Published by PDQ

Programming since the '80s.