Wednesday, August 24, 2011

Organizing unit tests

I have been using a different approach to organizing the unit tests and this have turned out to be very effective. Worth sharing.

So if we have a class that looks like:
public class AccountService {
  public void getAllAccounts() { ... }
  public void createAccount() { ... }
  public void removeAccount() { ... }
}

For such a class we would traditionally have a unit test class called AccountServiceTest and all the test cases for all methods mentioned above. We would also have a bunch of global variables in the Test class and a setup (@Before) method.

My different approach involves creating a unit test class for each method rather than just one test class. So now we would have three classes:
public class AccountService_getAllAccounts_Test {}
public class AccountService_createAccount_Test {}
public class AccountService_removeAccount_Test {}

Generalizing it the unit test class name should be:
<<class under test>>_<<method under test>>_Test.java

Each class would have test cases for only the method referenced in the file name.

So how is this approach effective?

SRP - Single Responsibility Principle - is restored
In the traditional way the SRP principle is violated with the setup method as it is now common to all the test cases for all methods for the class under test. The setup has responsibilities to setup the objects and data for all the test methods for all methods in a class. Even the Test class has multiple responsibilities to test all methods in there. With the new approach every test class has responsibility to test only one single method under test.

"Look and Feel" of unit test cases
This is more of a perception thing but it works. Say if every method under test can have 5 unit test cases, in the above example having a single test case class means we already have 15 methods in there. When a developer looks at a single class with that had large number of methods with a single setup method that looked cryptic and they were less likely to update any unit test cases or even add more tests to them. When the classes were separated the "look and feel" of the test cases improved developers are now willing to and able to extend existing code base by adding new test cases.

What are the side effects of this approach?
  • Popular plugins like moreunit do not work anymore
  • Proliferation of Test classes may be something some developers may not like at first.

Let me know what you think !!!