Spring #Autowire does not find beans through `mvn verify` - java

I have a Spring (not Spring Boot) project at https://github.com/poggs/spring-autowire-it-problem.
When running the integration test ExampleComponentIT through IntelliJ IDEA, both tests pass and the code can find the bean ExampleComponent. When running the integration test with mvn verify, it fails as it can't find ExampleComponent.
What I want is for mvn verify to be able to find ExampleComponent as it's executed as part of the CI build process.
Can anyone point out where I'm going wrong?

Peter, I have fixed this problem by a temporal workaround
mvn verify -Dfailsafe.useModulePath=false
The fix is already done and it will be released in the version 3.0.0-M6. There the workaround useModulePath=false would not be needed anymore.

It does not make sense to name it an integration test, e.g. ExampleComponentIT, if you want to load the classes from target/classes.
The version 3.0.0-M5 is right, and you should properly build or guarantee that the JAR file works as expected and then maven-failsafe-plugin would work properly with the integration tests.
The difference between Surefire and Failsafe is that Failsafe may fail on verify but the Surefire fails on test phase. Additionally, the Failsafe plugin uses JAR file instead of target/classes which is what the integration test expect due to the package phase happens before the phases integration-test and verify.

When running maven-surefire-plugin, specifically 3.0.0-M5, through mvn clean verify, the directory target/classes is not on the classpath. This directory contains the compiled Java code needed by the integration test.
Adding the following to the maven-failsafe-plugin configuration in pom.xml fixes the problem:
<configuration>
<additionalClasspathElements>
<additionalClasspathElement>target/classes</additionalClasspathElement>
</additionalClasspathElements>
</configuration>
Alternatively, downgrading to 3.0.0-M4 works.

Related

How to run single integration test in maven?

I am trying run single integration test. I have a a lot of *IT class and I want to run only one test. I try this :
mvn -Dit.test=XControllerIT verify
Am I doing wrong? Is there another alternative to this? Maven is being used.
There are two main options depending on your project setup:
Integration Tests are run with a dedicated Failsafe plugin
Integration Tests are run with a regular surefire plugin
If you have a failsafe plugin (and you actually should, its a recommended approach), then use the following snippet:
mvn -Dit.test=MySampleIntegrationTest failsafe:integration-test
If you're on surefire, then run:
mvn -Dtest=MySampleUnitTest surefire:test
In both cases there is a direct plugin goal execution, bypassing the lifecycle like in your initial example (with mvn verify)
In maven it is possible to run the lifecycle, see Default Lifecycle Documentation for more information
Basically, the lifecycle is comprised of phases with plugins bound to each phase
So when you run the mvn verify all the phases before verify will also run.
As a consequence, the code will be compiled (compile phase with a maven compile plugin automatically attached to it will do the job), tests will run (surefire plugin), and so on.
If you don't have a compiled source code and code of tests, you can't use the presented approach because you have to compile the code first.
However, if you already have everything compiled, it makes sense to run only the one test without recompilation of the code, and in this case, depending on the plugin you can use the suggested solution.
Especially it can make sense for local debugging or for CI in some cases multi-step build setup (can be seen in fairly complicated projects)

How to make a plugin goal run regardless of test failures

I have a plugin that is supposed to send files to a database regardless of test failures. I tried setting the fail-at-end setting but the plugin still didn't run. ignoring failures altogether doesn't seem to be an option for me in this case because then faulty jars would be deployed to the artifact repository. I can use this plugin for as a separate command line script but it would be optimal if it could be put in the pom.
The tests need to be run before the plugin does, because the plugin gets the test report files.
I am aware that there are similar questions to this that have been asked before, but they don't seem to help me so I was wondering if someone has similar advice.
If the plugin has to run after the tests, the tests just can't fail the build.
Maven Surefire plugin has an option: maven.test.failure.ignore to run the tests but keep execution
See Here a full description of Test MOJO.
This should be the first bet.
Another option is to build just like this, but run the plugin "externally" (a kind of two steps build). Run maven install or whatever you need, and then (separately)
mvn <group>:<artifact>:<version>:<mojo of your plugin>
try mvn your-goal -DskipTests - will ignore testing.

Integration tests not getting executed

I have some junit tests and htmlunit integration tests in one of my maven project. The problem is that my integration tests are not getting executed when I run
mvn clean test
Junit Tests Here:
webstore\src\test\java\com\istore\dao\AddressTest.java
Integration Tests Here:
webstore\src\test\java\com\istore\presentation\htmlunit\PageTests.java
How does mvn determines that AddressTest.java should execute and other one should not?
http://maven.apache.org/surefire/maven-surefire-plugin/test-mojo.html#includes describes the expected filepatterns.
btw, if you are talking about integration tests, have a look at the maven-failsafe-plugin. It uses *IT.java as file pattern
The problem is suffix Tests, should be Test in your PageTests.java!
By default, the Surefire Plugin will automatically include all test classes with the following wildcard patterns:
**/Test*.java - includes all of its subdirectories and all java filenames that start with Test.
**/*Test.java - includes all of its subdirectories and all java filenames that end with Test.
**/*TestCase.java - includes all of its subdirectories and all java filenames that end with TestCase.
Maven Failsafe Plugin is for integration tests and uses suffix IT. To invoke integration tests with Failsafe Plugin use
mvn verify
References:
Inclusions and Exclusions of Tests in Surefire
Inclusions and Exclusions of Tests in Failsafe
Problem resolved after executing following command:
mvn failsafe:integration-test

How can I run unit tests with Maven as if they are in a JAR?

We recently had a bug caused by some code assuming that a classpath resource could be opened as if it were a regular file. This code was covered by unit tests which passed, because that assumption happens to hold both in Maven and Eclipse. But in production, that code was in a JAR in the service's WAR, and obviously didn't work.
We fixed the bug but I'm not quite satisfied because I can't see how to ensure that it doesn't happen again.
Unit tests are run using Surefire. This happens during mvn test and "test" occurs before packaging. But if you want to run tests after mvn package, you should use Failsafe.
Here's some very relevant documentation about configuring the classpath. By default, it will put ${project.build.outputDirectory} in the classpath, but you should be able to prevent that by setting classesDirectory to some other directory. Then you can add your own jar as either an additionalClasspathElements or perhaps a dependenciesToScan

What is the process with Maven project to compile and test the code?

I have maven project imported in my eclipse. Now I need to start making changes to it and test it with the integration test (out of App server). Currently, the integration test is run out of server using openEJB container.
My basic question is, what is the regular process to compile, build and test with Maven?
mvn install
Maven -> Update Project.
Run my test from command line
Is it how it is done? I am specifically interested in knowing mvn install commands.
So should I do all three steps before I can test it?
Example: I just wanted to print something and see what is the output. For this I guess I need to do all these steps?
The openEJB container needs classes so it can load them.
There is a wonderful Maven quick-reference sheet at http://maven.apache.org/guides/MavenQuickReferenceCard.pdf
First, you should be aware that unit tests and integration tests are separate and are run from separate plugins and at separate parts of the maven lifecycles. Unit tests are run with surefire and integration tests are run with failsafe.
You want to run integration tests and the failsafe documentation says:
NOTE: when running integration tests, you should invoke maven with the (shorter to type too)
mvn verify
rather than trying to invoke the integration-test phase directly...
This is the best way to run integration tests directly in maven. It will run all the preceding steps necessary (eg: compile) in order to run the integration tests. It won't waste time doing an install because install happens immediately after verify.
But if you're running the tests locally, it may be a better idea to run your integration tests directly in your IDE. That will give you a much faster feedback loop.
If it is Eclipse project the most reasonable thing is to do everything not from command line but from Eclipse. Assuming you have m2e plugin installed, go to your_project->run as->Maven test and run it.
You dont need neither install nor package phase to run Maven tests, package will create a jar which is not needed for tests, install will copy this jar to local repo which is also useless. When Maven run tests it uses compiled classes from target dir and ignores project's jar if even it exists.
Yes, mvn isntall is the most popular option. It compiles, packages and tests your project.

Categories