keep it clean! (source)

Clean tests, Part 1: Naming

Danny Preussler
AndroidPub
Published in
3 min readJan 5, 2017

--

At Droidcon Berlin 2016 I gave a presentation about ways to write cleaner unit tests.

I’d like to share more details on some of the suggestions made.

Let’s look at a typical unit test. This one is from Toothpick, a lightweight dependency library for Java and Android:

@Test
public void testGetParentScope_shouldReturnRootScope_whenAskedForSingleton() {
//GIVEN
Scope parentScope = Toothpick.openScope(“root”);
Scope childScope = Toothpick.openScopes(“root”, “child”);
//WHEN
Scope scope = childScope.getParentScope(Singleton.class);
//THEN
assertThat(scope, is(parentScope));
}

Fo this snippet my first request is:

Don’t start your test method with “test”!

Why do people do this? For some, it’s the JUnit3 power of habit. That was roughly ten years ago. Back then this was the only way JUnit would find your test methods. Since JUnit4 we have an annotation for doing this: ‘@Test’.
Others might do this to distinguish the test method from other methods in the class. But there shouldn’t be any other public method in a test class! So this is not an explanation (or excuse).

The reason I’m emphasizing on not to start with ‘test’ is simple: it will make the naming of your method much harder. You limit yourself with this fixed prefix.

Speaking of good name:

Don’t put the name of the method you are testing in the test!

In the early days of unit testing we used to have a single test method for every method in the class under test.
So when you would test a method called getParentScope() you would name the test method testGetParentScope().

But soon we figured out that often we need more than one test per method. Especially when following the Clean Code principles where a method does one thing and a Test tests one thing and one thing only.

But should we really keep the method name? Why?

I think it hurts the readability of our test method. It should tell us what it does, what it tests, and not which method it calls while doing this.

In German we say: “Namen sind Schall und Rauch”, names are just sound and smoke. Names are nothing that lasts. So it is with names in our code. We might refactor that name at any time as we are continuously improving our code. But when we do, who remembers to update the test names?

It’s like with JavaDoc for the method: it will be outdated faster than we think.

But the behaviour we want to test lasts. So let’s focus on this in the test name!
So instead of:

testGetParentScope_shouldReturnRootScope_whenAskedForSingleton

Just write:

shouldReturnRootScope_whenAskedForSingleton()

For me this still reads hard, I personally prefer this style:

should_return_root_scope_when_asked_for_singleton()

Doesn’t this look much better? It reads like human language and not like abbreviated Technobabble.

Btw. this is another reason to not abbreviate in your names. It’s all about the names!

Tests are specification

When looking at my suggestion with the underscores, this might look a bit weird to you. Even for me this is not a name that I would have in my normal code base, as I use camel case as most of us do. But tests have slightly different needs. We are defining behaviours here so let’s write them like a document. Our tests are specification. Always remember this.

In addition: if our test breaks where will you see that name first? Good chances it’s in a report page or email notification from your CI system.

With this in mind, a better name would be:

Should return root scope when asked for singleton()

But sadly we can’t name our function like this.
At least not in Java. In other languages this is indeed a valid method name:

// Groovy
def “ Should return root scope when asked for singleton”()
// Kotlin
fun ` Should return root scope when asked for singleton`()

It was a long way from writing unreadable assembler code to this but you can clearly see the future.

Your tests are first class citizen so make sure you find good names. And actually spend even more time as it’s a specification document and must be clear and easy to read.

In the next part we’ll continue here by looking into the actual test code itself. Stay tuned and name tests better!

--

--

Danny Preussler
AndroidPub

Android @ Soundcloud, Google Developer Expert, Goth, Geek, writing about the daily crazy things in developer life with #Android and #Kotlin