我们正在尝试从使用gwt-test-utils编写的一组单元测试中为我们的GWT应用程序生成覆盖率报告。该项目是一个多模块的maven项目。我们在jenkins上使用sonar-plugin来生成和整理我们的覆盖范围和违规信息。
当构建作业运行时,所有GWT单元测试都作为正常构建的一部分传递,但是当Sonar插件尝试重新运行测试时,它们都会因以下错误而失败:
initializationError(uk.co.card.gwt.retailpost.client.dialog.productmodify.CurrencyEditDialogTest)经过的时间:0秒<<<错误! com.googlecode.gwt.test.exceptions.GwtTestException:生成gwt-test-utils先决条件时出错 在com.googlecode.gwt.test.internal.GwtFactory。(GwtFactory.java:113) 在com.googlecode.gwt.test.internal.GwtFactory.initializeIfNeeded(GwtFactory.java:45) 在com.googlecode.gwt.test.internal.junit.AbstractGwtRunner。(AbstractGwtRunner.java:30) 在com.googlecode.gwt.test.GwtRunner。(GwtRunner.java:19) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:513) 在org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:29) 在org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:21) 在org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59) 在org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26) 在org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59) 在org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:26) 在org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:250) 在org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141) 在org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 在java.lang.reflect.Method.invoke(Method.java:597) at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189) 在org.apache.maven.surefire.booter.ProviderFactory $ ProviderProxy.invoke(ProviderFactory.java:165) 在org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85) 在org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115) 在org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75) 引起:com.google.gwt.core.ext.UnableToCompleteException :(参见以前的日志条目) 在com.google.gwt.dev.cfg.ModuleDef.checkForSeedTypes(ModuleDef.java:559) 在com.google.gwt.dev.cfg.ModuleDef.getCompilationState(ModuleDef.java:363) 在com.google.gwt.dev.cfg.ModuleDef.getCompilationState(ModuleDef.java:354) 在com.googlecode.gwt.test.internal.GwtFactory.createCompilationState(GwtFactory.java:151) 在com.googlecode.gwt.test.internal.GwtFactory。(GwtFactory.java:106) ......还有25个
查看jenkins和工作区目录的其余控制台输出,我找不到“com.google.gwt.core.ext.UnableToCompleteException :(参见前面的日志条目)”引用的日志文件到。
有没有人遇到类似的问题并且知道如何让Sonar成功运行gwt-test-utils,或者至少知道何时查找异常中提到的先前日志条目。
编辑:经过进一步的实验,这个问题似乎是由jacoco引起的。试图只运行jacoco装备的单元测试(并且没有涉及声纳)会导致同样的错误
**编辑:
来自pom.xml的样本
<build>
pluginManagement>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.6.2.201302030002</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
<configuration>
<excludedGroups combine.self="override" />
<reuseForks>true</reuseForks>
<argLine>-Xmx1024m -XX:MaxPermSize=256m ${jacoco.agent.argLine}</argLine>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<configuration>
<propertyName>jacoco.agent.argLine</propertyName>
<destFile>${sonar.jacoco.itReportPath}</destFile>
<append>true</append>
<excludes>
<exclude>*.osgi.*</exclude>
<exclude>*.apache.*</exclude>
<exclude>*.sourceforge.*</exclude>
<exclude>*.junit.*</exclude>
<!-- Test support code does not need to be covered -->
<exclude>uk.co.card.retailpost.clientintegration.utilities.*</exclude>
</excludes>
<classDumpDir>temp/classes</classDumpDir>
</configuration>
<executions>
<execution>
<id>agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
答案 0 :(得分:3)
正如我在评论中提到的,javoco与maven-surefire-plugin以不同的顺序加载库。要解决这个问题,请编写自己的运行程序(扩展com.googlecode.gwt.test.GwtRunner)并更改线程contextClassLoader的类加载器。
import com.googlecode.gwt.test.GwtRunner;
public class MyGwtRunner extends GwtRunner {
static {
URLClassLoader classLoader = (URLClassLoader) MyGwtRunner.class.getClassLoader();
try {
URL[] urls = getClassPath();
ClassLoader cl = URLClassLoader.newInstance(urls, classLoader);
Thread.currentThread().setContextClassLoader(cl);
} catch (MalformedURLException e) {
throw new IllegalStateException(e);
}
}
public MyGwtRunner(Class<?> clazz) throws Throwable {
super(clazz);
}
private static URL[] getClassPath() throws MalformedURLException {
String classPath = System.getProperty("java.class.path");
String pathSeparator = System.getProperty("path.separator");
String[] array = classPath.split(pathSeparator);
List<URL> files = new ArrayList<URL>();
for (String a : array) {
files.add(new File(a).toURI().toURL());
}
return files.toArray(new URL[files.size()]);
}
}
在您的测试中,通过MyGwtRunner覆盖GwtRunner
@GwtModule("com.my.module.GwtTestUtils")
@RunWith(MyGwtRunner.class)
public abstract class AbstractGwtJunit extends GwtTest {
....
}