3

One of the reasons often given to write unit tests which mock out all dependencies and are thus completely isolated is to ensure that when a bug exists, only the unit tests for that bug will fail. (Obviously, an integration tests may fail as well). That way you can readily determine where the bug is.

But I don't understand why this is a useful property. If my code were undergoing spontaneous failures, I could see why its useful to readily identify the failure point. But if I have a failing test its either because I just wrote the test or because I just modified the code under test. In either case, I already know which unit contains a bug.

What is the useful in ensuring that a test only fails due to bugs in the unit under test? I don't see how it gives me any more precision in identifying the bug than I already had.

1
  • When modifying existing code, the failure might also be in a module that depends on the one you are changing. The location of your last edit is still the most likely culprit for the failure. Commented Aug 23, 2014 at 18:01

2 Answers 2

1

But if I have a failing test its either because I just wrote the test or because I just modified the code under test. In either case, I already know which unit contains a bug.

But, "the code under test" is not only the code of the class/module being tested, but also the code executed by its dependencies.

If I have

public TaxCalculator {
  public Currency getTaxAmount(Currency barePrice) {
     ...
  }

  public Currency getFinalPrize(Currency barePrize) {
     return barePrize.add(getTaxAmount(barePrize));
  }
}

and I test getFinalPrize without mocking getTaxAmount and I get a failure, then all I know is that either there is a failure in getFinalPrize or in getTaxAmount.

Granted, for a situation this simple you would see that getTaxAmount test has also failed and maybe you will automatically link both fails. But if you think of a bug in some class that is widely used, and you suddenly get tens or hundred of test failures, stablishing that relationship would not be that easy.

2
  • How could I suddenly get "tens or hundreds of test failures?" The only way I can see that happening is that I've just modified this widely used class. At that point, I already know which class is broken (I just modified it), and I don't see why I'd have trouble establishing the relationship. Commented Aug 23, 2014 at 23:37
  • Although it may be easier to find the source of a unit test failure than the source of an integration test failure, in practice it's not really that different (in my experience), because the test failure message is not and should not be the main source of diagnostic information; that main source is the exception stack trace you get. And when you make a change that breaks many tests, normally you only need to examine one of those failing tests; fix it, and usually all the other tests will be passing again.
    – Rogério
    Commented Jul 6, 2015 at 21:38
1

Who gives that reason? I consider it to be a weak reason, in fact almost useless. The point of having unit tests is to ensure that no detectable defects are in the code under test. When the test suite fails, you know that there is at least one defect, so you can't publish your code base - it doesn't matter whether exactly one test case fails or more.

Clearly it would be nice to be able to read off from the title of the single failing test exactly what the problem is, but that never happens in practice. It takes an inordinate effort to arrange matters so that every test really does exercise only exactly one bit of code, and no other test does the same, and that effort is almost never worthwhile. It is much more important that every code path is exercised at least once than exactly once. And if a change breaks more than one test case at a time, well usually you investigate one of them and fix the problem, at which point the other failures disappear as well - it's rather like compiler diagnostics in that respect: only the first failure is meaningful, the others may be spurious.

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.