How can I get maven-release-plugin to skip my tests? - maven

How can I get the maven-release-plugin to run without triggering the tests?
I have tried
-Dmaven.test.skip=true
and
-DskipTests
and
-DpreparationGoals=clean
...yet none work.
Yes, I know I shouldn't release if the tests don't pass, but I don't have control over making my coworkers write reliable tests.

-Darguments="-DskipTests" is what you want, or explicitly configuring the forked executions in the pom.

-Darguments="..." passes arguments to the forked maven process, but it is important to realise that there are two different switches being used here. The -DskipTests forces maven to not run any tests, but the tests are still compiled (this is important if you have any dependencies on a test-jar type). The -Dmaven.test.skip=true forces maven to not even compile the tests, which means that any test-jars will not be generated.
So, you must use -Darguments, but to skip tests running use only skipTests, to stop them compiling use maven.test.skip.

If you just want to skip integration tests, this will do it:
-Darguments="-DskipITs"

you have too differents choices to avoid and skip tests with the release plugin
The first is to pass as argument on cli to the release goal or phases by providing a -Darguments:
exemple: mvn -X -Darguments="-Dmaven.javadoc.skip=true -Dmaven.test.skipTests=true -Dmaven.test.skip=true" -P release-mode release:prepare
-The second is to perform thoses arguments on your pom.xml in the build like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.apache.maven.scm</groupId>
<artifactId>maven-scm-provider-gitexe</artifactId>
<version>1.9.4</version>
</dependency>
</dependencies>
<configuration>
<skip>true</skip>
<skipTests>true</skipTests>
<preparationGoals>clean validate</preparationGoals>
<arguments>-Dmaven.javadoc.skip=true -Dmaven.test.skipTests=true -Dmaven.test.skip=true</arguments>
<useReleaseProfile>false</useReleaseProfile>
<releaseProfiles>release-mode</releaseProfiles>
<tagNameFormat>TEST-#{project.version}</tagNameFormat>
</configuration>
</plugin>
Note that the second method override the first.
I recommanded you to prepare release first on a single action and then you can edit the release.properties file on the working directorie and look the exec.additionalArguments properties if your arguments are there. It will look like: exec.additionalArguments=-Dmaven.javadoc.skip\=true -Dmaven.test.skipTests\=true -Dmaven.test.skip\=true -P release-mode.
After you can perform the release.

I have managed to avoid running the verify goal by simply adding the configuration preparationGoals to clean:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version>
<configuration>
<preparationGoals>clean</preparationGoals> <!-- See here -->
</configuration>
</plugin>

Use the following argument to skip test
-Darguments="-DskipTests"
or
alternatively skipping by default
[...]
<properties>
<skipTests>true</skipTests>
</properties>
[...]

Related

Can maven exec:java be used with an arbitrary java class from the command iine

We have a few java/scala classes with main methods that would be useful to run via mvn exec:java.
Is it possible to do so without specifying the classes in the pom.xml? The examples that I have seen look like this:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<executions><execution>
<goals><goal>java</goal></goals>
</execution></executions>
<configuration>
<mainClass>some.main.MyClass</mainClass>
</configuration>
</plugin>
And then get executed as:
mvn exec:java -Dexec.mainClass="some.main.MyClass"
The intent is to be able to run
mvn exec:java -Dexec.mainClass="some.other.main.OtherClass"
even though it were not specified in the pom.xml.
When attempting to run that the error is
[ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.6.0:java (default-cli) on project sentiment: An exception occured while executing the Java class. myapp.MyMain
In other words the class specified on the command line is ignored in favor of the one listed in the pom.xml.
The Documentation at https://www.mojohaus.org/exec-maven-plugin/usage.html
says:
If you want to execute Java programs in the same VM, you can either
use the command line version
mvn exec:java -Dexec.mainClass="com.example.Main" [-Dexec.args="argument1"]
This works without adding anything to your pom.
As written in the comment, this only works, if you don't have a configuration in your pom. If you do have a configuration in your pom, you can use a property in it, which can be overridden from the command line
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<executions><execution>
<goals><goal>java</goal></goals>
</execution></executions>
<configuration>
<mainClass>${my.mainClass}</mainClass>
</configuration>
</plugin>
and predefine the property (nested directly in <project>)
<properties>
<my.mainClass>some.main.MyClass</my.mainClass>
</properties>
then you can run with
mvn exec:java -Dmy.mainClass="aaa.Test"
Looking from your usage if you are using the -Dexec.mainClass everytime, i would suggest you can get rid of the mainClass in the plugin configuration. The benefit of defining the mainClass would be to run like : mvn exec:java & it picks the main class from your defined class in pom.xml.
Once you remove the mainClass from pom.xml, you should be able to use any mainClass in the maven exec plugin usage from command line.

Maven : Child pom's argline is not applied?

I have a multi-module maven project. In the child module, failsafe plugin is used for the integration tests run. Some argLines are defined accordingly :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<skipAfterFailureCount>1</skipAfterFailureCount>
<argLine>-Xmx2048M -Xss512M -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC</argLine>
</configuration>
</plugin>
The problem is when I run the tests as mvn test or mvn integration-test, the arglines are not applied for the tests from neither the parent pom directory nor the child pom directory, but if I run the tests as mvn failsafe:integration-test from both of the directories, the arglines param are applied.
What is the reason behind this ? Is there any way to apply those params when I run the tests with mvn test command ? I tried to pass the parameters via command line as mvn test -Dchild.argline="-Xmx2048M -Xss512M -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC"
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<skipAfterFailureCount>1</skipAfterFailureCount>
<argLine>${child.argline}</argLine>
</configuration>
</plugin>
But it didn't work.
Also I tried to bind test and integration-test phases to failsafe integration-test and defined configuration params there, but it didn't work as well..
I set the MAVEN_OPTS accordingly but it didn't help...
The failsafe plugin goals are not included in the lifecycle by default. The POM configuration must include it. See this SO answer for an example. Also ensure that the plugin definition is in the <plugins> section, not inside a <pluginManagement> element.
As for how to define options in the POM - use the names supplied in the documentation. So, to specify argLine, add
<argLine>...</argLine>
in the plugin config. To specify on the command line, note that "User property" for the value you want to set. For the failsafe plugin's argLine, the user property is also argLine, so on the command line specify
-DargLine=...
Maven knows nothing about child.argline so silently ignores it. Also note, attribute and user property names are case sensitive.

Maven skip specific test [duplicate]

In my maven project I have a number of modules. Is it possible to turn off running unit test for some modules via command line options?
My project takes about 15 mins to run through all unit tests. I would like to speed up the overall build by running just the unit tests in the module I am working on. I do not want to go in and edit each individual pom.xml to achieve this.
I have tried a solution outlined here: Can I run a specific testng test group via maven? However the result is a lot of test failures in modules that I want to skip. I suppose 'group' is not the same concept of module?
To toggle unit tests on and off for an entire project use Maven Surefire Plugin's capability of skipping tests. There is a drawback with using skipTests from the command line. In a multi-module build scenario, this would disable all tests across all modules.
If you need more fine grain control of running a subset of tests for a module, look into using the Maven Surefire Plugin's test inclusion and exclusion capabilities.
To allow for command-line overrides, make use of POM properties when configuring the Surefire Plugin. Take for example the following POM segment:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.9</version>
<configuration>
<excludes>
<exclude>${someModule.test.excludes}</exclude>
</excludes>
<includes>
<include>${someModule.test.includes}</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<someModule.skip.tests>false</someModule.skip.tests>
<skipTests>${someModule.skip.tests}</skipTests>
<someModule.test.includes>**/*Test.java</someModule.test.includes>
<someModule.test.excludes>**/*Test.java.bogus</someModule.test.excludes>
</properties>
With a POM like the above you can execute tests in a variety of ways.
Run all tests (the above configuration includes all **/*Test.java test source files)
mvn test
Skip all tests across all modules
mvn -DskipTests=true test
Skip all tests for a particular module
mvn -DsomeModule.skip.tests=true test
Only run certain tests for a particular module (this example includes all **/*IncludeTest.java test source files)
mvn -DsomeModule.test.includes="**/*IncludeTest.java" test
Exclude certain tests for a particular module (this example excludes all **/*ExcludeTest.java source files)
mvn -DsomeModule.test.excludes="**/*ExcludeTest.java" test
Found a way to exclude on command line:
# Exclude one test class, by using the explanation mark (!)
mvn test -Dtest=!LegacyTest
# Exclude one test method
mvn verify -Dtest=!LegacyTest#testFoo
# Exclude two test methods
mvn verify -Dtest=!LegacyTest#testFoo+testBar
# Exclude a package with a wildcard (*)
mvn test -Dtest=!com.mycompany.app.Legacy*
This is from: https://blog.jdriven.com/2017/10/run-one-or-exclude-one-test-with-maven/
…and if you like to pass the parameter to maven release plugin in Hudson/Jenkins you have to use
-Darguments=-DskipTests
to get it work.
If you want to use Maven profiles:
http://maven.apache.org/guides/introduction/introduction-to-profiles.html
you might want to make it work doing something like this:
Skipping tests in some modules in Maven
I don't know if there is a supported command line option that does the same.
You also might try using environment properties directly, something as per this doc page:
http://maven.apache.org/plugins/maven-surefire-plugin/examples/skipping-test.html
i.e. something like:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12</version>
<configuration>
<skipTests>${moduleA.skipTests}</skipTests>
</configuration>
</plugin>
then using mvn -DmoduleA.skipTests=false test to test that one module.

Setting Maven for scripting languages?

Maven is for building and managing any Java-based project. But what happens if a project is in a scripting language?
All maven can do now with TCL is copy the files around and put them in the right place in the target directory.
My problems are as follows:
Code is in TCL-> need of an interpreter not of a compiler.
It doesn't see any Java code, so it doesn't compile anything.
It doesn't see any Java tests, so it doesn't run them.
There's no java to run coverage against, so the jococo won't have anything to do.
Is there any way to set up maven for supporting a TCL project?
I've searched a lot in the internet and I found only 'jacl', but I don't really know how I can use it for setting up Maven.
Tcl isn't closely integrated with Maven (unlike Java) so you'll have to do more work. To run a Tcl script from Maven, the simplest way is to use the Exec Maven Plugin, but you have to bind the executions to explicit lifecycle phases yourself instead of relying on defaults. For example, to run a script during the test phase (i.e., to do tclsh testscript.tcl anotherArgument), you use:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<id>run-tcl-tests</id>
<phase>test</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>tclsh</executable>
<arguments>
<argument>testscript.tcl</argument>
<argument>anotherArgument</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Maven's long-winded! Don't forget that you can probably put much of the complexity in a parent POM, and you can use properties and profiles to do interesting things.
You can also use the java goal to run Jacl or jTcl interpreters (in a sub-process). It depends on what exactly you want to do.
Unless you're using jTcl I don't see what Maven will do, apart from complicate your build process. Unless you understand Maven well and can develop some supporting plugins. As you've pointed out TCL is a scripting language, meaning your real challenge is a run-time deployment problem.
So, how would a TCL build process make deployment simpler? I would propose building RPM, Debian or MSI package for each targeted environment. These native installers can use dependency management to ensure the TCL interprertor is also installed. Another useful build option are starkits, which would bundle the TCL interpretor in a single file.
Once built, these binaries can be stored in your Maven repository (like jar files) and used as part of your deployment process. And finally don't forget you are not forced to use Maven as your build tool.
Disclaimer: Been a while since I've programmed with TCL, so hope this helps.
It is very much "not the maven way" to make dependencies on external build tools outside the maven ecosystem. Linking to tclsh will break your builds if tclsh isn't available. Not saying I haven't done worse (sometimes you just have to get it done and forget "the maven way"). Fortunately, there is an alternative - jacl.
First download the latest (probably 1.4.1) prebuilt jacl binary zip file from sourceforge.
Next, unzip and go into the lib/tcljava1.4.1 subdirectory. There are four jar files here you need to publish to your local repository (or another repo you use):
mvn install:install-file -Dfile=tjc.jar -DgroupId=jacl -DartifactId=tjc -Dversion=1.4.1 -Dpackaging=jar
mvn install:install-file -Dfile=tcljava.jar -DgroupId=jacl -DartifactId=tcljava -Dversion=1.4.1 -Dpackaging=jar
mvn install:install-file -Dfile=jacl.jar -DgroupId=jacl -DartifactId=jacl -Dversion=1.4.1 -Dpackaging=jar
mvn install:install-file -Dfile=itcl.jar -DgroupId=jacl -DartifactId=itcl -Dversion=1.4.1 -Dpackaging=jar
You'll also need to add these as dependencies to the project where you're calling the tcl script:
<dependency>
<groupId>jacl</groupId>
<artifactId>itcl</artifactId>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>jacl</groupId>
<artifactId>jacl</artifactId>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>jacl</groupId>
<artifactId>tcljava</artifactId>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>jacl</groupId>
<artifactId>tjc</artifactId>
<version>1.4.1</version>
</dependency>
Then just call the tcl (or really jacl) script using the exec goal of the exec-maven-plugin, passing in the script file path as the first argument (customize the execution as necessary to bind to the proper phase, etc.):
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.3</version>
<executions>
<execution>
<id>runTcl</id>
<phase>process-resources</phase>
<goals><goal>exec</goal></goals>
<configuration>
<executable>java</executable>
<arguments>
<argument>-Dbasedir=${basedir}</argument>
<argument>-classpath</argument>
<classpath/>
<argument>tcl.lang.Shell</argument>
<argument>${basedir}/src/main/scripts/myScript.tcl</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
Update: Note that I had to use the "exec" goal above instead of the java goal. That's because jacl calls System.exit() in it's main function, so it kills the jvm. With this config, you can fail the build by using:
package require java
java::call System exit 1
From within your tcl code (or any exit value other than zero or other successCodes configured in the plugin). Hope that helps.

How to run a maven goal when there is tests failures?

I would like to know if there is a way to execute a goal when there is test failures?
Since maven stops its execution (fail fast mode) after encountering a test failure, is there any options to launch a goal when there is test failures?
Regards.
I've been searching for a way to do this as well, with not much success.
However, there is the following question which might provide some general hints:
Maven reporting plugins do not execute if a unit test failure occurs
The idea is that you would run mvn install (or whatever) first, and then run:
mvn -Dmaven.test.skip=true your-plugin:your-goal
This will let you run the build again without running tests, preserving the results for your perusal. Of course, this is only useful if your plugin is parsing the test results...
Though not recommended, by setting the surefire property testFailureIgnore to true, you can continue maven execution even when there are test failures.
...
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.11</version>
...
<configuration>
<testFailureIgnore>true</testFailureIgnore>
...
</configuration>
</plugin>
...
Just do mvn clean install -DskipTests
I added this plugin in pom.xml and it worked well.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<testFailureIgnore>true</testFailureIgnore>
</configuration>
</plugin>
If you want to the build to run KNOWING beforehand that there are going to be failures, you can use:
mvn <goal> -Dmaven.test.skip = true

Resources