This page describes steps taken to provide support for running JUnit4-style tests within the Eclipse Test Framework (ETF). Included is a brief description of why each of the main changes was made. More information about the development process can be found in the bug report. Some changes are required on the part of the user to run tests which require JUnit 4.x. As for JUnit 3.x tests, the Framework is fully backwards compatible.
For the duration of this page, tests that use any of the new features provided by JUnit 4.x (annotations, static imports, etc.) will be referred to as "JUnit4 tests". Tests that do not use JUnit 4's features will be referred to as "JUnit3 tests".
Test framework changes
JUnit4 Bundle Rename
Because we wanted to retain backwards compatibility of the Framework, having the org.eclipse.test bundle depend on org.junit4 simply wasn't an option. This would mean that users running with a JVM <1.5 would not be able to resolve the org.eclipse.test bundle. So it was decided that by renaming the JUnit4 bundle to "org.junit" (same as the JUnit3 bundle name), the EclipseTestRunner (ETR) could just run with the highest version of org.junit that gets resolved.
org.junit4 is now "empty", and simply re-exports the packages exported by the org.junit version 4.x bundle.
JUnit Bundle Configuration
With the JUnit 3 and 4 bundles both named org.junit, we run into a problem of backwards compatibility. Let's say that our user would like to run his/her tests that depend on org.junit and specify a version less than 4.0.0. This user has also decided to run with a Java 1.5 VM. So now the ETR will attempt to run JUnit 3 tests with the org.junit version 4.x bundle resolved. This shouldn't be a problem as JUnit4 is backwards compatible, except that the user's bundle requires JUnit <4. So we run into an issue of org.junit packages being equal but not identical; ETR is using junit.framework version 4.x but the user's bundle is bound to junit.framework version 3.x. We are still working on a solution to this problem but the result will be that all bundles in the system should resolve against the older version of JUnit... there should be no mixed-version resolution.
Changes required by test bundles
Some test bundles will run just fine with either Junit3 or Junit4. However in some cases tests have created dependencies on one version of JUnit or another (either deliberately or not). Here are some of the kinds of changes that tests currently running on JUnit3 may have to make in order to run on JUnit4.
Some test bundles express a narrow version range on Junit 3.x, such as "[3.8.0,4.0.0)". Such test bundles won't resolve against JUnit4, and hence require updating the version range. Since JUnit is not an eclipse.org project and doesn't necessarily follow our version evolution semantics, the safest approach is to only specify the lower bound dependency. If you still want to be able to run with JUnit3, use a range of "3.8.0". If you only want to run on JUnit4, you can use a range of "4.0.0".
Dependencies on the shape of the JDT feature
Some tests make assumptions about the contents of the JDT feature - the number of bundles, the version number of the bundle "org.junit", etc. Such tests need to be updated due to the changes in the JDT feature (new bundle "org.junit" with a 4.x version). Typically these tests are in PDE and JDT and are unlikely to be an issue with tests outside the Eclipse SDK.
Custom subclasses of junit.framework.TestSuite
Some of the test runners in JUnit4 no longer call TestSuite.tests() to obtain the list of tests. If you have a subclass of TestSuite that overrides the tests() method, you will likely be broken by the move to JUnit4. The test runner in JUnit4 instead calls TestSuite.run(TestResult). If you were previously overriding TestSuite.tests(), you will now also need to override TestSuite.run(TestResult) to make sure your extra tests are called.
Custom subclasses of junit.framework.TestResult
The JUnit class TestResult changed several of its protected fields from Vector to List. This is a breaking change for any subclass of TestResult that accessed those fields. Such classes will need to update from calling Vector methods to calling List methods. Luckily since Vector implements List, after you make this change you will be able to run on both JUnit3 and JUnit4.
Using the test framework with JUnit3 or Junit4
Steps to run with JUnit4
- Run the Eclipse Test Framework with a Java 1.5+ VM
- Ensure that you specify that your bundle requires org.junit version 4.0.0+, either in the bundle dependencies or package imports.
Steps to run with JUnit 3
- Run the Eclipse Test Framework with JDK 1.4
- Ensure that you specify that your bundle requires org.junit version less than 4.0.0, either in the bundle dependencies or package imports.