Wednesday, 16 May 2012

Migrating from Junit 3.x to Junit 4.x

Hello and Welcome,
This is my first blog, so thought to start with something I recently did; and it was test framework migration from junit 3.x to junit 4.x.
Junit 4.x has now came up with variety of good features that gives functional or API testers flexibility to write better tests for example; you can put a timeout time for a test case, you can parametrized a test case, etc.
As like other technologies, Junit 4.x is also backward compatible with its previous versions (i.e. junit 3.x). So a code that is written in junit 3.x can anytime be executed on junit 4.x as well. But if you want to use junit 4.x in real sense (and not just a jar that runs 3.x code as well) I would encourage you to migrate your junit 3.x code to junit 4.x and start using features (powers) of junit 4.x.
So, following are the steps which you need to follow while migrating your code from junit 3.x to junit 4.x
1.       Remove all references of junit 3.x jar from the classpath and instead add junit 4.x jar.
As I told junit 4.x is backward compatible with junit 3.x so after adding junit 4.x jar, your code will not throw any compile error and hence you need to be more careful to make sure that you have removed all references of  junit 3.x.
At any point if you find “junit.framework.XXX” references in your test framework code then go ahead and remove it.
2.       Once the junit 4.x jar is added, go to your test base class (a class that is extended by all test suites in your framework). The test base class would be extending junit.framework.TestCase; remove this reference (delete extends TestCase part). If you have individual test suites extending junit.framework.TestCase then remove it from the individual test suites.
The point is junit.framework.TestCase reference should be removed; nothing in your framework should extend this class.
3.       In your test suite if you have a suite method, add @BeforeClass annotation above it. Basically, it is good idea to rename the basic junit 3.x standard methods (like suite(), setup(), teardown(), etc) just to be more sure that nothing is going junit 3.x way; but if you have taken care in removing all junit 3.x imports, then its ok to have the same method names.
4.       If you have a setup() and teardown() methods in your suite and/or test base class, then add @Before and @After annotations to it respectively. Again, you can rename these methods as well or keep them as is it is if you are very sure that all junit 3.x imports are removed.
The important thing here is that you can add @BeforeClass to only one method (per class) but you can add @Before and @After annotations to more than one methods.
5.       All the asserts in your test class/suite should come from class org.junit.Assert. You need to add following statement either to your base class (if you are overriding junit asserts in your base class) or to the individual test class/suite if you don’t have any base class in your framework.
import static org.junit.Assert.*;
6.       Finally, add @Test annotation to all your test cases.

If you want to add more than one suite to your test class, then this can be done using @RunWith and @SuiteClasses annotations.
For example: if you have a code in junit 3.x style similar to the one mentioned below;

Class MyTestPackage
public static Test suite()
TestSuite suite = new TestSuite();
return suite;

then this will be migrated to junit 4.x as

      TestTwo.class })
Class MyTestPackage

In most of the cases the testers migrating to junit 4.x will have lots of test classes/suites that need to be refactored using the above mentioned steps. Sometimes, the count can be in hundreds.
So, if you have few test classes in your framework (may be 10 or 20) you can go ahead and simply apply the above mentioned changes to those. But if there are large numbers of test classes/suites in your framework, it’s better to use a junit 3.x to junit 4.x convertor tool. There are many open source tools that are available on internet that help in automatically migrating from junit 3.x to junit 4.x.

In my next post I'll be coming up with a common feature that many junit testers demand, and that is, continue test execution even when one of the asserts fail in the test case and report the failing asserts in the test execution report. We'll see that this can be achieved with both, junit 3.x as well as junit 4.x.

1 comment: