Where should I put test support code for a Java library

前端 未结 2 973

I have a Maven project which is used as a library in other projects. The setup is pretty standard: src/main with the library code, src/test with te

相关标签:
2条回答
  • 2021-01-18 11:47

    You can do this with the Maven Jar Plugin

    Maven Jar Plugin

    Since you're using Maven you can just cut a separate artifact of the project that contains the libraries you want to use in foo add the following plugin to create another jar artifact:

      <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>
    

    This creates a second jar in this project of everything in the src/test directory.

    Test Jars

    You could splice out the stuff in that jar you don't need with some filters.

    Then to use this library you would include this as a dependancy in foo:

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

    To separate the projects further you can also create a test only project with your more frameworky test jars.
    See How to create a jar containing test classes (Preferred way) in the Maven Jar Plugin doc

    0 讨论(0)
  • 2021-01-18 11:51

    Here is a POM fragment which splits the main JAR into the normal artifact and a "JUnit support 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>
    

    In a nutshell, it looks for any package with junit in its name and puts it into the JUnit JAR, excluding it from the normal artifact.

    If the coordinate for the normal jar is

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

    then you can get the JUnit support code by simply adding <classifier>junit</classifier>:

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

    So to use this, the POM which depends on com.group:foo will look like this:

    <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>
    

    Sometimes, you will need JUnit to compile your "JUnit support JAR". If that's the case, use

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

    to include JUnit into the build. This will make the dependency available at compile time but it will not leak to anyone else.

    0 讨论(0)
提交回复
热议问题