4

We're in the middle of developing a big project, with many interacting modules and teams working on said modules. we have implemented CI with jenkins, which does periodic and on-commit builds that run junit tests, fitnesse tests, and cobertura coverage.

Since we're interacting with so many components, for some specific projects we have implemented integration tests, which bring up a Spring context, and run many test cases that simulate significant pieces of the application flow. These are implemented as Junit for simplicity/convenience, are placed in the src/test folders, but are not unit tests.

Our problem is that some component builds are taking very long to run, and one of the identified issues is that the long running integration tests are running twice, once in the test phase and once in the cobertura phase (as cobertura instruments the classes and then runs the tests again). Which leads to the question: is it possible to exclude a test from the cobertura execution?

Using exclude or ignore in the pom cobertura config only works for src/java classes, not the test classes. I couldn't find anything in the cobertura plugin documentation. I'm trying to find a way to do this via configuration. The only other way I think it could be accomplished is to move these tests to another maven module that does not have the cobertura plugin enabled, and have that module be the home of the integration tests. That way the build of the parent pom would trigger the integration tests, but it would not fall under the scope of cobertura. But if it could be done by configuration, it would be so much easier :)

Thanks in advance, JG

==== UPDATE AND RESOLUTION ====

After building a little on kkamilpl's answer (thanks again!) I was able to include and exclude the needed tests without changing anything in the directory structure. With just java style expressions, once you realize that overrides in the surefire plugin setup, you can manage to run "all but a package"/"only that given package" like this:

<profiles>
    <profile>
        <id>unit-tests</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <testcase.include>**/*.class</testcase.include>
            <testcase.exclude>**/integration/*.class</testcase.exclude>
        </properties>
    </profile>
    <profile>
        <id>integration-tests</id>
        <properties>
            <testcase.include>**/integration/*.class</testcase.include>
            <testcase.exclude>**/dummyStringThatWontMatch/*.class</testcase.exclude>
        </properties>
    </profile>
</profiles>

I was able to run all unit tests (that is, everything but the contents of the integration test folder) with test target and default profile, and then invoke target test with the integration-tests profile to just run the integration test. Then it's a matter of adding the call to the new profile in jenkins as a new top level target call (it targets a parent pom) so that the jenkins build will run the integration tests, but only once, instead of having them re-run by cobertura when it uses the test target.

JGN
  • 85
  • 1
  • 8

1 Answers1

2

You can always use maven profiles: http://maven.apache.org/guides/introduction/introduction-to-profiles.html

Separate tests to different directories e.g:

testsType1
    SomeTest1.java
    SomeTest2.java
testsType2
    OtherTest1.java
    OtherTest2.java

Next in pom define proper profile for each test type e.g:

    <profile>
        <id>testsType1</id>
        <properties>
            <testcase.include>%regex[.*/testsType1/.*[.]class]</testcase.include>
            <testcase.exclude>%regex[.*/testsType2/.*[.]class]</testcase.exclude>
        </properties>
    </profile>

To define the default profile:

        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>

And finally define surefire plugin:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>>
            <configuration>
                <includes>
                    <include>${testcase.include}</include>
                </includes>
                <excludes>
                    <exclude>${testcase.exclude}</exclude>
                </excludes>
            </configuration>
        </plugin>

To use it call

 mvn test #to use default profile
 mvn test -P profileName #to use defined profileName
kkamil
  • 2,593
  • 11
  • 21