Can you tell me how to call maven surefire in command line with the following configuration ?
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<executions>
<execution>
<id>Custom tests</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<classesDirectory>target/generated/classes/normalCase/</classesDirectory>
<reportsDirectory>target/generated/reports/normalCase/</reportsDirectory>
</configuration>
</execution>
</executions>
</plugin>
When surefire is defined like this in my pom.xml and I execute the phase test, it work exactly how i want it to work : it tries to run my tests on the classes located in target/generated/classes/normalCase.
So I tried this command line:
mvn surefire:test -DclassesDirectory="target/generated/classes/normalCase/"
But no, it keep checking the classes in the default value directory which is "target/classes".
So how can I achieve this in command line ?
To recap the situation you have. You are generating multiple version of your source code during the build, each of those version ends up in a separate folder under target. For each of those versions, you would like to execute your unit tests with the maven-surefire-plugin. Let's consider the base directory to be target/generated/classes. That means you have multiple subdirectories target/generated/classes/version1, target/generated/classes/version2... for each version.
A possible solution would be to use the iterator-maven-plugin to iterate over all subdirectories of a folder and invoke the maven-surefire-plugin from all those subdirectories. The variable #item# holds the current item.
<plugin>
<groupId>com.soebes.maven.plugins</groupId>
<artifactId>iterator-maven-plugin</artifactId>
<version>0.3</version>
<executions>
<execution>
<id>iterate</id>
<phase>test</phase>
<goals>
<goal>iterator</goal>
</goals>
<configuration>
<folder>target/generated/classes</folder>
<pluginExecutors>
<pluginExecutor>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
</plugin>
<goal>test</goal>
<configuration>
<classesDirectory>target/generated/classes/#item#</classesDirectory>
<reportsDirectory>target/generated/reports/#item#</reportsDirectory>
</configuration>
</pluginExecutor>
</pluginExecutors>
</configuration>
</execution>
</executions>
</plugin>
Related
I am trying to get the coverage of a few test cases related to an open source project of which I got the jar file.
I'm using maven as automatic build tool and the jacoco plugin for maven to get the coverage of the tests on the project.
What I would like to achieve is the same output that I can get with the command:
-jar jacococli.jar report jacoco.exec \
--classfiles <project.jar> \
--sourcefiles <myTestsDirectory> \
--html <jacocoReportsDirectory> \
--xml <jacocoReportsDirectory>coverageFile.xml \
--csv <jacocoReportsDirectory>coverageFile.csv
When I run this from the commandline I can retrieve the report for the coverage computed on the whole project (the jar).
I don't know how to insert this command (or something that can get me the same output) in the pom. I tried to put it in the surefire plugin argLine (with the -javaagent command) but this got me nowhere.
This is where I got so far:
<build>
<sourceDirectory>src</sourceDirectory>
<testSourceDirectory>src/test</testSourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.7</version>
<executions>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<dataFile>target/coverage-reports/jacoco.exec</dataFile>
<outputDirectory>target/coverage-reports/jacoco-reports</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M4</version>
<configuration>
<argLine>
-javaagent:lib/jacocoagent.jar=destfile=target/coverage-reports/jacoco.exec
</argLine>
<reportsDirectory>target/coverage-reports/surefire-reports</reportsDirectory>
</configuration>
</plugin>
</plugins>
</build>
Giving the whole src directory as the sourceDirectory gets my test cases as the target of the coverage computation and I don't want that.
Note: there are no java classes in src to which the tests are targeted, so there's no need to put that as sourceDirectory. I assume this has to point to the jar somehow.
I have an Eclipse Java project for which I am trying to execute the unit tests using Maven.
I have my unit tests as below so that it respects the expected hierarchy
src/test/java/StringUtilsTests.java
However, my unit test references the source code located in:
src/my/package/root/util/StringUtils.java
just because it has always been like this and I don't want to change my folder hierarchy for the tests.
Therefore, I use the build-helper-maven-plugin to add this source folder, as below
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>add-test-source</id>
<phase>generate-test-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>src/my/package/root/util</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
But even with that, I get the below error:
[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] /C:/Users/frederic/git/myproject/src/test/java/StringUtilsTests.java:[22,32] package package my.package.root.util does not exist
Below is my reference to the maven-surefire-plugin
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<configuration>
<skipTests>false</skipTests>
</configuration>
<executions>
<execution>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
</plugin>
And it's even worse if I don't put my test in
src/test/java/StringUtilsTests.java
but instead here for example:
src/tests/my/package/root/util/StringUtilsTests.java
The maven-surefire-plugin will show
No tests to run
Do you need to run them as Unit-Tests or can you run them as Integration-Tests? I think Integration tests would work out-of-the-box like this? Simply change the class names to end with IT MyClassIT.java for these tests or finetune your .pom and change the goal to integration-test-phase or verification-phase? I think that should work since it will be executed later on in the build cycle.
Otherwise try to change this line with a wildcard:
<source>src/my/package/root/util/*</source>
Based on this article, adding the below elements to my pom.xml fixed my issue:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<executions>
<execution>
<id>compiletests</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
<testSourceDirectory>${project.basedir}/src-test</testSourceDirectory>
And VERY important was to add this dependency
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.8.1</version>
<scope>test</scope>
</dependency>
I would like to execute a plugin goal from command line but perform multiple executions of the plugin. To this end my POM looks like this:
<plugin>
<groupId>xxx.yyy</groupId>
<artifactId>zzz</artifactId>
<version>1.1.6</version>
<executions>
<execution>
<id>default-cli-1</id>
<goals>
<goal>mygoal</goal>
</goals>
<configuration>
.... config1 ....
</configuration>
</execution>
<execution>
<id>default-cli-2</id>
<goals>
<goal>mygoal</goal>
</goals>
<configuration>
.... config2 ....
</configuration>
</execution>
</executions>
</plugin>
What I would like to do is something like:
mvn xxx.yyy.zzz:mygoal
and that would then execute the two executions. But I cannot figure out how.
I'm aware that I cannot use an <id> when executing from the command line. That is what the default-cli is for. However the <id> must be unique within <executions> which means I can only put the default-cli on one execution.
Maven version 3.0.5.
You can execute a goal (and its execution) from command line starting from Maven 3.3.1 on and this new feature, via the #executionId additional option.
Concerning Maven and execution ids generation, you can also check this SO question.
Before Maven 3.3.1 you could instead bind the two executions to a phase which would normally not harm (like validate) and have something like the following:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>execution-1</id>
<phase>validate</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>something1</classifier>
</configuration>
</execution>
<execution>
<id>execution-2</id>
<phase>validate</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>something2</classifier>
</configuration>
</execution>
</executions>
</plugin>
Then executing:
mvn validate
You will effectively execute the two executions of the same goal of the same plugin, as part of an harmless phase.
If you don't want to have them as part of this phase by default (understandable), then you can move them to a profile and activate it as part of the execution:
mvn validate -PpluginGoalExecution
For completeness, the profile would look like:
<profile>
<id>pluginExecution</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>execution1</id>
<phase>validate</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>something1</classifier>
</configuration>
</execution>
<execution>
<id>execution2</id>
<phase>validate</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>something2</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
And it goes without saying: the id of the profile should in this case be quite self explanatory about which plugin and which goal it would actually execute (that is, the purpose of the profile, as usual).
Update
Just cosmetic, but you could also add to the profiled build above the element:
<defaultGoal>validate</defaultGoal>
So that you would only need to run the following Maven command (only profile activation):
mvn -PpluginGoalExecution
And it would then automatically execute the validate phase and the configured plugin executions. Not a big change (as I said, cosmetic), but maybe closer to a plugin goal execution rather than a Maven phase invocation (again, just appearance).
I want to skip a plugin execution when I run the command 'mvn deploy'. Say in below example, I DON'T want to execute the 'properties-maven-plugin' in 'mvn deploy'
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0-alpha-2</version>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>read-project-properties</goal>
</goals>
<configuration>
<files>
<file>${session.executionRootDirectory}/xxxx.properties</file>
</files>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<tagNameFormat>#{artifactId}/#{artifactId}-#{version}</tagNameFormat>
</configuration>
</plugin>
<plugins>
Your plugin is bound to prepare-package phase, so I think you can not avoid it execution when deploying.
But, it is possible to create a profile that contains that plugin, such way you activate (command line, Jenkins configuration, ...) the profile when you want to run the plugin.
This way you can control whether to run it, but it is not an answer to your question, because this way you can not avoid the plugin execution on deploy.
I want to run the maven compiler plugin in a different phase and with different sourceDirectories and destinationDirectories such that code from directories other than src/main/java and src/test/java can be used.
I thought the solution would look something like the below, where the phase I was linking it to was pre-integration-test. However the properties for testSourceDirectory and testOutputDirectory don't seem to be specified in this way as they are in the section of the POM.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>compile mytests</id>
<goals>
<goal>testCompile</goal>
</goals>
<phase>pre-integration-test</phase>
<configuration>
<testSourceDirectory>${basedir}/src/inttest/java</testSourceDirectory>
<testOutputDirectory>${basedir}/target/inttest-classes</testOutputDirectory>
</configuration>
</execution>
</executions>
</plugin>
Is there a way to get this plug-in to compile different directories in different phases without affecting its default operation?
The source directories are set outside the compiler-plugin inside the <build> element, so this won't work.
You can use the build-helper-maven-plugin's add-source and add-test-source to specify additional source directories for your integration tests, but this will not remove the existing source dirs.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.3</version>
<executions>
<execution>
<id>add-it-source</id>
<phase>pre-integration-test</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${basedir}/src/inttest/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
If you bind the add-test-source goal to run just before the testCompile goal, your integration tests will be included. Note you want them to be output to target/test-classes so the surefire plugin will find them.
To handle removal of the standard test sources, I wrote a small plugin to modify the model to remove existing testSource locations before adding the ones for integration tests.
After more research it is apparent this is not actually possible in Maven 2 in the way I want, a hack of some form is necessary to introduce integration tests. While you can add additional directories (as suggested by Rich Seller) there is no plugin to remove the other sources or to compile a directory separately from the main compilation.
The best solution I have found for adding integration tests is to first use the build helper plugin to add the directory inttest directory to be compiled as tests.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>add-test-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>src/inttest/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
Now in order to get the integration tests to execute on the integration-test phase you need to use excludes and includes to manipulate when they get run as below. This allow any custom parameters you might want (in my case an agent being added via argline).
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludes>
<exclude>**/itest/**</exclude>
</excludes>
</configuration>
<executions>
<execution>
<id>inttests</id>
<goals>
<goal>test</goal>
</goals>
<phase>integration-test</phase>
<configuration>
<excludes><exclude>none</exclude></excludes>
<includes>
<include>**/itest/**/*Test.java</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>