如何同时使用 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 测试?

如何使用 HSQLDB 内存数据库设置为 Maven 项目执行 Junit 测试套件?

如何在 Maven 中按类别运行 JUnit 测试?

如何使用 Maven surefire 排除具有给定类别的所有 JUnit4 测试?