Modifying an Eclipse target definition to support JUnit

The Eclipse IDE has great tooling for writing and running JUnit tests. For most Java developers this tooling works without any issues, but things get a bit more complicated when working with Eclipse Plug-ins or OSGi bundles in general.

The reason for this is that plug-in/bundle developers, including most Eclipse RCP developers, will be using a custom target platform. These target platforms, usually in the form of a target definition file, must be modified to support JUnit integration.

Providing access to JUnit 4 and 5

When you set the target platform for your workspace (there can be only one active target at a time), only the features and plug-ins listed in your target will be available for compilation.

As an example, here is a very small Hello World JUnit example containing one plug-in and one test fragment (available on GitHub).

The JUnit test compiles and runs fine when the default target (the Eclipse installation itself) is active. But what if I change my target to the Eclipse RCP SDK?

Well it’s no surprise that our JUnit tests no longer compile as the JUnit libraries are no longer in our target.

What’s less clear is how to fix this. One somewhat messy solution is to add the Eclipse JDT Plug-in Developer Resources feature to your target. The JDT feature contains the JUnit plug-ins but also much else that you probably don’t want.

A better solution is to add the JUnit 4 and JUnit 5 plug-ins directly to your target. Luckily these libraries are available in the main Eclipse repository and here’s what a target location would look like.

<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="slicer" includeSource="true" type="InstallableUnit">
	<repository location="http://download.eclipse.org/releases/latest"/>
	<unit id="org.junit" version="0.0.0"/>
	<unit id="org.hamcrest.core" version="0.0.0"/>
	<unit id="org.junit.jupiter.api" version="0.0.0"/>
	<unit id="org.junit.jupiter.engine" version="0.0.0"/>
	<unit id="org.junit.jupiter.migrationsupport" version="0.0.0"/>
	<unit id="org.junit.platform.commons" version="0.0.0"/>
	<unit id="org.junit.platform.engine" version="0.0.0"/>
	<unit id="org.junit.platform.launcher" version="0.0.0"/>
	<unit id="org.junit.jupiter.params" version="0.0.0"/>
	<unit id="org.junit.platform.runner" version="0.0.0"/>
	<unit id="org.junit.platform.suite.api" version="0.0.0"/>
	<unit id="org.junit.vintage.engine" version="0.0.0"/>
	<unit id="org.opentest4j" version="0.0.0"/>
	<unit id="org.apiguardian" version="0.0.0"/>
</location>

At this point your unit tests will both compile and run using the Run As > JUnit Test context menu option.

I think it would be great if these plug-ins were packaged as a standalone feature published to the Eclipse repository. If anyone knows of anything close, let me know.

Adding support for Plug-in tests

Beyond regular JUnit tests, the Plug-in Development Environment also allows us to run in-container tests using the Run As > JUnit Plug-in Test context menu option. This allows us to run tests inside of an OSGi framework, and is useful for integration testing or if your unit tests include calls to OSGi APIs (e.g. a call to an Activator instance).

The issue here is that there is some overlap between the PDE tooling and the active target, and to support running these tests we have to add additional plug-ins to our target platform. Without these additional plug-ins you’ll get the following error.

Here is the target location that solves this particular issue.

<!-- Needed for Run As > Plug-in Test-->
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="slicer" includeSource="true" type="InstallableUnit">
	<repository location="http://download.eclipse.org/releases/latest"/>
	<unit id="org.eclipse.jdt.junit.runtime" version="0.0.0"/>
	<unit id="org.eclipse.jdt.junit4.runtime" version="0.0.0"/>
	<unit id="org.eclipse.jdt.junit5.runtime" version="0.0.0"/>
</location>

Handling unique issue with Eclipse 2020-09

There is a specific issue with Eclipse 2020-09 (4.17) that did not affect earlier versions and has been fixed for future releases. In this specific version of Eclipse the above target entries are not sufficient, and you’ll still get the following error when using the Run As > JUnit Plug-in Test context menu option.

Adding the following target location will resolve the issue.

<!-- Needed for Run As > Plug-in Test - Eclipse 4.17 only
See bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=567318 -->
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="slicer" includeSource="true" type="InstallableUnit">
	<repository location="http://download.eclipse.org/releases/latest"/>
	<unit id="org.eclipse.pde.junit.runtime" version="0.0.0"/>
</location>

Wrapping up

I would like to see this process made easier, as it’s very common for Eclipse RCP and Plug-in developers to have issues running JUnit tests. Here are a few recent bug reports.

For now, making these additions to your target seems like the simplest approach, though of course the specific JUnit libraries might change in future releases of Eclipse.

If you’d like to try out the Hello World example and the included target, you can find the GitHub repository here.

https://github.com/modular-mind/pde-junit-support