JUnit
JUnit is a testing framework for Java applications. It was one of the first testing frameworks for Java and it's a widespread use in the community. The framework simplifies the development of unit tests and the current IDE's make even easier building those tests from existing classes and running them. The latest version available in the official website is JUnit 4.5. In this post I won't enter the discussion about TDD or how to build a useful test, I will just show the basics to use JUnit for this purpose. A test case is the basic unit of testing in JUnit and is defined by a class extending junit.framework.TestCase. The TestCase class provides a series of methods that are used over the life cycle of a test. This life cycle consist on 3 steps (setup, test method, tear down) run in sequence for each test method. A test method is defined by any method that fits the following criteria:
- It must be public.
- It must return void.
- The name must begin with “test”.
The test case can have some optional life cycle methods:
- public void setUp(): executed before each test method
- public void tearDown(): executed after each test method
- public void setUpClass(): executed before starting the test case
- public void tearDownClass(): executed after finishing the test case
These methods can be used to load resources needed for the test, like database connections. Inside each test method we have some assertions that tell us if the test was successful or not. If a method finishes with all the assertions succeeding the test method is a success, if one of them fails the test method fails. The list of assertions we can use is:
- assertNull(Object x): Validates that the parameter is null
- assertNotNull(Object x): Validates that the parameter is not null
- assertTrue(boolean x): Validates that the parameter is true
- assertFalse(boolean x): Validates that the parameter is false
- assertEquals(Object x, Object y): Validates that the two objects passed are equal based on the equals(Object obj1, Object obj2) method
- assertSame(Object x, Object y): Validates that the two objects passed are equal based on the == operator
- assertNotSame(Object x, Object y): Validates that the two objects passed are not equal based on the == operator
- fail(): Fail the test.
Following the rules above we can create tests for both JUnit 3 and JUnit 4.5. JUnit 4.5 adds to the mix some annotations that allows us to mark the methods to use in the tests. These annotations are:
- @After: Method will be executed after each test method (similar to the tearDown() method in JUnit 3.x). Multiple methods may be tagged with the @After annotation, however no order is guaranteed.
- @AfterClass: Method will be executed after all of the test methods and tear down methods have been executed within the class. Multiple methods may be tagged with the @AfterClass annotation, however no order is guaranteed.
- @Before: Method will be executed before each test method (similar to the setUp() method in JUnit 3.x). Multiple methods may be tagged with the @Before annotation, however no order is guaranteed.
- @BeforeClass: Executed before any other methods are executed within the class. Multiple methods may be tagged with the @BeforeClass annotation, however no order is guaranteed.
- @Ignore(String): Used to temporarily exclude a test method from test execution. Accepts an optional String reason parameter.
- @Parameters: Indicates a method that will return a Collection of objects that match the parameters for an available constructor in your test. This is used for parameter driven tests.
- @RunWith(Class): Used to tell JUnit the class to use as the test runner. The parameter must implement the interface junit.runner.Runner.
- @SuiteClasses(Class []): Tells JUnit a collection of classes to run. Used with the @RunWith(Suite.class) annotation is used.
- @Test(Class, Timeout): Used to indicate a test method. Same functionality as naming a method public void testXYZ() in JUnit 3.x. The class parameter is used to indicate an exception is expected to be thrown and what the exception is. The timeout parameter specifies in milliseconds how long to allow a single test to run. If the test takes longer than the timeout, it will be considered a failure.
Another benefit of using JUnit 4.5 is that you don't need to extend any class, that way any POJO with the proper annotations can be used as a test unit. One example of a JUnit 4.5 test class using the annotations:
public class FooTestCase { private Foo foo; @Before public void buildFoo() { foo = new Foo(); } @Test public void testGoodResultsBar() { String param1 = "parameter1"; Stringresults = foo.bar(param1); assertNotNull("results was null", results); assertEquals("results was not 'good'", "good", results); } @Test public void testBadResultsBar() { try { String results = foo.bar(null); } catch (NullPointerException npe) { return; } fail(); } @After public void closeFoo() { foo.close(); }}
You can create a Suite to run several tests at once. This is not really necessary with the current IDE plugins, but if you are interested this example code:
@RunWith(Suite.class)@SuiteClasses({FooTest.class, BarTest.class})public class AllTests { public static Test suite() { return new JUnit4TestAdapter(AllTests.class); }}
will run the tests from classes FooTest and BarTest together. Credit of this text to the amazing refcard of Dzone: http://refcardz.dzone.com/refcardz/junit-and-easymock
Extensions
JUnit has a rich ecosystem of extensions to enhance its capabilities. In this section I will mention some of the most interesting ones.
DBUnit is a JUnit extension (also usable with Ant) targeted for database-driven projects that, among other things, puts your database into a known state between test runs. You can find more information in its wiki page and a guide on how to start here.
DOF
The Dependent Object Framework (DOF) enables efficient JUnit testing and Test Driven Development against code that depends on objects that are persisted (e.g., database). You can read an introduction to the framework at the JUnit site.
EJB3Unit
EJB3Unit is a JUnit extension and can execute automated standalone JUnit tests for all EJB 3.0 conform JEE projects. The out of container test approach leads to short build-test-cycles, because no container deployment is necessary anymore. EJb3Unit uses an internal in memory database by default. Alternatively a user defined database can be specified. You can follow these steps to download a sample project on how to use EJB3Unit.
T2 Framework
T2 is a fully automatic, trace-based random testing tool, featuring in-code specifications and reflexive testing. It is also almost interactive; depending on the complexity of your class it can respond in less than a second. T2 checks for internal errors, run time exceptions, method specifications, and class invariant. Unlike other testing tools, they are placed in the class we want to specify. What makes this tool useful is that randomness in testing that helps to detect unexpected errors.