Adam
Adam

Reputation: 5445

Is there an interface in a third-party library to use for JUnit @Category()

My parent pom contains the maven-surefire-plugin and maven-failsafe-plugin configurations defining the <groups> and <excludedGroups> params as below using my interface com.adam.testutil.IntegrationTest for the JUnit 4 @Category annotation, to flag any test as an integration test.

All modules under the parent pom (not just those with integration tests) will require com.adam.testutil.IntegrationTest on their classpath so that the surefire and failsafe plugins run, otherwise they throw a ClassNotFoundException.

So the class must be in a module that all the modules must declare as a dependency. I would prefer to declare it as a dependency in the parent pom so all the modules inherit it automatically, but that would create a circular dependency issue that stops mvn running.

In fact even if there are no unit or integration tests in a module, the module still has to declare the dependency.

I also have to make the module containing com.adam.testutil.IntegrationTest the first module in the build order, otherwise it won't be available in first-time installs on any new systems. I get a chicken-and-egg dilemma - I can't just run mvn install in a blank repository because the dependency with IntegrationTest isn't in the local repository yet.

In fact I don't particularly want to create a new module just to provide IntegrationTest. It would be so much simpler if JUnit had included a suitable org.junit.IntegrationTest class in the library.

While I think @Cateogry is a great way to annotate tests to flag them as integration tests, in a multi-module project it has all these disadvantages.

Is there a relevant or suitably named interface out there somewhere I could use instead of having to have my own?

In the worst case scenario, as far as JUnit, @Category, maven-surefire-plugin and maven-failsafe-plugin are concerned, I could use an interface in the JDK, e.g. java.lang.Cloneable - although anyone reading the code would wonder what on earth was going on.

I had hoped JUnit would have something, but I couldn't find anything useful.

I could just put a dependency on a third party library in my parent pom and all would be fine.

I'll accept the answer from anyone suggesting a suitable interface from a third party library, where the name of the interface would not raise immediate questions from anyone reading the code for the first time.

import org.junit.experimental.categories.Category
import com.adam.testutil.IntegrationTest

@Category(IntegrationTest.class)
public DbAndJpaIntegrationTests {
    ...
}

.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.18.1</version>
    <configuration>
        <excludedGroups>com.bp.gis.util.HeavyTest
        </excludedGroups>
    </configuration>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>2.18.1</version>
    <configuration>
        <includes>
            <include>**/*.java</include>
        </includes>
        <groups>com.bp.gis.util.HeavyTest</groups>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>integration-test</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Upvotes: 1

Views: 295

Answers (2)

kewne
kewne

Reputation: 2298

Your question seems to suggest that the purpose of the IntegrationTest interface is simply to mark which tests are executed by surefire and which are executed by failsafe.

In that case, you could use a naming convention. The default for failsafe is described in the docs:

<includes>
    <include>**/IT*.java</include>
    <include>**/*IT.java</include>
    <include>**/*ITCase.java</include>
</includes>

For surefire, the defaults are:

<includes>
    <include>**/Test*.java</include>
    <include>**/*Test.java</include>
    <include>**/*TestCase.java</include>
</includes>

Upvotes: 1

Naman
Naman

Reputation: 31928

If ..most of your module require.. the interface, you can declare your IntegrationTest in an individual module(though I would suggest not just a single interface but try and put things related to that Interface as well into this module). Let's call it by the name integration-test for an artifact.

I would prefer to declare it as a dependency in the parent pom so all the modules inherit it automatically, but that would create a circular dependency issue that stops mvn running.

  • It's not a must to declare the dependency in the parent pom.xml Though doing so using <dependencyManagement> can mark a better use of integration-test artifact versions maintained. Read more about it in the doc.

In fact even if there are no unit or integration tests in a module, the module still has to declare the dependency.

  • If that's the case you just need not declare the integration-test artifact dependency in the pom.xml for this module.

I also have to make the module containing com.adam.testutil.IntegrationTest the first module in the build order, otherwise it won't be available in first-time installs on any new systems

  • Reactor sorting takes care of the order of building the modules within a project wherein the dependent modules are build after the successful build of the modules they depend on. You get to know more about it here. So your integration-test would build prior to any module in the same project that depends on it.

In fact I don't particularly want to create a new module just to provide IntegrationTest. It would be so much simpler if JUnit had included a suitable org.junit.IntegrationTest class in the library.

So is there a handy interface out there somewhere? I can just put a dependency on it in my parent pom and all will be fine.

  • Unless you expose and prove what IntegrationTest interface is useful for, I doubt that it can be included in the junit lib. And the same for a handy interface out there somewhere, what your interface IntegrationTestis trying to do and is it worth would be the ultimate question.
  • Thereafter if it's feasible to be included(accepted) into any of the test scope libraries, it might be very convenient for you to import that lib's dependency into your parent pom.xml.
  • Until then I would still suggest you can use the integration-test individual module approach.

Upvotes: 0

Related Questions