I am using TestNg and Maven with the surefire plugin to run my tests. I have several different tests that I want to run in the same pom. Currently to do this I have two different XML files defined and i've defined two profiles to run different xml files but this keeps throwing errors!
I don't know how I should solve this issue.
Any help will be greatly appreciated!
<profile>
<id>run</id>
<activation>
<property>
<name>start</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
<suiteXmlFiles>
<suiteXmlFile>${project.build.directory}/resources/testng.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
<executions>
<execution>
<id>test</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<skip>false</skip>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
Imagine profile 2 to be pretty much the same BUT the xml suite file is different
I get a parsing error: It can't find the test class in the suiteXmlFile. However, if I just use one profile have just one xml file, it's acceptable. The one that was failing also works.
Try to move suiteXmlFiles to execution configuration and use maven-failsafe-plugin that is more suitable for integration tests
Related
My integration tests take long to run, and I don't want my developers to waste time every time they need to compile. I only want my integration tests to run:
In my CI/CD server.
When I tell my IDE (NetBeans) to specifically run a test file.
Is this possible? How can I achieve it?
Add a configuration to your POM that excludes the integration tests during your normal build (assuming that your integration tests are named something like UserService_IT.java.
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>${skip.surefire.tests}</skipTests>
<excludes>
<exclude>**/*_IT*.java</exclude>
</excludes>
</configuration>
To run the integration tests, say in your CI build, add a profile and activate it in your pipeline, like mvn verify -Pintegration-tests.
<profile>
<id>integration-tests</id>
<activation>
<activeByDefault>false</activeByDefault>
<property>
<name>integration-tests</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<includes>
<include>**/*_IT.java</include>
</includes>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
I'm generating a project from an archetype and I have a property in pom of this generated project (archetype-resources/pom):
<properties>
<myProperty>productionValue</myProperty>
</properties>
and the following surefire configuration:
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<argLine>
-Djava.library.path=${myProperty}
</argLine>
</configuration>
</plugin>
I want myProperty to be overridden with value from my archetype pom when I run ITs and stay the same when users generate this project. How do I do that?
I tried setting it in archetype.properties file, but it has a variable in it:
myProperty=${project.basedir}/IT/path.
I want ${project.basedir} to be a basedir of archetype project in case of ITs, not of generated project, which is not the case when I do it like that.
Another way I tried is to use plugin configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-archetype-plugin</artifactId>
<version>${maven-archetype.version}</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
</goals>
<configuration>
<properties>
<myProperty>${project.basedir}/IT/path</myProperty>
</properties>
</configuration>
</execution>
</executions>
</plugin>
But it didn't work as well, myProperty in pom of generated project is not changed. What is it that I'm doing wrong? Thank you so much for your help!
The problem was that I have put
<configuration>
<properties>
<myProperty>${project.basedir}/IT/path</myProperty>
</properties>
</configuration>
under <execution> tag and not <plugin>. After I did that it worked as expected.
I want to run test classes whose name end with ResourceTest.java, so I defined following execution.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</configuration>
<version>2.12.2</version>
<executions>
<execution>
<id>resource-tests</id>
<phase>resource-tests</phase>
<goals>
<goal>resource-tests</goal>
</goals>
<configuration>
<includes>**/*ResourceTest.java</includes>
<!-- <exludes>**/*.java</exludes> -->
</configuration>
</execution>
</executions>
</plugin>
But I'm not sure how to run this, I've searched a lot and I'm missing something.
I tried surefire:test, it skipped all the test cases as defined in above configuration. So, I tried surefire:resource-tests, maven is saying no goal is not defined.
I'm using eclipse to run my maven build, by passing these parameters. How can I run by the execution id?
How to select a specific execution when running with surefire:test when I've mulltiple executions defined in my pom?
What am I missing? Any help would be appreciated.
There are several problems with your current configuration :
you are forcing the maven-surefire-plugin to be executed in the resource-tests phase but this phase does not exist. You should delete that declaration to keep the default plugin binding phase, which is test.
you are invoking the goal resource-tests but maven-surefire-plugin does not define such a goal.
the <includes> element is ill-defined. There should be a <include> tag under it.
you are excluding all Java files from the plugin configuration so no test will be run
the configuration of the plugin should be done under the <configuration> element not for each <executions>.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.2</version>
<configuration>
<includes>
<include>**/*ResourceTest.java</include>
</includes>
</configuration>
</plugin>
When you have multiple executions and you want "select" one of them, you can use a profile:
<profiles>
<profile>
<id>resource-tests</id>
<properties>
<test-classes>**/*ResourceTest.java</test-classes>
</properties>
</profile>
<profile>
<id>task-tests</id>
<properties>
<test-classes>**/*TaskTest.java</test-classes>
</properties>
</profile>
</profiles>
with the following plugin configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.2</version>
<configuration>
<includes>
<include>${test-classes}</include>
</includes>
</configuration>
</plugin>
With such a configuration:
when you run mvn clean test -Presource-tests, only the classes matching **/*ResourceTest.java will be tested
when you run mvn clean test -Ptask-tests, only the classes matching **/*TaskTest.java will be tested
I'm trying to separate different kinds of tests (unit, integration, acceptance) by using maven profiles. This is the part of the main pom file:
<properties>
<build.profile.id>dev</build.profile.id>
<skip.unit.tests>false</skip.unit.tests>
<skip.integration.tests>true</skip.integration.tests>
<skip.acceptance.tests>true</skip.acceptance.tests>
</properties>
<profiles>
<profile>
<id>dev</id>
</profile>
<profile>
<id>integration-test</id>
<properties>
<build.profile.id>integration-test</build.profile.id>
<skip.unit.tests>true</skip.unit.tests>
<skip.integration.tests>false</skip.integration.tests>
<skip.acceptance.tests>true</skip.acceptance.tests>
</properties>
</profile>
<profile>
<id>acceptance-test</id>
<properties>
<build.profile.id>acceptance-test</build.profile.id>
<skip.unit.tests>true</skip.unit.tests>
<skip.integration.tests>true</skip.integration.tests>
<skip.acceptance.tests>false</skip.acceptance.tests>
</properties>
</profile>
</profiles>
<build>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.17</version>
<configuration>
<skipTests>${skip.unit.tests}</skipTests>
<includes>
<include>**/*UnitTests.java</include>
</includes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.17</version>
<executions>
<execution>
<id>integration-tests</id>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<skipTests>${skip.integration.tests}</skipTests>
<includes>
<include>**/*IntegrationTests.java</include>
</includes>
</configuration>
</execution>
<execution>
<id>acceptance-tests</id>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<skipTests>${skip.acceptance.tests}</skipTests>
<includes>
<include>**/*AcceptanceTests.java</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
As you can see I'm using the profile information to run certain types of tests based on the profile that is used. Default profile is dev and it will only run unit tests. They can be executed like this:
mvn clean test
For integration and acceptance tests I use failsafe plugin: Example of running integartion tests would be:
mvn clean verify -P integration-test
This works fine when I run it from the main pom module, but it doesn't work when running it from the child module. Tests are just ignored. Looking at the effective pom for child module I don't see the profiles. Am I doing something wrong or is this is expected behavior from maven? If profile inheritance (needs to cascade to deepest modules in the hierarchy) can't be achieved this way how can it be done?
Update: This is the project hierarchy
project directory
--main module
--commons module
--administration
----domain
----data
----business
----web
With multimodule project you usually don't execute modules directly. Instead you should always execute the main module, but specify only your desired submodule via -pl parameter. There are a lot more issues connected with running modules directly.
Just double checked some multi-module projects I have participated on and I we are using <pluginManagement> to propagate plugin configuration form parent POM to child projects.
Some unit tests in my application are related to finding and manipulating certain files resources that are part of the application itself.
I need these tests to be executed in the real production setting of the application, where it is deployed as a JAR file, not as an exploded directory.
How could I instruct Maven to execute my unit tests considering as the classpath the project generated jar file (and any other declared library dependencies) instead of the compiled classes in the file system as it does by default?.
In other words, right now the classpath for my unit tests is set to: /$PROJECTPATH/target/classes/.
Instead, I would like this classpath to be set to: /$PROJECTPATH/target/myjarfile.jar.
I have tried manually adding and removing dependency classes, as explained here:
http://maven.apache.org/plugins/maven-surefire-plugin/examples/configuring-classpath.html
,but until now it is not working.
My current project POM looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.mygroupid</groupId>
<artifactId>myartifact</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
...
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1.2</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.4</version>
<configuration>
<includeScope>runtime</includeScope>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>process-resources</phase>
<!-- <phase>package</phase> -->
<goals>
<goal>copy-dependencies</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.3</version>
<configuration>
<classpathDependencyExcludes>
<classpathDependencyExclude>
${project.build.outputDirectory}
</classpathDependencyExclude>
</classpathDependencyExcludes>
<additionalClasspathElements>
<additionalClasspathElement>
${project.build.directory}/${project.build.finalName}.${project.packaging}
</additionalClasspathElement>
</additionalClasspathElements>
</configuration>
</plugin>
</plugins>
</build>
</project>
Thanks in advance for any help!.
The standard unit tests executed as part of the test lifecycle phase cannot see the project JAR because the test phase is executed before the package phase, so your tests are run before Maven generates the JAR. See this page for a list of lifecycle phases and their order.
What you want it to run your tests as integration tests, which execute in the integration-test phase.
There are a number of tutorials for setting up Maven to run integration tests. Here and here are a couple of starters. The failsafe plugin is typically used for executing integration tests.
I can't recall exactly if integration tests use target/classes or your project's JAR file in the classpath. But if it doesn't you could always create another Maven project, add your tests in there and add the main project as a dependency to this integration test project. In some cases this can be preferable to using the integration test phase in the main project if it is not just a standard Java library, for example if you are writing an annotation processor.