I am building a maven project with Kotlin and Quarkus. I splitted unit and integration tests so I have a structure like :
src/
integration-test/ -> where I annotate classes with #QuarkusIntegrationTest
main/
test/ -> where I annotate classes with #QuarkusTest
I have an issue when trying to run all tests in integration-test (with mvn failsafe command, or with intelliJ). All the tests inside the first test class pass, but then the application fails to start before running tests of the second test class, stating that application port is already in use:
io.quarkus.runtime.QuarkusBindException: Port(s) already bound: 8081: Address already in use
When running each test class separately, all tests pass.
I have tried setting test-port: 0 in my application.yml, but I get the same error with the random port. Is there a way to tell quarkus to keep the same app instance for all integration test class ? Or to check that the first one has teminated completely before running the next class ? I don't know what I am doing wrong with this #QuarkusIntegrationTest annotation.
Thanks in advance for the help.
Well, this was a dumb issue; One of my test was annotated #QuarkusTest instead of #QuarkusIntegrationTest.
Related
This question is the continuation of question "SpringBoot: how to run tests twice, with two different config files".
I use to compile my project using mvn clean install. Doing that, maven also launches my unit tests and I immediately knows whether my development is correct.
I am actually working on a module that embeds a JMS connection. my module supports two JMS buses: EMS and AMQ. The bus to be used is specified in the configuration of my module
As a consequence, I need to create two profiles, one for EMS and one for AMQ.
However, when I launch my mvn clean install I want that maven launches automatically the tests using the two profiles, not only one; I don't want to have to launch it twice: mvn clean test -Dspring.profiles.active=ems ; mvn clean test -Dspring.profiles.active=amq
Thank you for help
You can pass the two profiles separated by a comma:
mvn clean install -Dspring.profiles.active=ems,amq
And then you'll have two active profiles:
The following profiles are active: ems,amq
I think that there is a miss-understanding; It seems that when I run my tests with spring.profiles.active=ems,amq:
all tests are launched one time
both profiles are enabled
What I want is different:
launch all tests TWO TIMES
first time with ems (and only ems) profile enabled
second time with amq (and only amq) profile enabled
For the moment, I do not succeed to find a solution; evey clue is welcome
Regards
I found a solution for my issue; a kind of trick based on:
overloading the SpringJUnit4ClassRunner
redefining the run() method in order to:
call force the use of the first profile
call the origial run() method
do the same with the other profile
public class MultiProfileTestRunner extends SpringJUnit4ClassRunner {
...
public void run(RunNotifier notifier) {
System.setProperty("spring.profiles.active", "ems");
super.run(notifier);
System.setProperty("spring.profiles.active", "amq");
super.run(notifier);
}
Between both calls to super.run() we have to 'force' Spring to reload its context, otherwize the profile change is not taken into account
I did it by using the annotation #DirtiesContext(classMode = AFTER_CLASS) on my tests
You can also specify in the src/test/resources/application.properties specific properties that apply every time Spring tests are run. Seems cleaner to me than specifying them on Maven command line. For your case :
spring.profiles.active=ems,amq
I have a #Service class where i'm caching some table data. I don't want those queries to run while building mvn install. Is there a way to ignore the file while building and it only execute when i start the server ?
It's a spring-boot application.
Here is background of my issue. I have initialized the spring boot app from http://start.spring.io/ site, which actually adds dummy application test file with SpringBootTest annotation and default contextLoads() with Test annotation, with an intention to initialize and execute all test cases, which needs to initialize and execute all code base. In my opinion this is not required, as we can have respective Test classes per controller/manager, which will give more controlled environment to hook up your Test setups and executions.
I have removed the default application Test file and included respective test classes for code coverage and quality. This way my beans are not executed at server startup time rather build time.
Well, I would like to have a maven goal execute-custom-tests inside my custom-maven-plugin that consists of running test methods (This tests are not unit tests). Something similar to test goal of soapui-pro-maven-plugin, for example.
Why? Basically the main objectives of the plugin are testing stuff (not unit testing) and the tests in src/test are for unit testing, right?
Being more specific I was thinking about something like this:
#Mojo (name = "run-custom-tests", LifecyclePhase.TEST)
public class TesterMojo extends AbstractMojo {
#Parameter(property = "someParameter")
private String someParameter;
// [...] parameters for test configuration
#Override
public void execute() throws MojoExecutionException, MojoFailureException {
// Piece of code that executes a set of custom tests which procedure I specified.
}
}
When test fail, I would like them to be marked as failed tests not as failed executions. What's the right thing to do here? Show me the light, please.
Maven conventions support two types of testing out of the box: unit tests (via maven-surefire-plugin) and integration tests (via maven-failsafe-plugin).
By default, maven-surefire-plugin only looks for the following files with unit tests:
**/Test*.java
**/*Test.java
**/*TestCase.java
Similarly, default includes for integration tests run by maven-failsafe-plugin are the following:
**/IT*.java
**/*IT.java
**/*ITCase.java
So, as you can see, Maven lets each plugin figure out which tests it should care about. So it's perfectly fine for src/test/java to contain different types of tests, not just unit tests.
Different folder
You can put tests in a different folder too. One example would be if you have non-Java tests, since then src/test/java location doesn't make sense. Standard Maven plugins get project model from Maven to figure out the src/test/java location and some 3rd party plugins use the same mechanism. Depending on the plugin you use, you might want to check out its configuration or use maven-build-helper-plugin to add-test-source in order for some plugins to pick up another test folder automatically.
Different tests on demand
From the Maven perspective the core difference between unit tests and integration tests is the additional requirements for the later: they often need to have your project already packaged and they often need additional setup or teardown. But you yourself can set up multiple test goals during both test and integration-test phases. All major test frameworks support specifying which test suite should be run when (e.g., via groups). If your framework doesn't, you can still use plugin includes/excludes. It is a standard practice to combine this with Maven profiles in order to only run smoke tests by default (during development) and to run full tests on CI environment. You can use the same approach to enable anyone (a tester?) to run extra tests on demand, e.g., to run extra heavy tests when certain important part of the code has changed.
Let's say we have a project that consists of some Eclipse-projects and Spring 3.1, the final result is a WAR-file. We use WTP for development. All the unit tests and integration tests are working (our Maven does this automatically). The project runs in WTP with a local configuration. In other words everything looks as if it is ready to roll.
Now we want to test run that WAR-file with different sets of configuration files for different platforms. The test should only start the context and see if that causes any issues (missing/misspelt property in a property file, too many beans for auto-wiring, ...). AFAIK it isn't necessary to have access to (or it accessible to) the outside world. Basically it should only start the context, close it and continue with the next configuration. If one context fails, the build should break.
How should we do this? Can we do this with Maven? Something external?
EDIT: Forgot to say: We will run our stuff with Tomcat 6.
Sounds like you are talking about integration test.
You should look at the failsafe plug for this:
http://maven.apache.org/surefire/maven-failsafe-plugin/usage.html
Using jetty and maven-failsafe-plugin You need to bind one of
jetty:run, jetty:run-exploded or jetty:run-war to the
pre-integration-test phase with deamon set to true, bind
failsafe:integration-test to the integration-test phase, bind
jetty:stop to the post-integration-test phase and finally bind
failsafe:verify to the verify phase. Here is an example:
Another possibility is a selenium test. Selenium tests require the war to be deployed and running before the tests are run. So there are plugins that do all this.
Then you would have a very simple selenium test case that just made a simple http request to the app to see if it was running.
You would use a different profile for each different configuration you wanted to test.
I have a set of integration JUnit test cases that I want to run under 2 or more separate spring application contexts. Application contexts differ in configuration settings and bean wirings. However, if I specify the application context file name using the #ContextConfiguration annotation at the top of the JUnit classes then I am only able to run these test cases once for the specified application context. Is it possible to run the same JUnit test cases with different application contexts?
Also, I am interested to execute the test cases once for each application context in the same test run - mvn test.
Put your test code in an abstract class and use subclasses with different #ContextConfigurations. See http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/testing.html#testing-examples-petclinic
You can use a master test application context file that just includes a specific context file by using Maven resource filtering
e.g.
#ContextConfiguration("classpath:test-context.xml")
where src/main/resources/test-context.xml is:
<beans>
<import resource="${project.test.context}" />
</beans>
Then run mvn test -Dproject.test.context=context1.xml, mvn test -Dproject.test.context=context2.xml etc.
If you do that, you should also set a default maven property project.test.context in your POM.
By the way, if these are integration tests, they should by convention be called ...IT.java rather than ...Test.java, and should be run by failsafe (using mvn verify), not surefire.