flicken
flicken

Reputation: 15543

Sharing Test code in Maven

How can you depend on test code from another module in Maven?

Example, I have 2 modules:

I would like a test case in Main to extend a base test class in Base. Is this possible?

Update: Found an acceptable answer, which involves creating a test jar.

Upvotes: 203

Views: 73304

Answers (5)

Krzysiek
Krzysiek

Reputation: 41

Worked for me for 1 project, but I didn't for another after doing exactly the same steps.

So I debugged:

  1. After mvn clean install I checked /target directory: .jar was there so thats good
  2. Ran mvn dependency:tree on a project which should use those test classes. Noticed that generated jar file with test classes is marked as dependency, so thats good.
  3. Conclusion could be only one - I restarted my Intellj. At first class import was still not visible, but after a minute it started to see it!

Note: I only restarted Intellj, no caches removal etc

Upvotes: 0

flicken
flicken

Reputation: 15543

Thanks for the base module suggestion. However, I'd rather not create a new module for just this purpose.

Found an acceptable answer in the Surefire Maven documentation and a blog. See also "How to create a jar containing test classes".

This creates jar file of code from src/test/java using the jar plugin so that modules with tests can share code.

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

In order to use the attached test JAR that was created above you simply specify a dependency on the main artifact with a specified classifier of tests:

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

Upvotes: 203

Ben
Ben

Reputation: 4965

I recommend using type instead of classifier (see also: classifier). It tells Maven a bit more explicitly what you are doing (and I've found that m2eclipse and q4e both like it better).

<dependency>
  <groupId>com.myco.app</groupId>
  <artifactId>foo</artifactId>
  <version>1.0-SNAPSHOT</version>
  <type>test-jar</type>
  <scope>test</scope>
</dependency>

Upvotes: 209

sal
sal

Reputation: 23623

We solved this by making a maven project with test code as the src/main/java and adding the following dependency to projects:

    <dependency>
        <groupId>foo</groupId>
        <artifactId>test-base</artifactId>
        <version>1</version>
        <scope>test</scope>
    </dependency>

Upvotes: 14

Steve Moyer
Steve Moyer

Reputation: 5733

Yep ... just include the Base module as a dependency in Main. If you're only inheriting test code, then you can use the scope tag to make sure Maven doesn't include the code in your artifact when deployed. Something like this should work:

<dependency>
    <groupId>BaseGroup</groupId>
    <artifactId>Base</artifactId>
    <version>0.1.0-SNAPSHOT</version>
    <scope>test</scope>
</dependency>

Upvotes: -3

Related Questions