如何同时使用 maven 和 jUnit 测试?
Posted
技术标签:
【中文标题】如何同时使用 maven 和 jUnit 测试?【英文标题】:How can I use maven and jUnit tests together? 【发布时间】:2010-12-28 22:08:14 【问题描述】:我在 Maven 中构建了一个 gwt 应用程序,现在我尝试运行一个简单的 GWT 测试,如下所示:
public class GwtTestLaughter extends GWTTestCase
/**
* Specifies a module to use when running this test case. The returned
* module must include the source for this class.
*
* @see com.google.gwt.junit.client.GWTTestCase#getModuleName()
*/
@Override
public String getModuleName()
return "com.sample.services.joker.laughter.Laughter";
/**
* Add as many tests as you like
*/
public void testSimple()
assertTrue(true);
在 pom.xml 文件中,配置 gwt-maven-plugin 和 maven-surefire-plugin 如下:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<version>2.1.0-1</version>
<configuration>
<!-- Use the 'war' directory for GWT hosted mode -->
<output>$basedir/war</output>
<webXml>$basedir/war/WEB-INF/web.xml</webXml>
<runTarget>index.html</runTarget>
<!-- Make sure the GWT compiler uses Xerces -->
<extraJvmArgs>
-Dgwt.style=DETAILED -Xmx512M -Xss1024k -XX:MaxPermSize=128m -Djavax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl -Djavax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl -Dlogback.configurationFile=./src/test/resources/logback-test.xml
</extraJvmArgs>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test</goal>
</goals>
</execution>
</executions>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<useFile>false</useFile>
<forkMode>once</forkMode>
<argLine>-Xmx128m</argLine>
<systemPropertyVariable>
<property>
<name>log4j.configuration</name>
<value>log4j.properties</value>
</property>
</systemPropertyVariables>
</configuration>
<executions>
<execution>
<id>unit-test</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<skip>false</skip>
<includes>
<include>**/*Test.java</include>
<includes>
<excludes>
<exclude>**/GwtTest*.java</exclude>
</excludes>
</configuration>
</execution>
<execution>
<id>integration-test</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<skip>true</skip>
<includes>
<include>**/GwtTest*.java</include>
<includes>
<excludes>
<exclude>**/*Test.java</exclude>
</excludes>
</configuration>
</execution>
<executions>
</plugin>
当我在命令行中运行“mvn test”时,我只能看到运行正常的 Junit 测试(带有 Test.java 文件名的测试),当我运行“mvn integration-test”时,我仍然看到所有测试,包括正常的 Junit 测试和 Gwt 测试(带有 GwtTest.java 文件名的测试)运行。
问题 1:
如何在集成测试期间完全排除运行正常的 Junit 测试?或者那是不可能的?因为在默认的maven生命周期中,测试阶段被定义为在集成测试之前存在,所以没有办法跳过测试阶段来运行纯粹的集成测试?
由于我在 /src/test/java 文件夹下混合了所有测试代码,当我运行“mvn integration-test”并在命令行窗口中观察输出时,我看到了以下内容:
[INFO] running com.sample.services.joker.laughter.client.GwtTestLaughter
..
[INFO] Validating newly compiled units
[INFO] [ERROR] Errors in 'file:...src/test/java/com/sample/joker/laughter/client/file1Test.java'..
[INFO] [ERROR] Line 42: No source code is available for type...; did you forget to inherit a required module?
...
问题 2:
我不明白,gwt 测试是一个非常简单的测试,为什么它会验证一个不相关的 *Test.java 并搜索它的源代码。虽然最终通过测试成功构建,但我怎样才能摆脱那些讨厌的错误消息?
也许我应该忘记 gwt-mavin-plugin 并坚持使用经典的 Juint 测试?
【问题讨论】:
【参考方案1】:您好,我了解您的问题,可能的解决方案位于此 gwt-maven-plugin 文档页面:https://gwt-maven-plugin.github.io/gwt-maven-plugin/user-guide/testing.html
根据插件文档:
有意: “测试”目标默认绑定到集成测试阶段,并且 GWTTestCase 不被视为单元测试,因为它们需要运行整个 GWT 模块。
要同时运行基于 Surefire 和 gwt-maven-plugin 的测试(使用 Surefire 进行常规服务器端 JUnit 测试,以及使用 GWT 进行客户端模型和控制器测试),您需要区分这些测试。这是使用命名约定完成的。
您可以使用一些命名模式配置 Surefire 插件(负责在 maven 构建期间运行测试)以跳过 GwtTest。
区分经典测试和 GWT 测试的更简单方法是将最新的 GwtTest 命名为“Something”.java。由于 surefire 会查找默认命名为 Something"Test".java 的测试,因此它们将在测试阶段被忽略。
默认情况下,gwt-maven-plugin 使用 GwtTest*.java 作为包含模式,因此此类测试不会匹配标准的 Surefire 模式。使用此约定,您不必更改配置。
【讨论】:
【参考方案2】:你应该像这样将 src 文件添加到类路径中:
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.6</version>
<configuration>
<additionalClasspathElements>
<additionalClasspathElement>
$project.build.sourceDirectory
</additionalClasspathElement>
<additionalClasspathElement>
$project.build.testSourceDirectory
</additionalClasspathElement>
</additionalClasspathElements>
<useManifestOnlyJar>false</useManifestOnlyJar>
<forkMode>always</forkMode>
<systemProperties>
<property>
<name>gwt.args</name>
<value>-out \$webAppDirectory</value>
</property>
</systemProperties>
</configuration>
Reference
【讨论】:
【参考方案3】:我可以帮助解决问题 1。跳过正在运行的测试:
mvn (goals) -Dmaven.test.skip=true
这将使它忽略 JUnit 测试。
至于问题 2,经典的 JUnit 可能是要走的路。我对 GWT 不太熟悉,但它有测试注释(@test)吗?第 42 行有什么错误?
【讨论】:
【参考方案4】:顺便说一句,在我参与的大多数重要项目中,对 JUnit 存在极端偏见,原因有两个。首先是 GWTUnit 需要启动 javascript 上下文,与 JUnit 测试相比,这很慢,非常慢。其次,根据您的设计和代码结构,您确实不应该编写太多需要 Javascript 上下文进行测试的内容;主要是因为问题 1,但也请记住,您现在正在使用 GWT 视图编写一些东西,但您真的希望它尽可能地与视图技术无关。这样,当 Swing 凯旋而归时,您可以更轻松地将其移植过来。我在开玩笑,更可能的情况是移植到 android 或者谁知道将来还会发生什么。
因此,基本上,GWTUnit 运行起来非常缓慢,因为它必须启动它的环境,实际上,您应该(恕我直言)分解您的业务逻辑,这样您就不会永远与任何一种视图耦合渲染技术。在我看来,可以从小部件和面板的纯 UI 世界中分离出来的大部分逻辑应该是,无论是控制流类型逻辑、验证逻辑,还是除了将内容放在屏幕上并将值输入和输出之外的任何东西其中。在更大的项目中,其他所有内容都应该不在这些类中,并将对象作为与 GWT 没有任何关系的输入。如果你这样做了,你就可以 JUnit 应用程序的绝大部分,这非常快,而且你不必永远等待(在一个大型项目中,使用 GWTUnit 进行大量覆盖需要几个小时,甚至几天)。我不会继续讨论如何维护一个强大的单元测试覆盖的代码库。
这个咆哮是由我在当前工作中完成的最后一项任务所预测的,有一组业务逻辑与视图层一起结束(在展开和构建一个完整单元结束时)测试套件)178 个不同的场景,所有场景都必须正确执行。这是永远不应该知道它在 GWT 中运行的东西,但它是捷径,并且充斥着对视图技术类的引用。事实上,这是已经为软件的早期版本编写的东西,并没有太大变化,但他们将逻辑封装在那个视图层(即 Swing)中。新团队刚刚重复了早期团队的罪行,因此这个代码部分需要数小时的手工测试,我敢肯定这并没有 100% 覆盖场景,而不是快速的几秒钟的单元测试运行它们。
【讨论】:
以上是关于如何同时使用 maven 和 jUnit 测试?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 maven-surefire-plugin 在同一个项目中执行 JUnit 和 TestNG 测试?
如何在 NetBeans Maven 项目中分析 JUnit 测试?
如何让 maven surefire 正确执行 JUnit 和 TestNG 测试?