Easy 2 Test == Less Reason to Test ?

Some classes are incredibly easy to test:

public class Name {
  private final String first;
  private final String last;

  public Name(String first, String last) {
    this.first = first;
    this.last = last;
  }

  public String getFirst() { return first; }
  public String getLast() { return last; }
}

Should we write unit tests for these simple classes? Kevin “pottymouth” Bourrillion brings this up as well:

If we write tests for these idiotic classes, we’re wasting time; if we don’t write tests for these idiotic classes, we find out later that they’re buggy because, say, we forgot to use a null-safe equality check for a nullable field, or something.

So what do you do? Do you test trivial code?

The Testing Suite Spot

Let’s look at an advanced diagram showing code complexity:

Testing Chart

Some code feels too trivial to test, so we don’t test all of those getters and setters. Other code is awful legacy crap that is damn near impossible to test. The tests become so convoluted, time-consuming, and hacky that we don’t bother.

Random Observations

  • If you wait until code gets really complex before writing that first test, it is generally too late. It is damn hard to retrofit existing code with good tests.
  • Most code starts out pretty simple. You may feel like you are wasting time testing this trivial code, but complexity sneaks up on you.
  • Writing that first stupid trivial test helps ensure you lay a foundation for ongoing testing. Are your build scripts up-to-snuff? Does you continuous integration build run the tests? Do you publish test results? Putting these features in place on day 1 is easy, when the code is “too trivial to test”. Procrastination makes all of these things much harder.
  • Testing as you go helps avoid complexity in the first place. People who never write tests do not grasp this concept.

I believe the last bullet is the most important. Code that is “too hard to test” is often that way because you did not write tests as the code evolved rotted.

Should We Test Trivial Code?

Back to the original question. Should we write tests for trivial code? I don’t see much harm in writing a handful of trivial tests for each class. I see far more harm in writing too few tests. Even if classes never evolve beyond simple POJOs with a few getters and setters, writing trivial tests wastes very little time. If the code happens to grow and require new features, having those first few tests gives you a better starting point.

As a learning exercise, writing tests for trivial classes is the first step towards understanding how to write tests for the really hard stuff. The stuff that really needs testing.


Mario Aquino Says:

The name class above looks like the kind of thing that would be tested as a side effect of testing some other class containing the business rules which necessitate the existence of the Name class. No user story would call for the Name class to be added to the system but rather for something that either retrieves or uses the data that the Name class encapsulates and *that* would be the target of a test. If we always start with failing tests before writing code that adds new capability to an application, it is inevitable that tests we write will cover classes with trivial complexity. Is it Name classes responsibility to check that it’s fields aren’t null? I don’t think so because Name class is neither the originator nor the consumer of the data. If null values could possibly be handed to Name, I would look at how the system allowed that in the first place.

What if the requirement becomes ‘First letters of first name and last name should be capitalized for display if they aren’t stored that way in the system’? Is that Name classes responsibility or the responsibility of the thing that returns a Name to its caller or the responsibility of the callers’ (which displays the values carried by Name instances)? Starting with a failing test that examines those kinds of details will ensure that you cover the implementation of the rules. This way you might not end up with a NameTest that checks the trivial implementation of Name but instead with some other test that accomplishes the same thing.

[...] just read Eric’s beautiful post on unit testing and it struck a chord (well several). He’s right on that testing [...]