我应该在哪里放置Java库的测试支持代码

时间:2012-12-21 13:29:32

标签: unit-testing maven module

我有一个Maven项目,在其他项目中用作库。该设置非常标准:src/main包含库代码,src/test包含src/main的测试用例。

我们假设我有一个项目foo,它依赖于这个库。 foo也有测试用例。为了帮助在foo中为使用我的库的代码编写测试,我想给foo一个支持框架来编写测试(比如设置一个模拟环境)。

我可以在哪里提供此支持代码?

  • 它不应该进入src/main,因为它不打算投入生产。
  • 它不能进入​​src/test,因为从foo的测试创建依赖项到库的测试会给类路径添加太多垃圾(比如logback-test.xml配置文件,从未执行过的测试......)。

我可以将代码放入一个新模块,但它与src/main中的代码紧密耦合,所以我想将它保存在同一个项目中(也允许测试支持代码访问包私有领域和方法)。

此外,src/test中的代码应该可以访问它,以便我可以使用它来编写我自己的单元测试。

我有什么选择让Maven将其保留在同一个项目中但仍然与src/mainsrc/test完全分开?我可以以某种方式为src/test-support创建第三个输出JAR吗?或者我应该将代码放入src/test然后使用JAR插件中的过滤器仅包含支持代码?

2 个答案:

答案 0 :(得分:3)

您可以使用Maven Jar插件

执行此操作

Maven Jar Plugin

由于您正在使用Maven,您可以在项目中剪切包含要在foo中使用的库的项目的单独工件,添加以下插件以创建另一个jar工件:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.3.2</version>
    <executions>
       <execution>
          <goals>
              <goal>test-jar</goal>
          </goals>
       </execution>
    </executions>
  </plugin>

这会在src / test目录中的所有项目中创建第二个jar。

Test Jars

你可以用一些过滤器拼出你不需要的那些东西。

然后要使用这个库,你可以在foo中包含它作为依赖:

 <dependency>
    <groupId>your.group</groupId>
    <artifactId>parent-artifact-id</artifactId>
    <version>1.0.0</version>
    <type>test-jar</type>
    <scope>test</scope>
 </dependency>

为了进一步分离项目,您还可以使用更具框架性的测试罐创建仅测试项目 请参阅如何在Maven Jar插件文档

中创建包含测试类(首选方式)的jar

答案 1 :(得分:0)

这是一个POM片段,它将主JAR拆分为普通工件和“JUnit支持JAR”:

<build>
    <plugins>
        <plugin>
            <artifactId>maven-jar-plugin</artifactId>
            <executions>
                <execution>
                    <id>default-jar</id>
                    <phase>package</phase>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                    <configuration>
                        <archive>
                            <index>true</index>
                            <manifest>
                                <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                            </manifest>
                        </archive>
                        <excludes>
                            <exclude>**/junit/**</exclude>
                        </excludes>
                    </configuration>
                </execution>

                <execution>
                    <id>junit-jar</id>
                    <phase>package</phase>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                    <configuration>
                        <classifier>junit</classifier>
                        <archive>
                            <index>true</index>
                            <manifest>
                                <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                            </manifest>
                        </archive>
                        <includes>
                            <include>**/junit/**</include>
                        </includes>
                    </configuration>
                </execution>

                <execution>
                    <id>test-jar</id>
                    <goals>
                        <goal>test-jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

    </plugins>
</build>

简而言之,它查找名称中包含junit的任何包,并将其放入JUnit JAR中,将其从正常工件中排除。

如果普通jar的坐标是

<groupId>com.group</groupId>
<artifactId>foo</artifactId>

然后只需添加<classifier>junit</classifier>

即可获得JUnit支持代码
<groupId>com.group</groupId>
<artifactId>foo</artifactId>
<classifier>junit</classifier>

所以要使用它,依赖于com.group:foo的POM将如下所示:

<dependency>
    <groupId>com.group</groupId>
    <artifactId>foo</artifactId>
    <version>...</version>
</dependency>
<dependency>
    <groupId>com.group</groupId>
    <artifactId>foo</artifactId>
    <version>...</version>
    <classifier>junit</classifier>
    <scope>test</scope>
</dependency>

有时,您需要JUnit来编译“JUnit支持JAR”。如果是这种情况,请使用

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <scope>compile</scope>
    <optional>true</optional>
</dependency>

将JUnit包含在构建中。这将使编译时的依赖性可用,但不会泄露给任何其他人。