I am trying to execute each method of a JUnit test into a separated VM without executing all the methods at the same time. I want to serialize the execution of the test methods using a separated VM for each of them.
I have tried several configuration and checked the Maven plugin documentation about forked VM but I did not manage to get the correct behavior.
I am using the following configuration but all the methods are executed at the same time.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<reuseForks>false</reuseForks>
<parallel>methods</parallel>
<threadCountMethods>1</threadCountMethods>
</configuration>
</plugin>
The number of threads is counted by code by default (https://maven.apache.org/surefire/maven-failsafe-plugin/integration-test-mojo.html#perCoreThreadCount). The following configuration is working.
<configuration>
<reuseForks>false</reuseForks>
<parallel>methods</parallel>
<threadCount>1</threadCount>
<perCoreThreadCount>false</perCoreThreadCount>
</configuration>
Related
I am running testng.xml file using POM.xml by adding compiler and surefire plugins. It runs test but the sequence of tests is not as expected.
I have 10 classes mentioned in testng.xml and it runs in that sequence when i run through testng.xml. But when running through POM.xml the sequence goes like; first it runs all the 0 priority tests mentioned in all classes, then 1 priority tests and so on. It should run tests according to the classes sequence mentioned in testng.xml.
Any quick help will be much appreciated.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>${jdk.level}</source>
<target>${jdk.level}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>testng.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
</plugins>
</build>
under testng dependency the scope tag needed to be changed to compile from test and it resolved the issue as it needed to compile the build after adding plugins.
It resolved the issue.
Because I need to customize Host header in HTTP request, I need to start my Spring Boot Java app with following argument (available since JDK 12):
java -jar -Djdk.httpclient.allowRestrictedHeaders=host application.jar
but how to pass it into maven pom.xml file to be able to use this argument durring tests which are failing because of missing this flag?
I tried to use maven-compiler-plugin in following way:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<compilerArgs>
<arg>-Djdk.httpclient.allowRestrictedHeaders=host</arg>
</compilerArgs>
</configuration>
</plugin>
but it's wrong:
error: invalid flag: -Djdk.httpclient.allowRestrictedHeaders=host
Following examples are not working either:
-jdk.httpclient.allowRestrictedHeaders=host
jdk.httpclient.allowRestrictedHeaders=host
So i tried even with spring-boot-maven-plugin
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<jvmArguments>-Djdk.httpclient.allowRestrictedHeaders=host</jvmArguments>
</configuration>
</plugin>
but it's also not working because in that case this flag is ignored and I got restriction error when I run mvn test. Which is not happening when I run java with this flag.
You seem to be configuring the wrong plugin. You said you need to "be able to use this argument during tests" which means you should be configuring Maven Surefire Plugin.
Have a look at the example they have provided. May be you can use systemProperties:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
<configuration>
<systemProperties>
<property>
<name>propertyName</name>
<value>propertyValue</value>
</property>
[...]
</systemProperties>
</configuration>
</plugin>
or the argLine approach:
<argLine>-Djava.endorsed.dirs=...</argLine>
I added in my pom.xml the following plugin to run test classes in parallel
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<parallel>classes</parallel>
<threadCount>10</threadCount>
<systemPropertyVariables>
<profile.name>${profile.name}</profile.name>
</systemPropertyVariables>
<forkCount>1</forkCount>
<testFailureIgnore>true</testFailureIgnore>
</configuration>
</plugin>
And i have
#RunWith(Suite.class)
#Suite.SuiteClasses({
test_1.class,
test_2.class
})
when i run it as a junit test it runs sequential not parallel... any help ??
<forkCount>1</forkcount> means 1 thread!
The default setting is forkCount=1/reuseForks=true, which means that maven-surefire-plugin creates one new JVM process to execute all tests in one Maven module.
from: https://maven.apache.org/surefire/maven-surefire-plugin/examples/fork-options-and-parallel-execution.html#Forked_Test_Execution
To run them in parallel, you should choose a forkCount > 1, and (to be safe) also <reuseForks>false</reuseForks>.
I want to create a jar file with my main java project and all of it's dependencies. so I created the following plugin definition in the pom file:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.5.1</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<!-- exclude junit, we need runtime dependency only -->
<includeScope>runtime</includeScope>
<outputDirectory>${project.build.directory}/dependency-jars/</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
so I execute mvn dependency:copy-dependencies, it works fine that it copies all the dependencies to target/dependency instead of dependency-jars. Any ideas?
That is normal: you configured a special execution of the maven-dependency-plugin, named copy-dependencies, however, invoking the goal dependency:copy-dependencies directly on the command line creates a default execution, which is different than the one you configured. Thus, your configuration isn't taken into account.
In Maven, there are 2 places where you can configure plugins: either for all executions (using <configuration> at the <plugin> level) or for each execution (using <configuration> at the <execution> level).
There are several ways to solve your issue:
Move the <configuration> outside of the <execution>, and make it general for all executions. You would have:
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<!-- exclude junit, we need runtime dependency only -->
<includeScope>runtime</includeScope>
<outputDirectory>${project.build.directory}/dependency-jars/</outputDirectory>
</configuration>
</plugin>
Note that, with this, all executions of the plugin will use this configuration (unless overriden inside a specific execution configuration).
Execute on the command line a specific execution, i.e. the one you configured. This is possible since Maven 3.3.1 and you would execute
mvn dependency:copy-dependencies#copy-dependencies
The #copy-dependencies is used to refer to the <id> of the execution you want to invoke.
Bind your execution to a specific phase of the Maven lifecycle, and let it be executed with the normal flow of the lifecycle. In your configuration, it is already bound to the package phase with <phase>package</phase>. So, invoking mvn clean package would work and copy your dependencies at the configured location.
So I have some classes that rely on a jar file that has native methods in them. I am running into issues when mocking the objects in this jar file...so I have found a solution that works.
Using forkedmode pertest seems to fix this issue. However, there are 5 files affected by needing to be run in forkedmode...there are 130 other tests that do not need forking, and the build time with cobertura and everything is VERY slow as it is forking for every test in that pom...
So my question is...is there a way to specify which classes you want to run in forkedmode and run everything else normally?
is there a way to specify which classes you want to run in forkedmode and run everything else normally?
You can do this by specifying two <execution> elements with specific <configuration>: a default one for most tests (excluding those that need to be forked) with the forkMode set to once and a special one for the special tests (including only the special one) where the forkMode set to always.
Here is a pom snippet showing how to do this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<!-- Lock down plugin version for build reproducibility -->
<version>2.6</version>
<executions>
<execution>
<id>default-test</id><!-- here we configure the default execution -->
<configuration>
<forkMode>once</forkMode><!-- this is the default, can be omitted -->
<excludes>
<exclude>**/somepackage/*Test.java</exclude>
</excludes>
</configuration>
</execution>
<execution>
<id>special-test</id><!-- and here we configure the special execution -->
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<forkMode>always</forkMode>
<includes>
<include>**/somepackage/*Test.java</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
See also
7.1.6. Setting Parameters for Goals Bound to Default Lifecycle