Passing threadCount to surefire plugin from maven cmdline - maven

I have in my pom the following settings for maven surefire plugin.
Occasionally I might want to run the tests with less threads. I was hoping for a way to set it from the mvn command line.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>2.22.0</version>
</dependency>
</dependencies>
<configuration>
<parallel>methods</parallel>
<threadCount>5</threadCount>
<includes>
<include>com.Online.runner.Regression.ONLINE_Chrome_RunnerTest</include>
</includes>
</configuration>
</plugin>
When I attempt to use the command below it doesn't appear to work.
mvn clean test -X -DthreadCount=1
Checking the values through the debugger shows that has set a system property. But it seems to get ignored.
[DEBUG] Setting system property [threadCount]=[1]
[DEBUG] parallel='methods', perCoreThreadCount=true, threadCount=5,
My tests still run in parallel. What am I doing wrong? there must be a way to override this value in the Pom?
EDIT: It seems as though it is completely ignoring the threadCount value altogether even the one set in the POM. Is this value not passed to the dependency Junit47?

In order for it to work, remove it with pom.xml:
<threadCount> 5 </threadCount>
Maven startup line:
mvn test -DthreadCount=5

Related

running secbugs maven plugin from command line/ maven plugin configuration parameters in command line

maybe this is a generic question with regards to how to transfer maven plugin paramters from the pom.xml to the commandline, but I have usually done this without problems using the method below. For the find-security-bugs plugin, however, it is not working.
The find-security-bugs plugin docu says that you can configure the plugin in your pom.xml as follows:
<plugins>
[...]
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
<version>4.7.2.1</version>
<configuration>
<includeFilterFile>spotbugs-security-include.xml</includeFilterFile>
<plugins>
<plugin>
<groupId>com.h3xstream.findsecbugs</groupId>
<artifactId>findsecbugs-plugin</artifactId>
<version>1.12.0</version>
</plugin>
</plugins>
</configuration>
</plugin>
</plugins>
I would like to do the same, but cannot do any changes to the pom.xml I'm testing, so would have to specify everything in the command line.
I'm running (from powershell, therefore the quotation marks):
mvn com.github.spotbugs:spotbugs-maven-plugin:4.7.2.1:check -"Dplugins.plugin.groupId=com.h3xstream.findsecbugs" -"Dplugins.plugin.artifactId=findsecbugs-plugin" -"Dplugins.plugin.version=1.12.0" -"DincludeFilterFile=secbugsfilter.xml"
but the parameters are not used. Is there any way to run a plugin with a configuration like this from the command line without specifying anything in the pom?

Surefire system property not being set

I'm trying to get our Mule tests to run with verbose exceptions, but I cannot get the surefire plugin to set the appropriate system property correctly, here is my surefire config:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<systemPropertyVariables>
<mule.verbose.exceptions>true</mule.verbose.exceptions>
</systemPropertyVariables>
</configuration>
Now if I run maven with the command -Dmule.verbose.exceptions=true it prints verbose exceptions, but will not if I do a simple mvn test. Why are my system properties being ignored here?
I haven't checked the code but it could be caused by a static check that is performed previous to the surefire initialization. I would rather try the special variables mechanism described in the documentation.

Sending email with attachment using Maven

Using surefire plugin and postman plugin, I am able to generate a surefire report and send email to a recipient. But the surefire report (html) is not getting attached with the email. Recipient is getting an email without the attachment. If I run the project again, email has been delivered with the attachment. Following is my pom.xml. I don't know what I am missing. Please help.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.testing.example</groupId>
<artifactId>SampleExample</artifactId>
<packaging>jar</packaging>
<name>SampleExample</name>
<version>1.0.0</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>ch.fortysix</groupId>
<artifactId>maven-postman-plugin</artifactId>
<version>0.1.6</version>
<executions>
<execution>
<id>send_an_mail</id>
<phase>test</phase>
<goals>
<goal>send-mail</goal>
</goals>
<inherited>false</inherited>
<configuration>
<from>xxxxxxxxxx</from>
<subject>this is a test auto email sent from Eclipse using Maven</subject>
<htmlMessage>
<![CDATA[
<p>Hi, Please find attached.</p>
]]>
</htmlMessage>
<failonerror>true</failonerror>
<mailhost>smtp.gmail.com</mailhost>
<mailport>465</mailport>
<mailssl>true</mailssl>
<mailAltConfig>true</mailAltConfig>
<mailuser>xxxxxxx</mailuser>
<mailpassword>xxxxxxx</mailpassword>
<receivers>
<receiver>xxxxxxxxx</receiver>
</receivers>
<fileSets>
<fileSet>
<directory>${basedir}/target/site</directory>
<includes>
<include>**/surefire-report.html</include>
</includes>
</fileSet>
</fileSets>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-report-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<testFailureIgnore>true</testFailureIgnore>
</configuration>
</plugin>
</plugins>
</reporting>
</project>
Generally, I find that it is more helpful to get a Maven build working from the command line before attempting to introduce Eclipse.
Do you have a remote repository set up (e.g. Nexus, Artifactory)? If not, it would be good to have that in place if you are going to continue to use Maven regularly. Once the remote repo exists, then you will need to configure the project's distributionManagement element in order to publish artifacts to that repository.
Now, back to your original question. surefire-report:report is a report goal, and runs as part of the reporting lifecycle by default. As you have it configured, it is not related to the build lifecycle in any way. In your POM, the postman plugin is bound to the test phase, which is part of the default lifecycle.
When you run command mvn surefire-report:report per the documentation Maven runs the build lifecycle up to and including the test phase. (The key phrase in the documentation is "Invokes the execution of the lifecycle phase test prior to executing itself.").
So, the order of operations when you run mvn surefire-report:report is:
Maven forks a 'mvn test' build behind the scenes
postman:send-mail runs as part of test phase
surefire-report:report creates the reports
Note how the last two steps are out of order. So, the first time you run the command, there are no test reports yet, and thus no attachment. The second time you run it, there are reports from the previous build that get attached.
The question for you becomes, do you plan to run this at the command line once in a while in order to send reports when someone asks for them? If so, then you may simply remove the phase configuration from the postman plugin and use Maven command mvn surefire-report:report postman:send-mail. This will perform the steps in the correct order.
If you want the email to happen every time (i.e. with every mvn clean install site), you need to bind the postman:send-mail goal to a phase that runs after the reports are generated. I would try the site phase. If that doesn't work, then use post-site and change the Maven command to mvn clean install post-site.
P.S. If you're new to Maven, I highly recommend learning about the different lifecycles and the difference between a phase and a goal. You can't really use Maven effectively without that knowledge.
Just change the order of plugin.
Maven compiler plugin
Surefire report plugin
Postman plugin
This will help and you can run it as you wish.

Insert MAVEN_OPTS in the POM.xml

I must increase java heap space to compile my project. The only way I found is modify mvn.bat and set:
set MAVEN_OPTS=-XX:PermSize=256m -XX:MaxPermSize=256m -Xms1300M -Xmx1300M
than all colleagues must change the file localy.
I want keep all inside my project, not localy. Can I insert in the POM.xml or other file?
Setting MAVEN_OPTS usually provides arguments to the JVM running the build, and these are passed down to the compiler because it runs inline. You have probably already noted that the maven-surefire-plugin used for test usually fork a separate process so passing options to the plugin is bound inside the pom.xml.
What if you fork the compilation process also and add the flags there, such as the below example.
Notice the fork and the compiler args
<project>
[...]
<build>
[...]
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<fork>true</fork>
<meminitial>128m</meminitial>
<maxmem>512m</maxmem>
<compilerArgument>-verbose -bootclasspath ${java.home}\lib\rt.jar</compilerArgument>
</configuration>
</plugin>
</plugins>
[...]
</build>
[...]
</project>

Skipping tests in some modules in Maven

I would like my Maven builds to run most unit tests. But there are unit tests in one project which are slower and I'd like to generally exclude them; and occasionally turn them on.
Question: How do I do this?
I know about -Dmaven.test.skip=true, but that turns off all unit tests.
I also know about skipping integration tests, described here. But I do not have integration tests, just unit tests, and I don't have any explicit calls to the maven-surefire-plugin. (I am using Maven 2 with the Eclipse-Maven plugin).
What about skipping tests only in this module ?
In the pom.xml of this module:
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.4.2</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
[...]
</project>
Eventually, you can create a profile that will disable the tests (still the pom.xml of the module) :
<project>
[...]
<profiles>
<profile>
<id>noTest</id>
<activation>
<property>
<name>noTest</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.4.2</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
[...]
</project>
With the latter solution, if you run mvn clean package, it will run all tests. If you run mvn clean package -DnoTest=true, it will not run the tests for this module.
I think this is easier, and also has the benefit of working for non-surefire tests (in my case, FlexUnitTests)
<profile>
<id>noTest</id>
<properties>
<maven.test.skip>true</maven.test.skip>
</properties>
</profile>
If you have a large multi-module project and you would like to skip tests only in certain modules without the need to change each of the module pom.xml file with custom configuration and profiling, you could add the following to the parent pom.xml file:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.12</version>
<executions>
<execution>
<id>regex-property</id>
<goals>
<goal>regex-property</goal>
</goals>
<configuration>
<name>maven.test.skip</name>
<value>${project.artifactId}</value>
<regex>(module1)|(module3)</regex>
<replacement>true</replacement>
<failIfNoMatch>false</failIfNoMatch>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<modules>
<module>module1</module>
<module>module2</module>
<module>module3</module>
</modules>
Thanks to the build-helper-maven-plugin you would actually dynamically check whether you are in a certain module or not during the build, via the project.artifactId property (pointing at each artifactId module during the build), the regex would then seek matching for certain values (the module names for which you want to skip tests) and populated the maven.test.skip property accordingly (setting it to true).
In this case, tests will be skipped for module1 and module3 while running properly for module2, that is, as expressed by the regex.
The advantage of this approach is to have it dynamic and centralized (in the parent pom.xml) hence better for maintenance: you could add or remove modules at any time simply by changing the simple regex above.
Obviously, if this is not the default behavior of the build (recommended case), you could always wrap the snippet above in a maven profile.
You could also go further and have dynamic behavior based on your input:
<properties>
<test.regex>none</test.regex>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.12</version>
<executions>
<execution>
<id>regex-property</id>
<goals>
<goal>regex-property</goal>
</goals>
<configuration>
<name>maven.test.skip</name>
<value>${project.artifactId}</value>
<regex>${test.regex}</regex>
<replacement>true</replacement>
<failIfNoMatch>false</failIfNoMatch>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Here we are actually replacing the regex value with a property, test.regex, with default value to none (or whatever would not match any module name or, also, the default skipping matchings required).
Then from command line we could have
mvn clean test -Dtest.regex="(module1)" > will skip tests only for module1
mvn clean test -Dtest.regex="(module1)|(module2)" > will skip tests on module1 and module2
mvn clean test -Dtest.regex="(module1)|(module2)|(module3)" > will skip the three module tests
mvn clean test -Dtest.regex=".+" > will skip all module tests
mvn clean test > would not skip anything (or fall back on default behavior)
That is, then at runtime you decide, without any need to change the pom.xml file or activating any profile.
Using Surefire Plugin 2.19 you can simply exclude the tests you don't want using regular expressions:
mvn '-Dtest=!%regex[.*excludedString.*]' test
The above command will exclude all the tests that contain excludedString.
NB1 If double quotation mark(") is used instead of apostrophe(') the command will not be interpreted properly and will produce unexpected results. (Tested using bash 3.2.57)
NB2 Particular attention should be paid to projects in which multiple version of the surefire plugin is used. Versions of surefire older than 2.19 will not execute any tests because they do not support regular expressions.
Version management(it might be a good idea to add this in the parent pom file):
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
</plugin>
</plugins>
</pluginManagement>
</build>
Examples of build commands that skip tests: https://artbcode.wordpress.com/2016/11/28/how-to-skip-a-subset-of-the-unit-tests/
I had a slightly different need from this question that may prove helpful. I wanted to exclude from the command line a few different tests from different packages, so a single wildcard would not do it.
I found in the Maven Failsafe documentation rules for exclusions that you can specify a comma-separated list of either regex or wildcard exclusions:
https://maven.apache.org/surefire/maven-failsafe-plugin/examples/inclusion-exclusion.html
So my pomfile looked like this:
<excludes>
<exclude>${exclude.slow.tests}</exclude>
</excludes>
and my command line included this:
mvn install "-Dexclude.slow.tests=**/SlowTest1.java, **/package/ofslowtests/*.java, **/OtherSlowTest.java"
For me the key ingredient was getting a bunch of tests into one maven property in a single exclude statement.

Resources