203

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

Example, I have 2 modules:

  • Base
  • Main

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.

1
  • 1
    It seems an answer equivalent to the combination of the accepted answer below, which is actually a note on the larger answer further below, is now at the Maven site: How to create a jar containing test classes Commented Aug 17, 2017 at 10:09

5 Answers 5

209

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> 
Sign up to request clarification or add additional context in comments.

4 Comments

Should there be a separate dependency entry for com.myco.app specially for the test-jar type?
Also remember to add test-jar to maven-jar-plugin configuration: maven.apache.org/guides/mini/guide-attached-tests.html
I was confused when first reading this answer... That's actually because it does not make sense on its own, you should first read the below answer: stackoverflow.com/questions/174560/…
Great. Works perfectly in IntelliJ without any further configuration - no need to configure a test jar module as the previous comment suggests.
203

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> 

10 Comments

Note, that there can be issues with using <classifier>tests</classifier in the dependency. Instead, use <type>test-jar</type>. Here's one issue in Maven jira.codehaus.org/browse/MNG-2045 and an unrelated one in IntelliJ youtrack.jetbrains.net/issue/IDEA-54254
It has been very useful to me, but I have found a problem: When I execute "install -Dmaven.test.skip=true", also the dependency test-jar is required and the proccess fails
@JaviPedrera it works for me even if I do 'mvn clean install -DskipTests=true' and the test-jar will be creating. no errors
@Allen have you made sure that you use the ServiceResultTransformer while packaging your jar? Otherwise you may end up with service files overwriting each other.
|
14

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> 

2 Comments

Yep, that'd work, thanks! See my comment below for alternate answer that I prefer.
We use this approach as well, it's a bit silly you are forced to go for classifiers or types (that are hardly basics in Maven for most of the users) and that you have to build JAR with some effort when you don't really need it or - as in this case - you have de-facto non-test code as a base only for the test code.
0

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

Comments

-3

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> 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.