I'm in the need to run integration tests one by one with the failsafe plugin (please, don't ask why... They just have to run in individual jvms, one good reason for avoiding singletons).
So I'd like to create a script with one maven call per line where each maven call runs tests on a single test file. Something like this:
mvn failsafe:integration-test -D<???>=**/ITest1.java
mvn failsafe:integration-test -D<???>=**/ITest2.java
mvn failsafe:integration-test -D<???>=**/ITest3.java
...
In a pom.xml I'd add something like
<includes>
<include>**/ITest1.java</include>
</includes>
to the plugins configuration. Is there a way to achieve the same with the command line? Is it possible to specify list-like configuration options?
The syntax is:
mvn -Dit.test=TestName verify
Source: Failsafe Plugin Examples: Running a Single Test
The it.test parameter does that. You can read about it here.
From the docs:
[...] so you can just type "-Dit.test=MyTest" to run a single test called "foo/MyTest.java".
Related
I have these properties in my application.properties:
spring.datasource.url=jdbc:postgresql://localhsost:5432/myDatabase
spring.datasource.username=myUsername
I would like to run mvn test with other values than the above, for example:
spring.datasource.url=jdbc:postgresql://my.test.server.com:5432/myDatabase
spring.datasource.username=anotherUsername
I tried the following
mvn test -Drun.arguments='--spring.datasource.jdbc:postgresql://my.test.server.com:5432/myDatabase --spring.datasource.username=anotherUsername'
and without spring prefix:
mvn test -Drun.arguments='--datasource.jdbc:postgresql://my.test.server.com:5432/myDatabase --datasource.username=anotherUsername'
But this does not seem to work. How can I override the values in the application.properties in context of running mvn test?
Something like this should work:
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20.1</version>
<configuration>
<systemPropertyVariables>
<spring.datasource.jdbc>value</spring.datasource.jdbc>
</systemPropertyVariables>
</configuration>
</plugin>
But more often we do this by placing a test version of application.properties into the src/test/resources. During testing, that file will have greater priority.
When overriding parameters in the command line, use a comma as separator, not a space:
mvn test -Drun.arguments='--spring.datasource.url=...,--spring.datasource.username=...'
This should work too:
mvn test -Dspring.datasource.url=... -Dspring.datasource.username=...
Edit from april 2021
The syntax above was valid for Spring Boot 1.X.
With Spring Boot 2.0/2.1, use:
mvn test -Dspring-boot.run.arguments='--spring.datasource.url=...,--spring.datasource.username=...'
And with Spring Boot 2.2, the syntax was changed again (use a whitespace as separator):
mvn test -Dspring-boot.run.arguments='--spring.datasource.url=... --spring.datasource.username=...'
Other answers and comments mention using profiles and put a custom application.properties in /src/test/resources, which is not a viable solution for you since you use different pipelines, but if I remember correctly, you can even use application-{profile}.properties in /src/test/resources. This way you should be able to maintain one test profile per pipeline, where you put your custom parameters, and then test your pipeline with:
mvn test -Dspring.profiles.active=foobar
Option 1 (preferred as is Maven structure-specific)
Create an application.properties under the test/resources to be picked up for your testing purposes
Option 2 (Spring Test fine-tuning a particular Test class alone)
Override your properties directly on the Test class by inlining the ones you want by using #TestPropertySource
Option 3 (Spring Boot - multiple properties files or a single YAML file)
Group the props under a Spring Profile (Example here) and invoke it directly from maven: mvn test -Dspring.profiles.active="myOtherSpringProfile"
Create another application-dev.properties file and paste:
spring.datasource.url=jdbc:postgresql://my.test.server.com:5432/myDatabase
spring.datasource.username=anotherUsername
Then run with the option -Dspring.profiles.active=dev in your mvn command.
E.g.: mvn test -Dspring.profiles.active=dev
You can add as many profiles as needed.
syntax: application-<profile name>.properties
I don't see many people using the environment variable option. If you set an environment variable for corresponding properties, then the value in the environment variable will be used. e.g.
Environment variables:
SPRING_DATASOURCE_URL="jdbc:postgresql://my.test.server.com:5432/myDatabase"
SPRING_DATASOURCE_USERNAME=anotherUsername
Inside the properties file:
spring.datasource.url=jdbc:postgresql://localhsost:5432/myDatabase
spring.datasource.username=myUsername
The application will use the values in the environment variables. For this to work you'll need to follow the naming convention. Use uppercase and replace "." with "_".
I'm running some service testing using restassured and cucumber and they work fine locally just using Maven test.
The issue is if I run Maven clean, then I must run Maven update or it will not work (Says it can't find my Cucumber feature files). For reference it says:
No features found at [classpath:classpath/classpath]
This wouldn't be a huge issue except I need to have this running through Bamboo where I can't call Maven update.
So I either need to figure out what is wrong with my POM to begin with to cause this issue, or how I can run Maven update through the goals/environment variables.
The POM is fairly simple, only having the needed dependencies/reporting stuff.
The build part of the POM is as follows:
<build>
<finalName>Test</finalName>
<directory>target</directory>
<outputDirectory>target/classes</outputDirectory>
<testOutputDirectory>target/test-classes</testOutputDirectory>
<sourceDirectory>src/main/java</sourceDirectory>
<testSourceDirectory>src/test/java</testSourceDirectory>
<resources>
<resource>
<directory>src/test/resources</directory>
</resource>
</resources>
</build>
This is all in Java 8 using Eclipse as the IDE.
I would avoid specifying anything in the build section in my pom and instead use the default values.
That is, I would keep my feature files in the same package as the runner or a sub package.
The runner could for example live in the package se/thinkcode/tage
As in the directory:
./test/java/se/thinkcode/tage
This means that the feature files should live in the directory:
./test/resources/se/thinkcode/tage
This would allow me to minimize the configuration in the runner. I typically use runners that looks like this:
package se.thinkcode.tage;
import cucumber.api.junit.Cucumber;
import org.junit.runner.RunWith;
#RunWith(Cucumber.class)
public class RunCukesTest {
}
This is the smallest configuration possible if you want to run Cucumber using JUnit from Maven.
It is even smaller that the example supplied by the Cucumber team: https://github.com/cucumber/cucumber-java-skeleton
Looks like defining the features/glue in the cucumber options fixed this.
I do believe there is a better option though.
I added the following cucumber options:
features ="src/test/java",
glue = "packagename",
Is there any way to input arguments when launching spring-boot application (mvn spring-boot:run) from commandline and then get them in main()?
Looking at the source code of the spring-boot-maven-plugin I found that you need to do:
mvn spring-boot:run -Drun.arguments="arg1,arg2"
Another way to get more information about what options the run goal of the spring-boot plugin supports is to execute the following command:
mvn help:describe -Dcmd=spring-boot:run -Ddetail
For Spring Boot 2.x, the source is here and you now need to use -Dspring-boot.run.arguments="args1,args2"
(edit from april 2021)
For Spring Boot 2.2+, you now need to use -Dspring-boot.run.arguments="args1 args2"
If you are using Gradle and you want to be able to pass command line arguments to the Gradle bootRun task, you first need to configure, for example like so:
bootRun {
if ( project.hasProperty('args') ) {
args project.args.split('\\s+')
}
}
and run the task using gradle bootRun -Pargs="arg1 arg2"
When passing multiple arguments using -Drun.arguments, if the argument in turn has 'comma-separated' values, then only the first value of each argument is used. To avoid this repeat the argument as many times as the number of values.
This is more of a workaround. Not sure if there is an alternative unless the delimiter is different - like '|'.
E.g Issue:
mvn spring-boot:run -Drun.arguments="--spring.profiles.active=test,dev"
Picks only 'test' profile for the above command.
Workaround:
mvn spring-boot:run -Drun.arguments="--spring.profiles.active=test,--spring.profiles.active=dev"
Picks both 'dev' & 'test' profiles for the above command.
Be aware : The way of passing arguments depends on the spring-boot major.minor version.
TLDR
For Spring Boot 1:
mvn spring-boot:run -Drun.arguments="argOne,argTwo"
For Spring Boot 2.0 and 2.1:
mvn spring-boot:run -Dspring-boot.run.arguments="argOne,argTwo"
(edit from april 2021)
For Spring boot 2.2 and later:
mvn spring-boot:run -Dspring-boot.run.arguments="argOne argTwo"
spring-boot-maven-plugin version and the the Spring Boot version you use has to be aligned.
According to the Spring Boot major version used (1 or 2), the spring-boot-maven-plugin in the 1 or the 2 version should indeed be used.
If your pom.xml inherits from the spring-boot-starter-parent :
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>ONE_OR_TWO_VERSION</version>
</parent>
In your pom, the version of the plugin used should not even be specified as this plugin dependency is inherited :
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
...
</configuration>
</plugin>
</plugins>
In case of your pom.xml not inheriting from spring-boot-starter-parent, don't forget to align the version of spring-boot-maven-plugin with the exact version of spring boot you want to use.
Passing arguments in command line with spring-boot-maven-plugin:1.X.X
For one argument :
mvn spring-boot:run -Drun.arguments="argOne"
for multiple :
mvn spring-boot:run -Drun.arguments="argOne,argTwo"
The maven plugin page documents it :
Name Type Since Description
arguments | String[] | 1.0 | Arguments that should be passed
to the application. On command line use
commas to separate multiple arguments.
User property is: run.arguments.
Passing arguments in command line with spring-boot-maven-plugin:2.X.X
For one argument :
mvn spring-boot:run -Dspring-boot.run.arguments="argOne"
for multiple :
mvn spring-boot:run -Dspring-boot.run.arguments="argOne,argTwo"
I didn't find the plugin documentation for the 2.X.X version that refers to that.
But the org.springframework.boot.maven.AbstractRunMojo class of the spring-boot-maven-plugin:2.0.0.M3 plugin refers to this user property:
public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo
...
#Parameter(property="spring-boot.run.arguments")
private String[] arguments;
...
protected RunArguments resolveApplicationArguments(){
RunArguments runArguments = new RunArguments(this.arguments);
addActiveProfileArgument(runArguments);
return runArguments;
}
...
}
Hint : as you pass more than one argument, whitespaces between commas are considered.
mvn spring-boot:run -Dspring-boot.run.arguments="argOne,argTwo"
will be interpreted as ["argOne", "argTwo"]
But this :
mvn spring-boot:run -Dspring-boot.run.arguments="argOne, argTwo"
will be interpreted as ["argOne", " argTwo"]
(edit from march 2021)
Whitespaces are now used as separator for multiple-arguments commands, see the relevant issue.
As I checked today, the correct usage for Spring Boot 2.2.5 is:
mvn spring-boot:run -Dspring-boot.run.arguments="--arg1=value --arg2=value"
Because help says:
commandlineArguments
User property: spring-boot.run.arguments
Arguments from the command line that should be passed to the application.
Use spaces to separate multiple arguments and make sure to wrap multiple
values between quotes. When specified, takes precedence over arguments.
Spring Boot 1 as 2 provide a way to pass multiple profiles as argument and avoid the issue related to the comma used both as separator between the args and the values passed as active profile.
So instead of writing :
mvn spring-boot:run -Dspring-boot.run.arguments=--spring.profiles.active=test,--spring.profiles.active=dev
use the Spring Boot Maven profiles property that is a convenience shortcut of spring.profiles.active such as the followings :
The Maven user property is different according to the Spring Boot version.
For Spring Boot 1.4+, that is run.profiles :
mvn spring-boot:run -Drun.profiles=dev,test
For Spring Boot 2, that is spring-boot.run.profiles :
mvn spring-boot:run -Dspring-boot.run.profiles=dev,test
From the plugin documentation :
profiles:
The spring profiles to activate. Convenience shortcut of specifying
the 'spring.profiles.active' argument. On command line use commas to
separate multiple profiles.
Type: java.lang.String[]
Since: 1.3
Required: No
User Property: spring-boot.run.profiles
I'm using spring.boot 2.4.2 and i separated the arguments with withe-space and put the values between double quotes.
mvn spring-boot:run -Dspring-boot.run.arguments="--param1=value2 --param2=value2"
And if you're using Eclipse...
| Parameter Name | Value |
| run.arguments | "--name=Adam" |
This is what worked for me (spring-boot v1.4.3.RELEASE),.
mvn spring-boot:run -Dspring.profiles.active=test,local -Dlogback-debug=true
For the latest version of spring use -Dspring-boot.run.arguments= as shown in the example below
spring-boot:run -Djasypt.encryptor.password=temp -Dspring-boot.run.arguments="OU,Grade"
Use the following command for a Spring Boot application.
mvn spring-boot:run -Dspring-boot.run.arguments="--java.net.preferIPv4Stack=true --config.password=PASSWORD --config.token=s.TOKEN --spring.application.name=ENV --config.server.ip=IP_ADDRESS --spring.profiles.active=ENV --spring.profiles.active.custom=ENV_custom"
I'm analyzing a Maven plugin that I can configure inside the configuration section of plugin:
<plugin>
...
<executions>...</executions>
<configuration>
<!-- items placed here are visible to the MOJO -->
</configuration>
</plugin>
The plugin completely ignores any configuration items for an execution, though:
<plugin>
...
<executions>
<execution>
<id>execution1</id>
<phase>test</phase>
<goals><goal>test</goal></goals>
<configuration>
<!-- items placed here are ignored -->
</configuration>
</execution>
</executions>
</plugin>
I run Maven with mvn test. I'm sure that the execution takes place, as Maven prints its id correctly, but the plugin is not configured -- prints warnings about incorrect settings that are not present when the <configuration> section is moved outside of <executions>.
The question: is it the way the plugin is implemented, that it accepts only "top level" configuration? I've studied its source code and it seemed to me that it's Maven that invokes setters on a MOJO class and it's transparent to the plugin which section the options came from.
The MOJO is annotated with:
* #component
* #goal test
* #phase test
* #execute phase="jasmine-process-test-resources"
The plugin in question is forking a custom lifecycle.
The forked custom lifecycle will have the execution with the specified id (execution1) removed (as it is a forked lifecycle)
Thus any of the plugin's goals that are performed by the forked lifecycle will be missing their configuration. The main mojo itself should be getting the configuration, but what is going wrong is the forked lifecycle executions.
I am guessing which plugin it is, if my guess is right, this is the custom lifecycle and the warnings you are seeing are coming from e.g. other mojos with text like
JavaScript source folder was expected but was not found. Set configuration property
`jsSrcDir` to the directory containing your JavaScript sources. Skipping
jasmine:resources processing.
With a situation like this you will need to either put the <configuration> section in the outer block or configure the executions for the lifecycle.
Configuring the executions for the lifecycle will require adding executions with ids that are of the magic format. I am not 100% certain, but in your case you would be defining an additional execution with an ids of either default-resources or jasmine-lifecycle-resources in order to ensure that the configuration takes.
The less verbose way is just to put the configuration in the outer section and be done with it.
I had this issue with the base maven-install-plugin:2.5.2 using the maven:3.6.3-jdk-8 docker image.
Thanks to the accepted answer for putting me on the right track.
I don't fully understand this note in the documentation (at the end of the section), but it seems that you can give the phase goal an execution id forcing it to use your configuration:
Note: Configurations inside the element used to differ from those that are outside in that they could not be used from a direct command line invocation because they were only applied when the lifecycle phase they were bound to was invoked. So you had to move a configuration section outside of the executions section to apply it globally to all invocations of the plugin. Since Maven 3.3.1 this is not the case anymore as you can specify on the command line the execution id for direct plugin goal invocation. Hence if you want to run the above plugin and it's specific execution1's configuration from the command-line, you can execute:
mvn myqyeryplugin:queryMojo#execution1
My final working docker command:
docker run -it --rm --name parser -v "$(shell pwd)":/usr/src/parser -w /usr/src/parser maven:3.6.3-jdk-8 mvn -X install:install-file#install-my-jar-file
Where install-my-jar-file is my executions id <execution><id>install-my-jar-file</id>...
I'm using JUnit 4.8.1 and Surefire 2.8.1. In my machine I can run one test method only by doing:
$$ mvn clean test -Dtest=TestClass#TestMethod
But when running the same command in the grid configuration, all tests from TestClass are run.
The only difference in the pom is the
<configuration>
<parallel>both</parallel>
</configuration>
configuration in the surefire-plugin.
Any idea, how do I run only one test method in the grid?
possible solution is to use #Categories annotation. But I use simple web driver(not grid).
try step by step set up here
The idea is in following:
you annotate a set of tests you want to exclude and then you show in POM file that you exclude'em in a way somthing like that:
<configuration>
<excludes>
<exclude>blablabla.class</exclude>
</excludes>
</configuration>
Hope this somehow helps you.