2

I have a single module project that has some unit tests that require an external hardware device. I don't want these tests to execute unless I indicate that the device is available.

I feel like this is solvable using Maven properties and the SureFire exclusion/inclusion configuration, but I can't quite see how to do it. A similar question shows how to disable/enable all the tests in a project based on a Maven property, but doesn't quite answer my issue.

In summary, I wish to identify a pattern (e.g. **/*ResourceTest.java) that describes the tests I don't want to run, unless I pass a Maven property to enable them.

E.g.

mvn clean install (runs the standard tests, but skips device-related tests)

mvn -Drun.device.tests=true clean install (runs all the tests)

Thanks in advance.

(Edited to remove the misleading usage of the word "resource" > replaced with "hardware device").

Community
  • 1
  • 1
Duncan Jones
  • 67,400
  • 29
  • 193
  • 254

3 Answers3

2

You also can just use the JUnit Assume methods to decide (inside the test) if a test should be executed or skipped.

The best option IMHO would however be to 'declare' the device dependend tests to be "integration tests" and let them be executed by the Maven Failsafe Plugin. I think this would be the "build in" maven solution without any profile 'magic'.

FrVaBe
  • 47,963
  • 16
  • 124
  • 157
  • This is useful to know. I will wait to see if I can use pure Maven configuration to achieve my goal. But failing that, it's clear this would also work, thanks. – Duncan Jones Jul 24 '12 at 11:13
  • It will have the benefit that you can decide in each test if the individual precondition to run the test is given. Nevertheless it should only by the exceptional case to skip tests. – FrVaBe Jul 24 '12 at 11:21
  • 2
    @Duncan Jones Just had the idea that your device dependent test are integration tests that should be run by the failsafe plugin and updated my answer. – FrVaBe Jul 24 '12 at 12:19
  • An excellent suggestion, I think we will use this for our next project. As for now, I will leave the accepted answer with Jean-Rémy as it most directly responds to what I asked for. – Duncan Jones Jul 24 '12 at 13:00
1

The link you provided gave the good answer.

The right way

Use a mix of Profile Management and Surefire Configuration inclusion / exlcusion is the right way.

You should ask yourself WHY you want to activate some tests dependings on a resource. The resource should always been in your classpath.

If not, you probably just want to activate some test manually, for some tricky reasons. In that case consider this is a bad use of Maven (how would you automate that on a distant server for instance ?)

What you asked

If you really really want to do that, because you have some good reasons that we are not aware of, simply use this :

This example will trigger the profile when the generated file target/generated-sources/axistools/wsdl2java/org/apache/maven is missing.

Example from Maven official doc : http://maven.apache.org/guides/introduction/introduction-to-profiles.html

<profiles>
  <profile>
    <activation>
      <file>
        <missing>target/generated-sources/axistools/wsdl2java/org/apache/maven</missing>
      </file>
    </activation>
    ...
  </profile>
</profiles>

As of Maven 2.0.9, the tags and could be interpolated. Supported variables are system properties like ${user.home} and environment variables like ${env.HOME}. Please note that properties and values defined in the POM itself are not available for interpolation here, e.g. the above example activator cannot use ${project.build.directory} but needs to hard-code the path target.

You could find more information here : http://www.sonatype.com/books/mvnref-book/reference/profiles-sect-activation.html

Hope that will help. Don't hesitate to challenge my point of view with you own reasons (even legacy code ;) ) or experience

Jean-Rémy Revy
  • 5,607
  • 3
  • 39
  • 65
  • My usage of the word "resource" was very unfortunate. I will edit my original question, which will hopefully explain what I meant. I may still be able to use your answer to solve my issue (although your specific example will now be redundant - sorry). – Duncan Jones Jul 24 '12 at 11:08
  • Yes, profiles are clearly the answer to my issue. I will mark your answer as accepted, but I'll also post a complete answer showing quite how it worked in my POM. (FYI - background is that I work for a company that produces hardware products. Every project we work with requires our products, hence many of the unit tests assume the presence of the hardware). – Duncan Jones Jul 24 '12 at 11:21
  • @DuncanJones OK, it's quite clear now, and you reasons sounds good to trigger tests like that. Thanks :). I'm waiting for you pom, this subject is quite interesting !! – Jean-Rémy Revy Jul 24 '12 at 13:07
0

To expand on @Jean-Rémy answer, I have done the following in my project POM file:

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-surefire-plugin</artifactId>
      <version>2.12</version>
      <configuration>
        <excludes>
          <exclude>${tests.to.skip}</exclude>
        </excludes>
      </configuration>
    </plugin>
  </plugins>
</build>

<profiles>
  <profile>
    <!-- This profile will be used when running tests without a device -->
    <id>default-profile</id>
    <activation>
      <activeByDefault>true</activeByDefault>
    </activation>
    <properties>
      <tests.to.skip>**/*DeviceTest.java</tests.to.skip>
    </properties>
  </profile>

  <profile>
    <id>device-profile</id>
    <activation>
      <property>
        <name>device</name>
        <value>true</value>
      </property>
    </activation>
    <properties>
      <!-- Unsure how to match nothing -->
      <tests.to.skip>NOTHING</tests.to.skip>
    </properties>
  </profile>

This creates two profiles, the default profile will exclude the device tests, whereas the "device-profile" will execute all tests.

To execute the device profile, one can execute mvn -Ddevice=true test.

Duncan Jones
  • 67,400
  • 29
  • 193
  • 254