1

I have a module in my Java project with multiple integration tests. Two of them are UpgradeDatabase.java and CreateDatabase.java which are currently executed at each run in the pre-integration phase. I want to schedule these to run only once in a while (let's say monthly) because they take too long to execute (many DBs are created, etc.), How can I achieve this ? My failsafe plugin configuration looks like this (note, the skip.selenium.tests parameter is false):

<plugin>
            <artifactId>maven-failsafe-plugin</artifactId>
            <configuration>
                <forkMode>${tests.forkMode}</forkMode>
                <skip>${skip.selenium.tests}</skip>
                <environmentVariables>
                    ...this area skipped...as it's non important
                </environmentVariables>
                <systemPropertyVariables>
                    <!--<rc.count.firefox>${rc.count.firefox}</rc.count.firefox>-->
                    <selenium.browser>firefox</selenium.browser>
                    <user.home>${env.USERPROFILE}</user.home>
                </systemPropertyVariables>
            </configuration>

            <executions>
                <!--before the tests-->
                <execution>
                    <id>upgrade-the-database</id>
                    <configuration>
                        <includes>
                            <include>**/UpgradeDatabase.java</include>
                        </includes>
                    </configuration>
                    <phase>pre-integration-test</phase>
                    <goals>
                        <goal>integration-test</goal>
                        <goal>verify</goal>
                    </goals>
                </execution>
                <!--before the tests-->
                <execution>
                    <id>recreate-the-database</id>
                    <configuration>
                        <testFailureIgnore>false</testFailureIgnore>
                        <includes>
                            <include>**/CreateDatabase.java</include>
                        </includes>
                    </configuration>
                    <phase>pre-integration-test</phase>
                    <goals>
                        <goal>integration-test</goal>
                        <goal>verify</goal>
                    </goals>
                </execution>

            </executions>
        </plugin>
misha
  • 85
  • 4
  • 13

4 Answers4

1

Have a look at Build Profiles.

In short. Enclose your configuration with:

<profiles>
  <profile>
    <id>monthly</id>

      ... your configuration ...

  </profile>
</profiles>

Add it to your settings.xml if you want it to be activated by default:

<activeProfiles>
    <activeProfile>monthly</activeProfile>
</activeProfiles>

Or activate it on the cmd line:

mvn -P monthly ...
Gerold Broser
  • 14,080
  • 5
  • 48
  • 107
  • Gerold, I don't get your solution here. First, what settings.xml are you reffering? is it %USER_HOME%/.m2/settings.xml OR %M2_HOME%/conf/settings.xml – misha Oct 02 '14 at 12:51
  • @misha Did you read the _complete_ chapter I linked to? Re `settings.xml`: If you want to activate the profile just via the cmd line you don't need this setting in `settings.xml`. This was an extra info, just in case... If you'd like to use this, it depends whether you'd like the config to be available to all or just specific users on a machine, see [Maven, Settings Reference, Quick Overview](https://maven.apache.org/settings.html): _"If both files exists, their contents gets merged, with the user-specific settings.xml being dominant."_ – Gerold Broser Oct 02 '14 at 13:38
  • But I have just one build configuration in my CI environment, so I would still have to manually activate/inactivate the profile in order to setup my environment with new Databases. What I really need is to fully automate this, maybe use some script to check for the first day of month and trigger the execution of the other profile (which includes my UpgradeDatabase.java and CreateDatabase.java tests) – misha Oct 02 '14 at 14:12
0

If you are using TestNG, I would suggest to handle this via test groups.

You can specify for each test into which group/groups the test belong (e.g. @Test(groups = { "SlowIntegrationTest" })). Than when you are running the maven you can specify what groups should be executed (e.g. clean test -Dgroups=UnitTest,IntegrationTest).

Of course this involves discipline from developers to mark tests properly. But if anybody forgets to mark the test, it wouldn't be executed and it should come up in coverage stats for particular module (This falls down to quality of your CI process).

luboskrnac
  • 23,973
  • 10
  • 81
  • 92
0

You can move the DB setup / upgrade code into a new module. Then you can use build profiles to hide this new module in the standard build (i.e. when you invoke Maven without a profile). On your CI server, you can run Maven once in a while (maybe every night) with -P name to enable the profile name which should include the new module.

Note that Maven executes modules in the order that you specify unless they depend on each other. In the second case, Maven will reorder the modules to make sure that dependencies are built, first.

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
  • Just because I'm curious: Why do you suggest a move to a new module? If I don't activate a profile, its configuration isn't active no matter where the thing the configuration refers to is located. – Gerold Broser Sep 30 '14 at 15:19
  • It's just another option. I prefer modules when the config for the plugins is complex (i.e. to keep the XML simple) or when I want to separate things which simply don't belong into the same module (like unit tests and integration tests). – Aaron Digulla Oct 01 '14 at 08:15
0

@misha Re your comment to my previous answer:

  1. Pure external Maven profile activation:

    Make the regular build job parameterized with a parameter PROFILE, for instance, and an empty parameter value (or just a space character if an empty value isn't supported) as default. Add this parameter to your mvn cmd line:

    mvn ${PROFILE} ...

    Such, an empty (or space) value is added to your cmd line doing...nothing.

    Create a monthly build job that triggers the regular and injects this parameter with a value of -P monthly, so that your regular build's cmd line becomes:

    mvn -P monthly ...
  2. Mixed external and POM internal Maven profile activation:

    See 5.3. Profile Activation or Introduction to Build Profiles, Details on profile activation.

    Add an activation section to your profile like:

    <activation>
      <property>
        <name>monthly</name>
      </property>
    </activation>

    ... and supply your regular build's mvn cmd line with an appropriate property:

    mvn -D monthly ...

    ... using the method of 1. above, for instance.

Community
  • 1
  • 1
Gerold Broser
  • 14,080
  • 5
  • 48
  • 107
  • I created a profile which overrides the failsafe plugin and additionally executes the initialization tests, but in TeamCity there is no way I can activate that profile based on a monthly schedule i.e. I can trigger the monthly build but can not inject that parameter -P monthly. Note that I'm using TeamCity 8.1.3 – misha Oct 06 '14 at 09:01
  • @misha I'm sorry. I'm not familiar with TeamCity. I think this is worth a new question. – Gerold Broser Oct 09 '14 at 10:32