Choosing test category on command line - java

I am using JUnit's categories to split my tests into different categories and using maven to compile and run my test (surefire and failsafe).
Question is, how to I choose which category of tests are executed from command line?
something like: mvn clean install -DloadTests.
my failsafe plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${failsafe.plugin.version}</version>
<configuration>
<!--Exclude load tests by default-->
<excludedGroups>com.test.lib.categories.LoadTestCategory</excludedGroups>
</configuration>
</plugin>

You could do that with profiles and specify the plugin configuration in there.
<profiles>
<profile>
<id>noLoadTests</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${failsafe.plugin.version}</version>
<configuration>
<!--Exclude load tests by default-->
<excludedGroups>com.test.lib.categories.LoadTestCategory</excludedGroups>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
And then run maven
mvn test -PnoLoadTests
If you only ever need to exclude/include one specific category you could also define a property in the profile and use that in the . For more info you can look here
Edit: The other provided answer is the better one in this case, but profiles allow for various advanced configurations.

According to the documentation, user property is called groups. Therefore this should work:
mvn clean install -Dgroups=com.test.lib.categories.LoadTestCategory

Related

What does a Maven Artifact means in a context of runnable jar project? [duplicate]

I have a project that consist of 3 different libraries. When I run install script it takes all libraries from repo and run mvn clean install on them. But this version of library already installed in repo. Is there a way to skip install phase if version in pom.xml equal version in my local repo.
I know that I can use local repo and just set dependencies. But my boss want that our project can build only with public repos and without any our repos.
You can bypass like this
-Dmaven.install.skip=true
<profiles>
<profile>
<id>skipInstall</id>
<activation>
<property>
<name>maven.install.skip</name>
<value>true</value>
</property>
</activation>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>default-install</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
Last week Olivier Lamy patched this jira.
MINSTALL-73
Most maven plugins can be skipped by specifying something like:
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>X.Y</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
you can also set up build profiles to set properties and use that to determine the value. for example, running the command: mvn -Pexample would select the "example" profile. The POM would then contain:
...
<properties>
<skip.install>false</skip.install>
...
</properties>
...
<profile>
<id>example</id>
<properties>
<skip.install>false</skip.install>
</properties>
</profile>
...
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>X.Y</version>
<configuration>
<skip>${skip.install}</skip>
</configuration>
</plugin>
...
Using these POM additions, the default behavior for the install plugin will be to perform its default goal, but if the example profile is selected, then the install plugin will skip its goal.
Using what I learned from the other answers, this was the cleanest result for me.
In my super pom I added a pluginManagement/plugin to disable default-install and default-test phases when the property deployOnly is set.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
<executions>
<execution>
<id>default-install</id>
<configuration>
<skip>${deployOnly}</skip>
</configuration>
</execution>
<execution>
<id>default-test</id>
<configuration>
<skip>${deployOnly}</skip>
</configuration>
</execution>
</executions>
</plugin>
So on the command line, I can disable install and test phases by adding -DdeployOnly.
mvn clean install #build and test everything
mvn deploy -DdeployOnly #just deploy it
I know that I can use local repo and just set dependencies. But my boss want that our project can build only with public repos and without any our repos.
Are you sure you understood correctly what you boss meant? I interpret the above as "don't install third party libraries in your local repository, use only libraries available in public repositories". This is different from "don't use your local repository" which is basically impossible, that's just not how maven works. I'd try to clarify this point.
Apart from that, I don't get the question which is very confusing (what repo are you talking about? What is the install script doing? Why do you call clean install on libraries? etc).
Extending the other answers, from the future.
Maven plugins have a surprisingly high freedom, how do they run. If they want, they can ignore/override the typical pom.xml settings. Furthermore, also the <configuration><skip>true</skip></configuration> is only a convention, nothing obligates a plugin to follow it, except that most of them is developed so.
My experiments with the recent problem show, that both #Cemo's and #MiloshBoroyevich solution should be utilized, also the plugin requires both to really let us in peace. More concretely, the only working configuration by me was this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
<executions>
<execution>
<id>default-install</id>
<phase>none</phase>
</execution>
</executions>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
One of your options is to put the deployment to another module. I.e. have one pom.xml build the artifact and install it to the local repo, and another pom.xml to deploy it. This separation is quite common in larger projects, where the testsuite is sometimes a separate module or even a project, the packaging happens in several stages, etc.
- pom.xml - myProject-root - type=pom
- pom.xml - myProject-artifact - type=jar
- pom.xml - myProject-deploy - type=pom, does the deployment, skips it's own `install` goal

maven-release-plugin goals ignored in submodule in multi-module project

I have a multi-module Maven project. The project is laid out as follows
project/
pom.xml
types/
pom.xml
client/
pom.xml
service/
pom.xml
The types and client modules are built as JARs, service is built as a WAR. I'm using the maven-release-plugin to create new releases of this project. I would like to have the release plugin invoke extra goals when performing the release of the service module.
The release plugin is configured like so in the root pom (nothing special):
<plugin>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version>
</plugin>
... and configured like so in the service pom along with the plugin I'm trying to invoke via the <goals> parameter:
<plugin>
<artifactId>maven-release-plugin</artifactId>
<configuration>
<goals>deploy dockerfile:build dockerfile:push</goals>
</configuration>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<configuration>
<repository>12345.ecr.us-east-1.amazonaws.com/project</repository>
</configuration>
</plugin>
The idea is that I'd like to build a Docker image for the service module but it doesn't make sense to build images for other modules in the project. However, when cutting a new release, the goals configuration in the service pom file are never invoked.
Maven version: 3.3.3
maven-release-plugin: 2.5.3
JDK: Oracle 1.8.0u144
The command being used:
mvn -Pstaging -B clean release:clean release:prepare release:perform
I'm not able to share the output from this command.
I've verified that the relevant configurations seem be be applied via
mvn -Pstaging help:effective-pom
My question is: Is what I'm trying to accomplish possible with the release plugin? I haven't found any questions or articles that indicate it's impossible.
With the caveat that I have never used the dockerfile-maven-plugin, try release profiles instead of goals.
Step 1. Edit the release plugin config in project/pom.xml.
<plugin>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version> <!-- should define in pluginManagement -->
<configuration>
<releaseProfiles>publish-docker</releaseProfiles>
<!-- other plugin config -->
</configuration>
</plugin>
Choose a name for the profile that makes sense. I'll use publish-docker as the name here.
Step 2. Add a profile with that name to service/pom.xml:
<profiles>
<profile>
<id>publish-docker</id>
<build>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<configuration>
<repository>12345.ecr.us-east-1.amazonaws.com/project</repository>
</configuration>
<executions>
<execution>
<id>docker-publish</id>
<phase>deploy</phase> <!-- important -->
<goals>
<goal>build</goal>
<goal>push</goal>
</goals>
</execution>
</executions>
</plugin>
</build>
</profile>
</profiles>
This profile includes plugin configuration that binds the dockerfile:build and dockerfile:push goals to the deploy phase. The release plugin will enable the publish-docker profile for each module. The profile will only exist in the service module, so that's where it will run.
One other thing I notice. In the release command:
mvn -Pstaging -B clean release:clean release:prepare release:perform
I suspect the -Pstaging part is not actually being applied during the release. The release plugin forks another process for each goal run. To pass the argument to the fork, the arguments parameter is required:
mvn -Pstaging -Darguments="-Pstaging" -B clean release:clean release:prepare release:perform

Using parameters from pom.xml to switch environments for selenium tests + using mvn command line arguments

My goal: using parameters to switch environments in my tests for instance:
mvn test google -> Tests goes to google site
mvn test bing -> bing site
"I need to feed my tests which environment is the target and it should comes from the pom.xml and using them as arguments."
It would be very useful for teamcity/jenkins integration as well.
Apart from that, I need to use url as variables in my tests. How can I do that?
Profiles can be a solution in pom.xml?
<profiles>
<profile>
<id>google</id>
<properties>
<base.url>http://www.google.com</base.url>
</properties>
</profile>
<profile>
<id>bing</id>
<properties>
<base.url>http://www.bing.com</base.url>
</properties>
</profile>
</profiles>
From build section:
<configuration>
<systemProperties>
<base.url>${base.url}</base.url>
</systemProperties>
</configuration>
But How can I use system properties and overall the approach is good? Thanks!
You can configure the maven-surefire-plugin to include only specific test classes and the run mvn test. By default, mvn will run all these:
"**/Test*.java" - includes all of its subdirectories and all Java filenames that start with "Test".
"**/*Test.java" - includes all of its subdirectories and all Java filenames that end with "Test".
"**/*Tests.java" - includes all of its subdirectories and all Java filenames that end with "Tests".
"**/*TestCase.java" - includes all of its subdirectories and all Java filenames that end with "TestCase".
but you could specify the tests you want to include like this:
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20.1</version>
<configuration>
<includes>
<include>Sample.java</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
[...]
</project>
or exclude:
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20.1</version>
<configuration>
<excludes>
<exclude>**/TestCircle.java</exclude>
<exclude>**/TestSquare.java</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
[...]
</project>
Having said that, this is probably not the best design and generally, you should be using some testing framework which you then can configure according to your needs. Few examples are (or combination of): jUnit, TestNG, Cucumber, Spring.
In Cucumber, for example, you can have tags which then you can configure as a part of your test execution. If you use Jenkins, you might have something like this in your build fild:
clean install -Dcucumber.options="--tags #Google
or
clean install -Dcucumber.options="--tags #Bing
In Spring, you can have profiles that you can run like this as Jenkins job:
mvn clean test -Dspring.profiles.active="google"
EDIT
Alternatively, you can define a custom property in your pom like this:
<properties>
<myProperty>command line argument</myProperty>
</properties>
And then pass it from command line like this:
mvn install "-DmyProperty=google"
EDIT2
Providing a -D prefixed value in command line is a way of setting a system property. You can perform this action from Java code itself like this:
Properties props = System.getProperties();
props.setProperty("myPropety", "google");
or simply:
System.setProperty("myPropety", "google");

TestNG mvn run tests without group

I am using TestNG and Maven with surefire plugin to run tests.
I have:
#Test(groups={"groupA"})
TestA{}
#Test
TestB
I would like to have possibility to run:
mvn test
should invoke all test without any group
mvn test -Dgroups=groupA
should invoke only groupA tests ( this works by default but just added here to have it working with previous option )
I tried to configure surefire like:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.16</version>
<configuration>
<excludedGroups>groupA</excludedGroups>
</configuration>
</plugin>
mvn test works as expected, but after
mvn test -Dgroups=groupA
no tests are executed
Edit
I found solution here:
https://labs.consol.de/blog/maven/citrus-and-testng-groups/
<!-- TestNG groups -->
<testGroups></testGroups>
<testGroupsExcluded>groupA</testGroupsExcluded>
<!-- /TestNG groups-->
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.16</version>
<configuration>
<groups>${testGroups}</groups>
<excludedGroups>${testGroupsExcluded}</excludedGroups>
</configuration>
</plugin>
...
<profiles>
<profile>
<id>a-testes</id>
<properties>
<testGroups>a</testGroups>
<testGroupsExcluded></testGroupsExcluded>
</properties>
</profile>
</profiles>
But there is one problem with this solution. It works fine when we want run just always one groups of tests, for example mvn test -P a-tests, but when we will add another group, let's say b-tests, then after mvn test -P a-tests, b-tests only one group will be executed because last defined profile will overide properties... Any ideas how to combine testGroupsExcluded, testGroups properties from multiple profiles?
Edit 2
I just ended with solution
<properties>
<testGroups>unit</testGroups>
</properties>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.16</version>
<configuration>
<groups>${testGroups}</groups>
</configuration>
</plugin>
But I had to assign all my tests explicitly to groups (all unassigned tests now are 'unit'), but now I can call:
mvn test To invoke all tests marked as unit
mvn test -DtestGroups=groupA, groupB To invoke any group tests...
Dude, have you checked http://testng.org/doc/documentation-main.html#beanshell ?
In surefire plugin attach testng suit config:
<configuration>
<suiteXmlFiles>
<suiteXmlFile>testng.xml</suiteXmlFile>
</suiteXmlFiles>
...
in testng.xml
<suite name="Emap test suite">
<test name="Emap tests">
<method-selectors>
<method-selector>
<script language="beanshell"><![CDATA[
addClassPath("target/test-classes" );
return com.yourpackage.shouldExecuteTest(groups, System.getProperty("groups"));
]]>
In static Java method shouldExecuteTest you can implement any rule you want!
Accoriding to doc, you can use those vars:
java.lang.reflect.Method method: the current test method.
org.testng.ITestNGMethod testngMethod: the description of the current test method
java.util.Map<String, String> groups: a map of the groups the current test method belongs to.
System.getProperty("groups") is just -Dgroups=xxx passed from mvn invocation.
Works like a charm!

maven plugin run only if user preference

Is there a generic way to do this for any maven plugin - run based on user preference/ disable it based on a property file?
Have a properly working maven plugin using com.mysema.querydsl, now want to change is so it only runs if a particular flag/ command line options is provided.
<plugin>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-maven-plugin</artifactId>
<version>${querydsl-maven-plugin.version}</version>
//executions
<configuration>
<jdbcDriver>com.mysql.jdbc.Driver</jdbcDriver>
<jdbcUrl>jdbc:mysql://myurlk:port/db</jdbcUrl>
<jdbcUser>id1</jdbcUser>
<jdbcPassword>ccc</jdbcPassword>
<packageName>com.sample</packageName>
<targetFolder>${project.basedir}/src/main/java</targetFolder>
<schemaPattern>APP</schemaPattern>
//goal prefix here?
</configuration>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.driver.version}</version>
</dependency>
</dependencies>
</plugin>
Tried to add
<executions>
<execution>
<id>execution1</id>
<phase>test1</phase>
<goals>
<goal>export</goal>
</goals>
</execution>
</executions>
and a goal prefix
<goalPrefix>mysema1</goalPrefix>
But not working. Want a way so this plugin is not run when we do a default
mvn clean install
But need to add another flag to make it run?
Using Apache Maven 3.0.4
Did you try to put the plugin execution into a Maven profile? There are several triggers to enable a profile for a build (e.g. OS, Java version, property value or the profile id itself on the command line).
See http://maven.apache.org/guides/introduction/introduction-to-profiles.html for more details.
Define a profile, add the plugin definition into the profile and add a property trigger for the profile like this:
<project>
...
<profiles>
<profile>
<id>profile-id</id>
<activation>
<property>
<name>myProperty</name>
</property>
</activation>
<build>
<plugins>
<plugin>
...
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
When you build yout project with mvn clean install the plugin will not be executed, when you build your project with mvn clean install -DmyProperty or mvn clean install -Pprofile-id your plugin will be executed. In the second case the property activation trigger for the profile is obsolete.

Categories