Execute application using mvn clean install - spring

I am working on a simple spring boot application (created from spring initializr contains web mega-dependency).
I added also Cucumber dependencies for acceptance test.
When I run mvn clean install it runs directly the cucumber test, but me I want to run the app before tests (And why not stop the app after the tests terminate).
I tried maven exec plugin but it does not work:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<executions><execution>
<goals><goal>java</goal></goals>
</execution></executions>
<configuration>
<mainClass>org.dhappy.test.NeoTraverse</mainClass>
</configuration>
</plugin>

Skipping tests
If there is a need to skip tests and just compile and package the application, you can set the skipTests property as follows:
mvn install -DskipTests
Application execution
If you want to run the application, you can use the exec plugin. There are two flavours ("goals" really): one runs the package application and the other runs a Java class. If you know the class name, you can run that plugin as follows:
mvn exec:java -Dexec.mainClass="org.dhappy.test.NeoTraverse"
Integration testing
Finally, if you want to run the application first before you can run the tests, you are actually not doing unit testing. Your tests in this case are perhaps integration and not unit tests. The actual details would vary depending on whether your application has complex needs such as a database and a web server.
Integration testing happens at a different "phase" in maven lifecycle.
In short, you need to rename your Java test classes something other than *Test.java so that maven surefire plugin ignores your tests. You then need to include maven-failsafe-plugin so that integration testing happens.

You want to perform these steps:
Start the application
Run a set of tests
Stop the application
Starting and stopping the application is one thing and could be done in the <phase>pre-integration-test</phase> and <phase>post-integration-test</phase>. Integration testing is done in the <phase>integration-test</phase>
You want to read and understand https://maven.apache.org/surefire/maven-failsafe-plugin/usage.html. Specifically, look at the Using jetty and maven-failsafe-plugin example.

Related

Run unit/integration test(s) within a given process i.e. existing test server

Problem statement
How to invoke tests within a given test server(i.e. within the process)?
Explanation
We know that there is surefire plugin, but this uses surefire:test goal which runs unit tests in separate process. In my case, i need to run the tests within the existing process (pre-configured test server and required environment) to run test. In surefire plugin, there is configuration that has forkCount and reuseForks. If i use it with forkCount as 0, reuseForks true, still creates separate server and hence process. I simply want to avoid setup part for test.
Update after Joe's comment saying it as duplicate As my application usage SpringBoot, running mvn clean install build the project and execute tests. While executing tests, it creates server for each running test. Even though i used configuration given below, in console it shows same process id, but starting server every time. In my case i don't want to make server up for every test case, rather used pre-existing test server and the test should use that server.
Configuration used
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<forkCount>0</forkCount>
<reuseForks>true</reuseForks>
</configuration>
</plugin>

autoweaving AspectJ fails during unit tests in IntelliJ

We have a series of unit tests and they were passing fine prior to me trying to add some aspects for dependency injection and logging duration of methods being called in our rest end points.
In the unit tests prior to the tests failing, we get two odd errors:
[AppClassLoader#14dad5dc] error aspect 'com.lutherconsulting.aphirm.log.DurationLoggingAspect' woven into 'com.lutherconsulting.aphirm.rest.ClientRest' must be defined to the weaver (placed on the aspectpath, or defined in an aop.xml file if using LTW).
and
[AppClassLoader#14dad5dc] error aspect 'com.lutherconsulting.aphirm.log.DurationLoggingAspect' woven into 'com.lutherconsulting.aphirm.log.DurationLoggingAspect' must be defined to the weaver (placed on the aspectpath, or defined in an aop.xml file if using LTW).
We are using the aspectj maven plugin to just let it autoweave the aspects into the web application. The configuration for that from our pom.xml for Maven is below.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.8</version>
<configuration>
<showWeaveInfo>true</showWeaveInfo>
<complianceLevel>1.8</complianceLevel>
<source>1.8</source>
<target>1.8</target>
<Xlint>ignore</Xlint>
<encoding>UTF-8</encoding>
<verbose>true</verbose>
</configuration>
<executions>
<execution>
<goals>
<goal>test-compile</goal>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
The strange thing is that this all works perfectly fine if I build the war file and deploy it to a Tomcat instance, or if I run all of our cucumber feature tests. When I do either of those, The aspect weaves fine and I get data on the duration of the rest methods I annotated logged to a database correctly. If I run a specific test package from intelliJ or try to run all junit tests in intellij, it fails with those two errors
Is this something I'm just missing in Intellij as a run/debug configuration in the way it executes unit tests? I didn't think our structure of our app was different than any normal web app
- src
| - main
| - java
| - packages
| - resources
| - test
| - java
| - packages
| - resources
- pom.xml
I appreciate any ideas on
In the end, what turned out to fix this was to go into the project structure in IntelliJ, on the AspectJ settings there is a check box for Post-Compile Weave Mode. Checking this made sure weaving occurred in Intellij prior to the tests executing.
As far as I understand you are running your tests from IntelliJ using its own runner and not maven.
Therefore you have configured the weaver to be run using maven through the aspectj-maven-plugin. The problem is that your IntelliJ runner is not running maven, hence its weaver plugin is not being run either.
I can come up with an idea and you could run your maven test goal within IntelliJ to run all your tests with the maven configuration, so it will detect aspectj-maven-plugin and run the weaver too. Here you can check how to run maven goals:
https://www.jetbrains.com/idea/help/executing-maven-goal.html
On the other hand, according to this link you have to enable Load Time Weaving in IntelliJ
http://www.aspectprogrammer.org/blogs/adrian/2006/02/a_practical_gui_2.html
Quoting the link it says:
Open the "Run/Debug Configurations" dialog using the drop-down in the
toolbar. Click the "+" icon to create a new configuration and name it
e.g. "tests".
For this project, I've selected "All in package" and search for tests
"In whole project".
Now all you have to do is add the VM startup parameter that brings in
the AspectJ LTW agent:
-javaagent:lib/aspectjweaver.jar
The part after the ":" should be the path to your copy of aspectjweaver.jar. In this case, I've copied the
aspectjweaver.jar from the Spring distribution into the lib directory
of my project (it doesnt' need to be on the project's classpath). You
can use the jar from AspectJ 5 final release too if you want to.
Also, you can check to configure AspectJ facet, check this link to read about it
https://www.jetbrains.com/idea/help/aspectj.html

Make maven run one task before another when running a single plugin

I've got a project set up using the Maven Cargo plugin to launch Tomcat with my webapp deployed in it, along with some other webapps that are needed for support. This works great. Unfortunately, when I run "mvn cargo:run" it doesn't do a build first, but instead just actually starts Tomcat running the code the last time I did do a build.
Previously I used the tomcat7 plugin instead, and that did do a build first and always ran the current version of the source code. As such, I could change my code and run "mvn tomcat7:run" and know that the code changes had been built and were running.
I can't find any way with the Cargo plugin to make it do this, but is there some way with Maven to make it at least run the Package phase when I run a specific plugin so that it will build the WAR file correctly first?
The Tomcat plugin automatically invokes the compile phase prior to executing itself. The Cargo plugin won't do that. In order to compile your code before executing the plugin, you need to run
mvn clean compile cargo:run
If you want to start and stop the container automatically before and after your integration tests, you can also bind cargo:start and cargo:stop to Maven's lifecycle phases. See Automatically executing and stopping the container when running mvn install for details.
Here is a full example how to integrate the start via Cargo in the usual build. https://github.com/khmarbaise/maui/tree/master/src/main/resources/it-example-container. You can start the integration tests via mvn -Prun-its clean verify which might be better
A completely different approach would be to use the exec-maven-plugin to execute multiple goals with one command:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.4.0</version>
<configuration>
<executable>mvn</executable>
<arguments>
<argument>clean</argument>
<argument>compile</argument>
<argument>cargo:run</argument>
</arguments>
</configuration>
</plugin>
<!-- more plugins... -->
</plugins>
</build>
This way, you would only have to call
mvn exec:exec
to clean, compile and run your application.

System brokes when start single test in InteliJ

I have complex web application using Spring,Hibernate, Maven joint build(Java+Groovy) with test in Spock and different Maven profiles. All source files are in Java. I have Maven configuration(part of it) for local testing:
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.0</version>
<configuration>
<path>/services</path>
<port>8062</port>
<contextReloadable>true</contextReloadable>
<backgroundProcessorDelay>2</backgroundProcessorDelay>
<contextFile>../context.xml</contextFile>
</configuration>
</plugin>
So when I have changes in the bytecode maven contextReloadable triggers redeploy of the app. That is the desire state. When I run some test with maven configuration usingin InteliJ, in my system I see that redeploy is triggered.
I have no changes in the files or in the tests. But redeploy is triggered and everything is OK. But there is a problem for the same test when I click right button and click run on UploadTest using InteliJ 14.0.3 Community Edition
Redeploy happens but the profiles are not taken under consideration and the environment variables are not set. If I add them
org.apache.catalina.core.ContainerBase backgroundProcess WARNING: Exception processing loader WebappLoader[/services] background process java.util.ConcurrentModificationExceptio
And my backendSystem crashes. So my questions are:
Why InteliJ triggers redeploy when run Spock test without changes in the code/tests?
Why starting a single Spock test using InteliJ, cause my backednSystem brokes(I need to restart it)(what can be the source of the problems?? InteliJ runs the test with diferent parameters, profiles are not taken or ...).
Does inteliJ start compilation of the test with different eviroment variables set? (I see that inteliJ start its own launcher for the test).

How to defer Maven test goal after deployment?

I'm using the JBoss and WildFly Maven plugin to deploy my applications.
<plugins>
<plugin>
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-maven-plugin</artifactId>
<version>1.0.0.Beta1</version>
</plugin>
</plugins>
The problem that I have found is that if I have some Junit test in my project they are executed before application deployment, leading to a test with an inconsistent application state. Is it possible to configure somehow this plugin to kick-in before the test phase ?
Thanks
This plugin by default executes alongside the package phase and you'll probably have issues attempting to run the plugin before your application is packaged. As an alternative, you could override the maven-surefire-plugin to run your tests in a later phase, such as integration-test, which would be executed after your application has been packaged.
A practical example can be found on this Maven tutorial where it's show how to include failsafe plugin and bind it to the executions of the integration-test and verify phase. This way tests which are engineered as integration test (e.g ending in *IT) will execute only during the integration-test phase.

Resources