Unit-testing – Is it reasonable to not write unit tests because they tend to get commented out later or because integration tests are more valuable

integration-testsunit testing

I was discussing unit/integration testing with a colleague, and he made an interesting case against writing unit tests. I'm a big unit test (JUnit primarily) proponent, but am interested to hear others' takes, as he made some interesting points.

To sum up his points:

  • When major code changes occur (new set of POJOs, major application
    refactoring, etc.), unit tests tend to be commented out rather than
    reworked.
  • Time is better spent on integration tests covering use cases,
    which make the smaller-scoped tests less/not-at-all important.

Thoughts on this? I'm still pro-unit test (as I consistently see it producing improved code), although integration tests sound at least as valuable.

Best Answer

I tend to side with your friend because all too often, unit tests are testing the wrong things.

Unit tests are not inherently bad. But they often test the implementation details rather than the input/output flow. You end up with completely pointless tests when this happens. My own rule is that a good unit test tells you that you just broke something; a bad unit test merely tells you that you just changed something.

An example off the top of my head is one test that got tucked into WordPress a few years back. The functionality being tested revolved around filters that called one another, and the tests were verifying that callbacks would then get called in the correct order. But instead of (a) running the chain to verify that callbacks get called in the expected order, the tests focused on (b) reading some internal state that arguably shouldn't have been exposed to begin with. Change the internals and (b) turns red; whereas (a) only turns red if changes to the internals break the expected result while doing so. (b) was clearly a pointless test in my view.

If you have a class that exposes a few methods to the outside world, the correct thing to test in my view are the latter methods only. If you test the internal logic as well, you may end up exposing the internal logic to the outside world, using convoluted testing methods, or with a litany of unit tests that invariably break whenever you want to change anything.

With all that said, I'd be surprised if your friend is as critical about unit tests per se as you seem to suggest. Rather I'd gather he's pragmatic. That is, he observed that the unit tests that get written are mostly pointless in practice. Quoting: "unit tests tend to be commented out rather than reworked". To me there's an implicit message in there - if they tend to need reworking it is because they tend to suck. Assuming so, the second proposition follows: developers would waste less time writing code that is harder to get wrong - i.e. integration tests.

As such it's not about one being better or worse. It's just that one is a lot easier to get wrong, and indeed very often wrong in practice.

Related Topic