在项目的RCP程序中有两类代码需要测试:
- 一类是testSourceDirectory里的测试代码,由maven-surefire-plugin执行。
- 一类是单独的test plugin里的测试代码,由tycho-surefire-plugin执行。
1. 测试testSourceDirectory
testSourceDirectory默认是src/test/java,可以在pom中修改,Eclipse plugin project的源代码在src folder里,对应的测试代码通常就放在test folder里。pom文件设置:
<build> <sourceDirectory>src</sourceDirectory> <testSourceDirectory>test</testSourceDirectory> </build>
对于packaging类型为eclipse-plugin,eclipse-test-plugin等tycho类型的Mave项目,需要明白以下两点:
- Maven使用tycho-compiler-plugin编译plugin,tycho-compiler-plugin没有testCompile goal,所以testSourceDirectory里的代码不会被编译。
- maven-compiler-plugin有testCompile goal,但是effective pom里没有,默认不会执行。
所以为了能够测试testSourceDirectory,我们需要添加maven-compiler-plugin来编译测试代码,然后使用maven-surefire-plugin运行unit test。务必写明在哪个phase执行哪个goal,effective pom里默认没有,所以不会继承任何<execution/>设置。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<executions>
<execution>
<id>compiletests</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<executions>
<execution>
<id>test</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
</plugin>
2. 测试单独的test plugin
test plugin是运行在OSGI环境中的,会先加载其所依赖的plugin,然后执行本身的unit test,如果有UI的话,会打开相应的UI。
2.1 设置Target Platform
添加一个target platform plugin,在Eclipse中作为我们的开发、运行环境,在Maven中作为我们的运行环境。
Eclipse Plugin-in Development Environment这个非常重要,plugin test依赖的junit和junit runtime包含在这个feature里面。

2.2 配置POM
在pom中聚合这个target platform plugin,并且使用target-platorm-configuration插件配置maven在构建过程中使用该target platform。
<modules>
<module>../tychodemo.target</module>
</modules>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>target-platform-configuration</artifactId>
<version>${tycho-version}</version>
<configuration>
<target>
<artifact>
<groupId>tychodemo</groupId>
<artifactId>tychodemo.target</artifactId>
<version>0.0.1-SNAPSHOT</version>
</artifact>
</target>
<environments>
<!-- Specify environment value according to system type -->
<environment>
<os>macosx</os>
<ws>cocoa</ws>
<arch>x86_64</arch>
</environment>
<!--
<environment>
<os>win32</os>
<ws>win32</ws>
<arch>x86_64</arch>
</environment>
<environment>
<os>linux</os>
<ws>gtk</ws>
<arch>x86_64</arch>
</environment>
-->
</environments>
</configuration>
</plugin>
</plugins>
</build>
tycho-surefire-plugin的配置:
- <useUIHarness/>为false,表示使用headless mode运行,即使没有Display也可以运行;
- <useUIThread/>为true,表示使用UI线程。
- <providerHint/>为junit4,表示使用junit4执行unit test。Indigo只支持junit3,即使写成junit4,junit4的unit test也不会被执行。
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-surefire-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<useUIHarness>false</useUIHarness>
<useUIThread>true</useUIThread>
<providerHint>junit4</providerHint>
</configuration>
</plugin>
2.3 给test plugin添加依赖
test plugin运行在OSGI环境中,dependencies中添加:
- org.junit:只能是RCP environment自己的junit。手动在class path中添加一个junit,或者使用自己封装的third-party plugin里的junit,都不work。运行时说,cannot specify target Test Framework, available is junit3, junit4, junit47, junit5。这句英文是我凭记忆写的,原message应该不是这样的。这个错误,就算在tycho-surefire-plugin里指定Test Framework也不work。
- org.eclipse.jdt.junit.runtime:这个plugin也是RCP environment里的,用于发现和执行测试类。如果没有这个依赖,一个测试也不会执行,最后说no test is found。

2.4 编写测试代码
Test plugin中的测试代码,要放在src folder里,不能放在test folder里,因为tycho-surefire-plugin只会在src folder里寻找test classes。当然我们也可以在test folder里写测试测试类,但这些测试类只能被maven-surefire-plugin执行(前提是配置了maven-surefire-plugin)。
Plug-in test中,可以访问UI。也就是可以测试UI,例如测试当前OSGI环境中某个Service是否注册了;打开一个UI,检测各个Widget是否正确等。
注意:在Eclipse Indigo 3.7.2环境中,plugin unit test要使用Junit 3的写法,继承TestCase类。Junit 4的annotation写法,经过测试,Eclipse上执行class loader抛异常;maven命令行执行,无法识别这些测试类。
Example:
public class HelloPlutinTest extends TestCase {
public void testShellExist() {
assertNotNull(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
}
}
2.5 运行plugin test
Eclipse上执行:右键 —> Run As / Debug As —> Junit Plug-in Test。
Maven命令行执行:tycho-surefire-plugin绑定在integration-test phase上,执行mvn integration-test便可。
3. 总结
如果项目中的Junit Plug-in Test不测UI,它就跟普通的Junit测试没啥两样,但是性能不如普通的Junit测试,因为Junit Plugin-in Test要初始化运行环境,加载需要的plugin等。
unit test的执行要尽可能的快,所以如果Junit Plug-in Test里面没有测试UI的类,我倾向于使用maven-surefire-plugin来执行。
小技巧:将Junit Plugin-in Test工程的source folder从src改为test,它们就会变被maven-surefire-plugin执行,而tycho-surefire-plugin就不会执行它们。