Unit Test Good Practice: One Test Serves Only One Purpose

In this post, I would like to talk about a concrete example of unit test and keep myself to keep the good practice of unit test in mind as the following figure suggests.

Unit Test: Checks a single assumption about the behavior of one system

Unit Test: Checks a single assumption about the behavior of one system

Developers should be familiar with this principle of Unit Test, Let’s take a look at one concrete example here. Consider the following unit test:

@Test(expected=CustomException.class)
public void testException() {
    CustomClass fixture = new CustomClass();
    assertEqual(10, fixture.divdeTwoNumbers(100, 0));
}

The above test is a bad one because, assertEqual() could be confusing, the good practice we should follow is that one test should serve only one purpose, the scope of testing is smaller, the better. That is, a unit test should only involve one functionality of the system, like what is says in the figure: Checks a single assumption about the behavior of one system.

So a better one should be:

@Test(expected=CustomException.class)
public void testException() {
    CustomClass fixture = new CustomClass();
    fixture.divdeTwoNumbers(100, 0);
}

Or equivalently, we should write something like the following:

@Test
public void testException() {
    CustomClass fixture = new CustomClass();
    try {
        fixture.divdeTwoNumbers(100, 0);
        fail();
    } catch (CustomException e) {
       // PASS
    }
}

One might think it is not a big deal because essentially, all of the three tests above are working and serve what we what to test. That is true, but as things go on, the later two, especially that last one makes more sense when we get back to read the test and understand the test.

To summary, for Unit Test, One Test Serves Only One Purpose might have two folds of meaning: 1)  Checks a single assumption about the behavior of one system, this is about the one being tested; 2) The unit test itself has to be of a single testing purpose, if you only test exception, then do not use assertTrue or assertEquals, because they are different and separate testing purposes, and could be confusing.

I posted this article just in order to keep myself to be aware of such details, and if you have any better and other good practices to suggest, feel free to leave comments and I would appreciate it a lot! Thanks in advance!

Written on May 28, 2015