Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to execute a method once before maven surefire runs tests

I have a test suite which needs to have some setup code to be executed before hand to make sure some data is correct in our database.

We're using the maven surefire plugin to run tests in parallel. ${tests.wildcard} is specified by the profile.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.16</version>
    <configuration>
        <forkCount>4</forkCount>
        <reuseForks>false</reuseForks>
        <includes>
            <include>${tests.wildcard}</include>
        </includes>
    </configuration>
</plugin>

I'd like to be able to run a method only once per entire maven execution before surefire runs my tests in parallel. How can I do that?

like image 733
Andy H. Avatar asked Oct 18 '22 17:10

Andy H.


1 Answers

You could have a special test case which executes your verification code (and fail if the case).

This test case would then be executed by a specific Maven Surefire execution (excluding other tests) and attached to a Maven phase occurring just before the test phase (like process-test-classes): hence, effectively being invoked once per Maven run and before any other test.

Then, the normal test phase would execute any other desired test, excluding the special init test.

An example of such a configuration would be:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.19</version>
    <configuration>
        <excludes>
            <exclude>**/InitTest.java</exclude>
        </excludes>
    </configuration>
    <executions>
        <execution>
            <id>test-init</id>
            <phase>process-test-classes</phase>
            <goals>
                <goal>test</goal>
            </goals>
            <configuration>
                <test>InitTest</test>
            </configuration>
        </execution>
    </executions>
</plugin>

Note the global configuration for any Surefire execution would exclude the special init test. Then an additional execution would be executed (before the test phase) and would run only the init test (using the <test> element, which takes priority over any other include/exclude).

As such you would have the following flow:

  • Execute special init test and verify data into database (and fail if required)
  • Execute any other test

Update
Note that you can achieve the same and perhaps in a more semantically correct way by overriding the default surefire test execution (having default-test execution id) to run the special test (and exclude the others) and then add another surefire execution for the rest (as described above as global configuration, this time as specific execution configuration).
With this approach everything would be attached to the test phase, that's why it would be semantically more correct, although a little bit more verbose in the pom.

like image 129
A_Di-Matteo Avatar answered Nov 15 '22 06:11

A_Di-Matteo