Automated Unit Testing Frameworks
About the Frameworks Series
Beside the Java language, a world of Java frameworks exists. These frameworks can afford substantial improvements in programmer productivity and enhance the quality, performance, reliability, and interoperability of different Java applications. Fortunately, many of these popular and widely used frameworks are open source projects so anyone can benefit from them if he can invest some time in learning when and how to use such frameworks. This article, the third one in the frameworks series, encourages Java programmers to employ unit tests to get robust code quickly. It also introduces JUnit, an open source Java framework for unit testing any Java code.
Previously Published Articles in This Series
Without unit testing, a programmer will write a low-level class and get it compiled to assume that the code would work properly. At the end of the day, the programmer may end up with a group of related and dependent classes that are all compiled without errors but unfortunately the final program is not working at all or at least the resultant program is not working as planned. To deal with a situation like this, a programmer will spend a lot of time debugging and correcting the code.
During the debugging process, the programmer may detect that many of the assumptions he made about the correctness of some pieces of code were wrong and he may have to review each class and verify that it works properly in isolation of the other code.
Based on this scenario, you have the opportunity to save time and effort if you replace the assumption that each piece of code would work properly with the knowledge that each piece of code is already working properly. This is primarily what unit testing can afford you.
What Is Unit Testing?
A unit test exercises "a unit" of production code in isolation from the full system and checks that the results are as expected. The size of the unit may vary between a class and a package. In the case of Java, a unit usually refers to a single class.
The importance of unit testing had increased with the intervention of extreme programming, a lightweight software methodology proposed to reduce the cost of software development. In this approach, a developer should write unit tests even before writing the actual code.
Whether you will follow a test-driven development approach or not, it's your responsibility, as a developer, to write unit tests to check your own code. Nowadays, unit testing has become an integral part of any professional Java developer toolkit.
Why Should You Use Unit Testing?
Before listing some of the benefits you will gain when applying unit testing to your code, let's explain how you can employ unit testing to maximize your profits.
In Java, you will need to test every Java class you implement. The question is: Which should I write first, the code or the test? The answer is: You could start with implementing your class and getting it compiled before writing the necessary unit tests. However, a better approach, named Test-Code-Simplify cycle, suggests following these steps:
- Write a single test.
- Compile it. It shouldn't compile because you haven't written the implementation code it calls.
- Implement just enough code to get the test to compile.
- Run the test and see it fail.
- Implement just enough code to get the test to pass.
- Run the test and see it pass.
- Refactor for clarity.
By following this approach, unit testing will not only help you to write robust code and decrease your bugs but it also will assist you to improve your design, and reduce the cost and fear of changing working code. Moreover, it will make your development faster and will act as a concise executable documentation of your code.
Automate Your Unit Tests with JUnit
JUnit is the defacto standard for testing any Java code. It was invented in 1999 and many developers have already practiced this very simple and easy-to-learn and use framework. JUnit relies on a number of classes and interfaces that will be summarized in the next sections.
The abstract class, TestCase, is the central class in the JUnit framework. A test case composes a group of tests that share the same fixture. Fixtures are implemented in test cases and are used to set up and tear down objects that are common to the tests in the test case.
The JUnit Assert class provides a group of methods for asserting that some condition is true. The following is a list of the most used Assert class methods.
- assertEquals ([String message], expected, actual)
- assertSame ([String message], expected, actual)
- assertTrue ([String message], boolean condition)
- fail ([String message])
The optional message parameter is a message to be reported in case of a failure. The two parameters, expected and actual, represent the value you want to see and the actual value produced by the code under test. The type of these two parameters could be any primitive data type (for example, int, float, double, and so forth) or Object.
Test suites are collections of tests. Dynamically, each test case has a test suite composed of all the tests implemented within this test case. However, you may statically customize the test suite. For example, you can force a specific order of tests, remove some tests, or add tests from other test cases.