Scenario
Project-A provides some functionality (let's say it's a Ledger Aspect), and as part of the project's test code, it contains a mocked out persistence layer that makes use of a Ledger Aspect Test Harness to provide full test coverage. Project-A's pom snippet will look like this and won't have anything noteworthy there.
...
<project>
<artifactId>projecta</artifactId>
<groupId>myProjects</groupId>
<version>1</version>
<name>Project A</name>
</project>
Project-B makes use of the Ledger Aspect, and as part of the developing team's process, they want to write a unit test that makes use of the Ledger Aspect Test Harness to test that Project-B can actually integrate with Project-A. We start out with a "naïve" pom to capture the dependencies.
...
<project>
<artifactId>projectb</artifactId>
<name>Project B</name>
<dependencies>
<dependency>
<artifactId>projecta</artifactId>
<groupId>myProjects</groupId>
<version>1</version>
</dependency>
</dependencies>
</project>
The problem we'll see is that the Ledger Aspect Test Harness is part of Project-A's test code, and will therefore not be part of the artifact build, so when we run our maven test goal on Project-B, we are given a build failure on our test classes.
How-to
There are two steps to solving this problem. To get it to work, you have to follow them exactly. First, tell Project-A to build its test classes, and deploy them in a test jar.
...
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Once you include this snippet in Project-A's pom, you will see the projecta-1-tests.jar artifact appear in your repository (on install or deploy). The "tests" portion of the artifact name is a hidden classifier that is automatically assigned by the maven-jar-plugin. Do not try and specify a classifier - this is done for you behind the scenes.
Next, add a new dependency to Project-B's pom, like this. Note that the scope is "test" (singular) and the classifier is "tests" (plural). This is because "test" is a legitimate scope that Maven provides, whereas "tests" is simply an ad-hoc classifier that the maven-jar-plugin creates behind the scenes.
...
<dependency>
<artifactId>projecta</artifactId>
<groupId>myProjects</groupId>
<version>1</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
This allows Project-B to have its tests (but not its main code) compile against the test code from Project-A. In this example, Project-B's main code does depend on Project-A's main code, but it so happens that Project-B's test code has an additional dependency on Project-A's test code.
As a side note... Another way to point Project-A's dependency to the test jar is by specifying the type as "test-jar". This is the way recommended by the "Guide to using attached tests" at http://maven.apache.org/guides/mini/guide-attached-tests.html
One problem with this approach is that while the "tests" classifier magically appears on the artifact name, the "test-jar" type doesn't appear anywhere except in Project-A's dependency. I do not know of any reasons why it is preferrable to use type over classifierJust follow http://maven.apache.org/guides/mini/guide-attached-tests.html.
It doesn't explain why you should use
| Code Block |
|---|
<type>test-jar</type>
|
instead of
| Code Block |
|---|
<classifier>tests</classifier>
|
but one reason I can think of is that by using the type tag, you reduce the possible confusion with using type of jar and classifier of tests.
