Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

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.