Maven failsafe plugin will not run test classes annotated with JUnit Category - maven

I have an interface like this:
public interface IntegrationTest {
}
I configure the failsafe plugin like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.14</version>
<configuration>
<groups>acme.test.IntegrationTest</groups>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
</goals>
</execution>
</executions>
</plugin>
If I then create an integration test like this
#Category(IntegrationTest.class)
public class ExampleClassIntegrationTest {
#Test
public void slow_and_painful_test() {
This test will not run.
If I however name the class according to the Inclusions and Exclusions of Tests
**/IT*.java
**/*IT.java
**/*ITCase.java
Like so:
#Category(IntegrationTest.class)
public class ExampleClassIT {
#Test
public void slow_and_painful_test() {
The test runs fine. Why do I have to name the test AND have an annotation when i use the groups-tag? Am I missing something? The documentation on using JUnit states that you can use the Category annotation at the class level.

Thats because these are the default java classes which fail safe plugin includes when executed.
You can however over ride this in your pom with tag :
E.g
<includes>
<include>**/*.java</include>
</includes>
To include all the java files.

You should either add JUnit as a dependency (>4.8) which is already done or in particular add the following to your failsafe-plugin configuration:
<plugins>
[...]
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.14.1</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>2.14.1</version>
</dependency>
</dependencies>
</plugin>
[...]
</plugins>
But i assume it will not change the situation.

Related

Quarkus: how can I ignore tests written for different test profile and test tags

I'm strugling with finding info of how to ignore some tests that were exclusively written for some "other" profile when runing default mvn clean install.
I need different tests for different use cases:
CRUD operations on entities with hibenate-orm create-drop option
other operations on entities with hibernate connected to mock database (hence integration tests, with hibenate-orm validate)
I've got my custom test profile
public class IntegrationProfile implements QuarkusTestProfile {
#Override
public String getConfigProfile() {
return "integration";
}
#Override
public Set<String> tags() {
return Collections.singleton("integration");
}
}
And use it like this:
#QuarkusTest
#TestProfile(IntegrationProfile.class)
public class ArticleIntegrationRepositoryTest { ... }
I run these tests in cmd line like:
mvn -Dquarkus.test.profile.tags=integration clean install
But when I run
mvn clean install
all tests, including "profiled" ones are executed and I don't want that.
Is there any way to annotate these "other" tests so they don't get run unles I specificaly execute them with mvn -Dquarkus.test.profile.tags=integration clean install
Any help appreciated
I figured it out:
First I addet junit 5 tag to to my integrations test classes
#Tag("integration")
then I updated my pom.xml files accordingly.
For maven-surfire-plugin I added executions to ignore my integration tags on tests
<executions>
<execution>
<id>default-test</id>
<goals>
<goal>test</goal>
</goals>
<configuration>
<excludedGroups>integration</excludedGroups>
</configuration>
</execution>
</executions>
and added new integration profile to include only these tests when needed
<profile>
<id>integration</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<executions>
<execution>
<id>quarkus-test</id>
<goals>
<goal>test</goal>
</goals>
<configuration>
<groups>integration</groups>
</configuration>
</execution>
</executions>
...
</plugin>
</plugins>
</build>
</profile>
now mvn clean install ignores my "integration" tests and mvn -Dquarkus.test.profile.tags=integration -P integration clean install executes only integration tests

How to self start spring app without writing a main method?

So is there a way to initialize and start a command line Spring app without writing a main method. It seems like all such main methods have the same form
public static void main(final String[] args) throws Exception {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml", Boot.class);
SomeService someService = (SomeService) applicationContext.getBean("someService");
someService.bar();
}
I suppose that's not complicated, but has someone found a way to provide a way to just specify the context.xml at the command line or, better yet, in a manifest file?
The goal here is to simplify the creation of spring applications as executable jars. I hope that I can specify some utility class as the Main-Class in the manifest. I suppose I would also need to specify the starting point for the app, a bean and a method on it where begins the process.
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.stackoverflow</groupId>
<artifactId>stackoverflow-autostart-spring-app</artifactId>
<version>0.1</version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.5.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.stackoverflow.spring.autostart.Autostart</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Write a simple SpringMain which takes an arbitrary number of xml and properties files as the arguments.java -cp myapp.jar util.SpringMain context.xml
You then use the lifecycle attributes (init-method) on your relevant beans to kick-start the application

Not able to run a category in Junit4 tests

Have a test method annotated with category:
public interface BVT {} //is placed in package net.test.categories, file name BVT.java
public class TestClass{
#Test
#Category(BVT.class)
public void someTest(){
System.out.println("smoke");
} }
I use Junit 4.12 and surefire 3.0.0-M3
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
<configuration>
<forkCount>${threadCount}</forkCount>
<reuseForks>false</reuseForks>
<skip>false</skip>
<groups>${testGroup}</groups>
</configuration>
</plugin>
If I try to run test from BVT category
mvn clean test -DtestGroup="net.test.categories.BVT"
I get
[INFO] Results:
[INFO]
[INFO] Tests run: 0, Failures: 0, Errors: 0, Skipped: 0
Have no ideas why the test was not run/skipped...
Using of created in pom profile didn't help - it just runs all the tests.
Adding this runner dependency also doesn't help:
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>3.0.0-M3</version>
</dependency>
</dependencies>
Creating a Suite runs the needed test but I don't want to list all required classes in this suite class, just want to run a certain group from command line
From the documentation:
You can use JUnit categories by using the groups parameter.
Using mvn -D... sets a system property, not a plugin parameter.
So you need something like:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
<configuration>
...
<groups>${myGroup}</groups>
</configuration>
</plugin>
And run it with mvn ... -DmyGroup="net.test.categories.BVT"
Didn't find reason, but adding include section in surefire configuration solved the issue.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
<configuration>
<forkCount>${threadCount}</forkCount>
<reuseForks>false</reuseForks>
<skip>false</skip>
<groups>${testGroup}</groups>
<includes>
<include>*</include>
</includes>
</configuration>
</plugin>

Spring Maven mutimodule project with common test resources not picking up properties

I have a multimodule Spring Maven project with structure:
Parent
Child_A
Child_B
In Child_A I create a common test-jar as follows:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
and I want to use it in Child_B and Parent so I added the dependency as follows:
<dependency>
<groupId>groupId</groupId>
<artifactId>artifactId</artifactId>
<version>1.0.0</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
Now in Child_B I can access the classes which are in the test-jar, but for some reason, I can't access the properties file. I looked in the jar and the properties file was there.
I Child_A I have a common test class which has the following annotations:
#RunWith(SpringRunner.class)
#WebAppConfiguration
#SpringBootTest
#Transactional
#Getter
and also I have TestMainClass there which is same as normal Spring main class what extends SpringBootServletInitializer.
I have read many post here and they all refer to creating the test-jar and all should work but still for some reason I cannot access the properties.
What am I missing?

Binding a custom Maven plugin to a default phase

I have a custom Maven plugin that I'm trying to bind to the package phase by default. I've tried every combination of using the #Mojo annotation along with the #Execute annotation, but it doesn't seem to auto bind.
The only way I manage to get my plugin to work is by defining it like this:
#Mojo(name = "put")
public class SSHMojo extends AbstractMojo {
And then in my project using the plugin, defining an execution. I'd like to avoid having to add the <executions> every time I want to use my plugin.
<plugin>
<groupId>com.patrickgrimard</groupId>
<artifactId>ssh-maven-plugin</artifactId>
<version>1.0.2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>put</goal>
</goals>
</execution>
</executions>
<configuration>
<serverId>devopsmtl</serverId>
<host>example.com</host>
<remoteDirectory>/srv/www</remoteDirectory>
</configuration>
</plugin>
My full plugin pom can be found at https://github.com/pgrimard/ssh-maven-plugin/blob/master/pom.xml
Hi simply use the following:
#Mojo( name = "put", defaultPhase = LifecyclePhase.PACKAGE )
Apart from that i would suggest to use a newer version of maven-plugin-api (3.0 at least)...
Use annotation attribute defaultPhase (like already mentioned by khmarbaise):
#Mojo(name = "put", defaultPhase = LifecyclePhase.PACKAGE)
public class SSHMojo extends AbstractMojo { ... }
In the pom.xml of the consuming Maven project you can leave away the reference to the phase after this:
<plugin>
<groupId>com.patrickgrimard</groupId>
<artifactId>ssh-maven-plugin</artifactId>
<version>1.0.2</version>
<executions>
<execution>
<!-- <phase>package</phase> --><!-- needed no longer -->
<goals>
<goal>put</goal>
</goals>
</execution>
</executions>
...

Resources