Finding good names is one of the challenges of crafting software. And you need to find them all the time and for everything – classes, methods, variables, just to name a few. But what makes a name a good name? To quote Uncle Bob: ‘Three things: Readability, readability, and readability!’ Which he defines later one by clarity, simplicity, and density of expression .

Though this makes sense to me, I watch myself struggling in particular with test method naming a bit. To better understand of what I am talking about, one needs to know that I write my code test driven. And doing this for a while I changed my focus of work gradually from the unit under test more to the test itself. This is probably because I like to think of a test case as a living specification and quality assurance in one piece and hence that it is vitally important .

So whenever a test breaks, ideally I would be able to recognize at a glance what specification was broken and why. And the best way to achieve this seems to be by finding an expressive test name, because this is the first information displayed in the reporting view:

Seen from this angle I am not always happy with what shows up in this view and so I spent a bit of time on research to see what school of thought might be helpful. Unfortunately, most of the results I found were somewhat dated and – less surprising – the opinions on this topic are divided. This post represents my reflections based on those findings and a bit of personal experience.

Testing with JUnit Testing with JUnit is one of the most valuable skills a Java developer can learn. No matter what your specific background, whether you’re simply interested in building up a safety net to reduce regressions of your desktop application or in improving your server-side reliability based on robust and reusable components, unit testing is the way to go. Frank has written a book that gives a profound entry point in the essentials of testing with JUnit and prepares you for test-related daily work challenges. Get It Now!

Tests per Method or Behavior Related JUnit Test Names?

In its pure form, the tests per method approach is often provided by tools that e.g. generate a single test stub after the fact. In case you have a class Foo with the method bar the generated method would be called testBar . I was always skeptical about the usefulness of such a development style or naming convention and would have argued like this quote from an old JavaRanch thread: ‘you shouldn’t think about it as testing methods at all, you should think about it as testing behavior of the class. Consequently, I like my test method names to communicate the expected behavior’ .

Interestingly enough I am about to change my opinion a bit on that one. The idea of communicating the ‘behavior’ as stated above requires finding a concise name that expresses this ‘behavior’ comprehensively. But then the term behavior implies a transition from one state to another conducted by an action or denoted in BDD terms, for example, a Given-When-Then pattern. Honestly, I do not think that it is, in general, a good idea to put all this information in a single name :

@Test public void givenIsVisibleAndEnabledWhenClickThenListenerIsNotified() {} @Test public void givenIsVisibleAndNotEnabledWhenClickThenListenerIsNotNotified() {} @Test public void givenIsNotVisibleAndEnabledWhenClickThenListenerIsNotNotified() {}

Maybe its just a question of taste but from my experience, this approach often lacks readability due to the absence of simplicity and/or clarity no matter what kind of format style I chose. Furthermore, such overloaded names tend to have the same problem as comments – the names get easily out of date as the content evolves . Because of this, I would rather like to go with the BUILD-OPERATE-CHECK pattern instead. This would allow to split up the phases into separate sub-method names placed within a single test:

@Test public void testNameHasStillToBeFound() { // do what is needed to match precondition givenIsVisibleAndEnabled(); // execute the transition whenClick(); // verify the expected outcome thenListenerIsNotified(); }

Unfortunately, this leads us to where we started. But if you take a closer look at the examples above, all the methods group around a common denominator. They all belong to the same action that fires the transition. In our case the click event. Considering that from the development process point of view I regard a test case more important than the unit under test, one could interpret this as a sign to reflect the action by an appropriate method name in the unit under development .

So for the sake of example assume we have a ClickAction that wraps around a UI control. And introducing a method called ClickAction#execute() might seem appropriate to us, given the situation above. As simplicity matters we could use that name also for the test method that represents the transition from the default state of the ClickAction – control construct via ClickAction#execute() :

class ClickActionTest { @Test public void execute() { Control control = mock( Control.class ); ClickAction clickAction = new ClickAction( control ); clickAction.execute(); verify( control ).notifyListeners(...) } }

To keep things simple the next test name may mention only the state information that is important as it differs from the default and leads to another outcome:

class ClickActionTest { [...] @Test public void executeOnDisabledControl() { Control control = mock( Control.class ); when( control.isEnabled() ).thenReturn( false ); ClickAction clickAction = new ClickAction( control ); clickAction.execute(); verify( control, never() ).notifyListeners(...) } @Test public void executeOnInvisibleControl() { [...] }

As you can see, this approach results in a set of test names that technically spoken represents a variety of the ‘tests per method’ pattern – but not for completely bad reasons as I think. Given the context I consider this naming pattern is simple, clear and expressive up to one point:

The expected test outcome is still not mentioned at all. On first glance, this looks unsatisfactory, but from my current point of view, I am willing to accept this as a sound trade-off. Especially as the cause for a failing test is usually also shown in the JUnit reporting view. Because of this, that problem can be handled by providing meaningful test failures .

Update 2015/10/01: During the work on my book Update 2015/10/01: During the work on my book Testing with JUnit I refined and elaborated my thoughts on this topic a bit. Now, I determine behavior precisely as the outcome of a component’s functionality applied under given circumstances or preconditions. This matches self-evidently the Structure of a Well Written Test (setup the preconditions, execute the functionality, and verify the outcome), since we intend to test behavior. Given these terms, an expressive and unique test name can be derived from its functionality and the given preconditions, which exactly leads to the naming pattern I’ve described with the last listing.

Conclusion

Actually, I am using the test naming pattern described above for some time now. So far it works out not too bad. In particular, when working with pretty small units as I usually do, there is little room for misinterpretation. However, this approach does not match all cases and sometimes it simply feels better and is still readable enough to mention the outcome. I will not be harping on about principles here and maybe I am getting it all wrong. So I would be happy for any pointers to more elaborated approaches that you might be aware of to broaden my point of view.