Newsletter sign-up
View all newsletters

Sign up for our Enterprise Java Newsletter

Enterprise Java

Add Zing to your unit tests

Introducing a framework for generic, productive, reliable, and maintenance-free unit tests

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone

Unit testing is as an integral part of extreme programming, and many open source tools and frameworks help developers write unit tests. IDE plug-ins can create skeleton unit test cases, and Ant tasks and Maven goals automatically run test cases and generate reports during continuous integration.

However, unit test cases are not generic. Any functional method handles multiple data scenarios. We write one test method for every data scenario because we create the test data, fire the test, and validate the output in the same test method. If a new requirement adds additional data scenarios for the method, then we end up writing more test methods. Thus, test-case maintenance requires effort. The complexity of tests further increases when testing server-side components against data that changes during transactions. In addition, we must ensure that the tests are always correct. All of these issues require considerable time to address and increase the complexity of the test cases. Overall, we yearn for something that will remove the complications involved in writing test cases and provide a generic set of test cases that are free from maintenance.

This article first outlines a comprehensive list of issues faced during unit testing and then details the creation of a testing framework that facilitates the writing of generic and configurable unit test cases by integrating with multiple open source testing tools and frameworks. In this article, we refer to the JUnit, JUnitPerf, Cactus, JUnitEE, and DbUnit frameworks and tools such as Ant, CruiseControl, and XStream. Please note that this article is not a tutorial for these frameworks and tools.

Issues in unit testing

Here is the summary of the issues that must be addressed while unit testing:

  • The effort required to create/maintain unit tests: We create test data within the test method's body. Thus, to have robust unit testing, we must create different test methods for every possible combination of data for that functional method. Let's call combinations of data data scenarios. We do not generalize data creation and output assertion. Hence, we end up writing test methods for every data scenario that needs testing, which causes maintenance issues. If we change the method to handle more data scenarios, we end up writing more test methods. Also, changing the data for a scenario isn't always straightforward since the test data is embedded in the code and we must change the test-case code and rebuild the entire test suite.
  • Maintaining data consistency: We also need to maintain data consistency for the methods that complete database transactions. For example, if a method creates a customer in the database and we try to create the same customer again, the unit test case will fail.
  • Providing the same approach to writing unit tests but leveraging high-quality tools and frameworks: Some JUnit tools/frameworks available in the open source community enhance unit testing. One such tool is JUnitPerf. It allows basic performance testing of the code. However, it has its own approach to creating test cases and running them. It needs information about the load and response time to create tests. This information is hard-coded in the test methods and the developer ends up writing more unit test cases. Abstracting that information out of the test case so the same unit test case can be run as a load test or response-time test without the developer knowing the intricacies of JUnitPerf would prove beneficial.
  • Complexity of test cases when testing server-side components: When testing server-side components, we need Java Enterprise Edition (JEE) features—e.g., JNDI (Java Naming and Directory Interface) lookup and an EJB (Enterprise JavaBeans) container—which further adds to the complexity of test cases. Tools are available for server-side testing, with the best examples being Cactus and JUnitEE. If we want to leverage the advantages of both, we must glue them together and hide their configuration and intricacies from the developer. We must provide a simple way for the developer to do server-side testing.
  • Encouraging maximum test effectiveness (all the data scenarios are tested): Unit testing is a critical element of continuous integration. During continuous integration, we can use unit testing to measure the build progress. That is, if the unit test reports show a 50-percent success rate, then we should be able to get an idea of the overall build progress. To achieve such evaluation of build progress, the unit tests should be functionally correct and reliable.
  • Correct tracking of the build phase: Most unit test code follows the same pattern. On a higher level, the code looks repetitive. Abstracting such repetitive code from the test cases minimizes the effort required to write unit test cases.


These issues can be resolved by writing a unit test framework that reduces testing effort, by making test cases generic and configurable, and provides seamless integration with excellent open source unit test frameworks. The building blocks of the framework are:

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comments (1)
Login
Forgot your account info?

JUnit Testing with HibernateBy Anonymous on May 15, 2009, 5:06 amA method under test uses Hibernate to query the database. Hence the test case prepares data by inserting them into the table. For eg let us say feature A works...

Reply | Read entire comment

View all comments

Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.