我该如何同时使用maven和jUnit测试?

6

我有一个使用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生命周期中,测试阶段被定义为在integration-test之前存在,没有办法跳过测试阶段来运行纯粹的integration-test?
由于我将所有的测试代码混在了/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测试?

4个回答

7

你好,我了解到你的问题,可能的解决方案在这个gwt-maven-plugin文档页面上:https://gwt-maven-plugin.github.io/gwt-maven-plugin/user-guide/testing.html

根据插件文档:

出于意图: “test”目标默认绑定到integration-test阶段,并且GWTTestCase不被视为单元测试,因为它们需要整个GWT模块来运行。

要同时运行Surefire和gwt-maven-plugin基础测试(用于使用Surefire进行常规服务器端JUnit测试以及使用GWT进行客户端模型和控制器测试),您需要将这些测试区分开来。这是通过命名约定完成的。

您可以配置Surefire插件(负责在maven构建期间运行测试)使用一些命名模式跳过GwtTests。

一个更简单的方法是将最新的GwtTest"Something".java命名为GwtTest*.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


1

我可以帮忙回答问题1。若要跳过运行测试:

mvn (goals) -Dmaven.test.skip=true

这将使其忽略JUnit测试。

至于问题2,经典的JUnit可能是最好的选择。我对GWT不太熟悉,但它是否有测试注释(@test)?第42行出了什么错误?


1

顺便提一下,在我参与的大多数非平凡项目中,有一个对JUnit的极端偏见,原因有两个。第一是GWTUnit需要启动JavaScript上下文,这比JUnit测试慢得多,令人痛苦。其次,根据您的设计和代码结构,您不应该编写太多需要JavaScript上下文来进行测试的内容。主要是由于问题1,但也要记住,您现在正在编写一个GWT视图,但您真正希望它尽可能地与视图技术无关。这样当Swing重返显赫时,您可以更轻松地将其移植过去。开玩笑,更可能的情况是将其移植到Android或未来的其他平台。

基本上,GWTUnit 运行非常缓慢,因为它必须启动环境,实际上,你应该(在我看来)将业务逻辑分离出来,这样你就不会永远与任何一个视图渲染技术耦合。在我的观点中,大多数可以从纯 UI 世界的小部件和面板中分离出来的逻辑都应该是,无论是控制流类型逻辑、验证逻辑还是除了将东西放在屏幕上并将值输入和输出之外的任何其他逻辑。在一个更大的项目中,所有其他内容都应该超出这些类,并以没有任何与 GWT 相关的方式作为输入的对象。如果你这样做,你可以对你的应用程序进行 JUnit 测试,这是非常快速的,你不必等待太久(在一个大型项目中,使用 GWTUnit 进行大量覆盖可能需要几个小时,甚至几天)。我不会继续谈论强大的单元测试覆盖代码库对于维护的重要性。

这篇文章是基于我在目前工作中完成的最后一个任务而写的,其中有一组业务逻辑与视图层绑定在一起,最终在完全解开和构建完整单元测试套件之后,共有178个不同的场景需要正确执行。这本来是不应该知道它在运行GWT的,但是由于被捷径处理了,并且充斥着对视图技术类的引用。实际上,这是已经为软件的早期版本编写的东西,没有太多改变,但他们将逻辑封装在那个视图层(即Swing)中。新团队只是重复了早期团队的错误,因此这段代码需要手动测试数小时,我相信这并没有100%覆盖所有场景,而不是快速几秒钟的单元测试来运行它们。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接