43

There is a clear solution for sharing the common test code between maven projects using test-jar goal of maven-jar-plugin plugin (see here).

I need to do the similar thing with test resources, in particular, I want test resources of project A be available in the classpath of project B during testing.

For project A one need to declare:

<!-- Package and attach test resources to the list of artifacts: -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-antrun-plugin</artifactId>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>run</goal>
            </goals>
            <configuration>
                <tasks>
                    <jar destfile="${project.build.directory}/test-resources.jar">
                        <fileset dir="${project.basedir}/test-resources" />
                    </jar>
                </tasks>
            </configuration>
        </execution>
    </executions>
</plugin>
<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>build-helper-maven-plugin</artifactId>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>attach-artifact</goal>
            </goals>
            <configuration>
                <artifacts>
                    <artifact>
                        <file>${project.build.directory}/test-resources.jar</file>
                        <type>jar</type>
                        <classifier>test-resources</classifier>
                    </artifact>
                </artifacts>
            </configuration>
        </execution>
    </executions>
</plugin>

And in project B it will be normal dependency:

<dependency>
    <groupId>myproject.groupId</groupId>
    <artifactId>myartifact</artifactId>
    <version>1.0-SNAPSHOT</version>
    <classifier>test-resources</classifier>
    <scope>test</scope>
</dependency>

Question: Should it work in all cases? Is it possible to pack resources without maven-antrun-plugin (using more 'lightweight' plugin)?

Community
  • 1
  • 1
dma_k
  • 9,513
  • 13
  • 68
  • 122
  • Seems there is a need to enhance remote resource plugin for test resources - http://maven.apache.org/plugins/maven-remote-resources-plugin/index.html – cetnar Feb 11 '10 at 21:35
  • @centar: thanks for the interesting plugin information, although, what you said is a bit offtopic :) – dma_k Feb 15 '10 at 11:09

4 Answers4

39

Just use jar:test-jar and declare the resulting JAR as a dependency (refer to this guide for more details). And while I don't understand the problem of having resources and classes in this jar, you can always exclude all .class files:

<project>
  <build>
    <plugins>
     <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-jar-plugin</artifactId>
       <version>2.2</version>
       <executions>
         <execution>
           <goals>
             <goal>test-jar</goal>
           </goals>
         </execution>
       </executions>
       <configuration> 
         <excludes>
           <exclude>**/*.class</exclude>
         </excludes>
       </configuration> 
     </plugin>
    </plugins>
  </build>
</project>

And to use it:

<project>
  ...
  <dependencies>
    <dependency>
      <groupId>com.myco.app</groupId>
      <artifactId>foo</artifactId>
      <version>1.0-SNAPSHOT</version>
      <type>test-jar</type>
      <scope>test</scope>
    </dependency>
  </dependencies>
  ...
</project>
Pascal Thivent
  • 535,937
  • 127
  • 1,027
  • 1,106
  • Shouldn't the execution phase be set to package? – sal Feb 12 '10 at 20:00
  • 1
    @sal It is because `jar:test-jar` *"binds by default to the lifecycle phase: `package`."* – Pascal Thivent Feb 12 '10 at 20:05
  • @Pascal: Thanks for the hint. I agree, that makes sense to package resources with classes. +1 for your answer, however, the original questions was not answered (how to package test resources separately in most optimal way?). – dma_k Feb 13 '10 at 18:17
  • 1
    @dma_k Well, I suggested a way to exclude classes and thus to package the test resources only. Doesn't this answer the question? – Pascal Thivent Feb 13 '10 at 19:13
  • @Pascal: Yes, your answer can be really accepted. Maybe you can also help me to find out, how `maven-jar-plugin` also adds test resources to destination jar file? I haven't found any code that does it in `org.apache.maven.plugin.jar.AbstractJarMojo.java`. Who helps him to add resources? – dma_k Feb 13 '10 at 22:33
  • @dma_k The jar plugin just packages the content of a directory, nothing more. Resources are copied during the `process-resources` phase by the Maven Resources plugin (http://maven.apache.org/plugins/maven-resources-plugin/). – Pascal Thivent Feb 13 '10 at 23:05
  • it is possible to use the dependency on the same project twice, having different scope and type; One for production use, and another one with test resources for test scope? – supertonsky Apr 11 '17 at 04:13
  • I think you mean "classifier" instead of "type"… I don't think it is possible to achieve this with `maven-jar-plugin`, but using `maven-antrun-plugin`+`build-helper-maven-plugin` this is pretty possible. What difficulties have you faced? – dma_k Nov 30 '18 at 21:35
4

Accepted answer helped me, but it's not quite accurate in case you need regular jar of same project as well. It will delete *.class files from both jars.
Settings below translates to something like:

  • create me 2 jars, 1 regular, 1 test;
  • remove *.class files, but only from test jar

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <executions>
            <execution>
                <goals>
                    <goal>test-jar</goal>
                </goals>
                <configuration>
                    <excludes>
                        <exclude>**/*.class</exclude>
                    </excludes>
                </configuration>
            </execution>
        </executions>
    </plugin>
miracle_the_V
  • 886
  • 1
  • 10
  • 30
  • 1
    I don't really see the difference in comparison with POM snippet from accepted answer. – dma_k Nov 30 '18 at 21:39
  • It's all about where configuration (exclusion) apply: it only applies for test-jar here, as opposed to both test and normal jar in accepted answer. Excluding class files from main jar may not be desired behavior. – miracle_the_V Dec 03 '18 at 09:14
2

Using maven-dependency-plugin we can put the resource needed in the right directory, only modifying the pom on dependent project is needed:

<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-dependency-plugin</artifactId>
   <executions>
      <execution>
         <phase>generate-test-resources</phase>
         <goals>
            <goal>unpack</goal>
         </goals>
         <configuration>
            <artifactItems>
               <artifactItem>
                  <groupId>dependeeGroupId</groupId>
                  <artifactId>dependeeArtifactId</artifactId>
                  <version>dependeeVersion</version>
                  <type>test-jar</type>
                  <outputDirectory>${project.build.directory}/test-classes</outputDirectory>
                  <includes>resourceNeeded.txt</includes>
                  <overWrite>true</overWrite>
               </artifactItem>
            </artifactItems>
         </configuration>
      </execution>
   </executions>
</plugin>

type is used to get test resource
outputDirectory is used to put the resource usable in tests

Documentation here: https://maven.apache.org/plugins/maven-dependency-plugin/unpack-mojo.html

0

There is already a goal to build a test jar from maven.

Assuming you need something a little more flexible, you can use the jar plugin to package your test resources and run that goal with the main package goal with something like this.

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>jar</goal>
            </goals>
            <configuration>
              <classifier>test-resources</classifier>
              <includes>
                <include>**/*.whatever-you-want</include>
              </includes>
            </configuration>
          </execution>
        </executions>
      </plugin>

Whatever you want bundled would be added to the project-name-version-test-resources.jar when the jar goal is run.

You could then include it in a project via the same dependency you use above.

sal
  • 22,528
  • 15
  • 64
  • 84
  • Executing the `jar` goal automatically binds `maven-jar-plugin` to "classes directory", not "test classes directory". So above will package simply normal classes, and `include` will not help to all any test resources to the artifact. Sorry, but "-1". – dma_k Feb 13 '10 at 17:36