Is it possible to execute a lifecycle target (e.g. integration-test) on an artefact that has been installed within the local repo?
My use case is as follows. I have a multi module project with many modules that dedicated various types of integration testing (compliance test, performance tests, etc). I need to invoke these integration multiple times with different environment configurations. These configurations are expressed as maven profiles and parameterised using properties. I want to avoid recompiling the project over and over again.
I would like to have one build CI job performing the mvn install, then separate CI jobs performing the integration tests, triggered once the build CI job has passed. The integration tests would simply invoke integration-test lifecycle phase of the installed artefact setting the profile and passing the parameters
I have tried pointing mvn at the .pom file within the local repo but this does not work. It fails because it cannot find classes within the artefact's own JAR file (as if it were not being put on the classpath) - a problem that doesn't occur if I have my integration job checkout the tree and invoke the pom.xml within the source tree.
mvn -f ~/.m2/repo/x/y/z/myproj-perftests-x.x.x-SNAPSHOT.pom integration-test -Pmyprofile -Dparam1=blah
No, it is not possible. Maven plugins (normally) only work with project sources.
If your only concern is recompiling project again and again, consider splitting your project into the core part and the integration tests part. Then when running integration tests you'll only need to recompile the integration tests part.
Related
I am working on understanding Maven and I'm learning about building your Java app with it.
So when I do a :
maven package
It does build my jar as expected but I see in the output console that Maven does build tests (it always say that the test a run and there are no failure).
I researched on the web about that and learned that Maven use a plugin called Maven Surefire. But I can't understand what does that plugin do to my code, what does the tests "means" ? What does the tests do with my code and how it works behind the console ?
The Maven surefire plugin runs the tests you have written. These are usually in the src/test/java folder. If you have none, the plugin does nothing.
Is this only one question? :D
So. Different things are going on.
You create an application with Java. To test the single components / packages / classes that you create most people use JUnit or TestNg. You usually have dedicated test classes that verify your production code behaves as intended without you clicking through all the things on every change.
When you now use maven to run your build the pom.xml file defines a packaging - in your case "jar" since you create a jar file. The packaging defines what set of default plugins run in the defined maven phases. You probably recognize package here. Maven executes all phases up to package and the registered / configured plugins.
To execute those tests maven provides the surefire plugin which supports running JUnit or TestNg tests. If you follow the directory conventions your tests reside in src/test/java and the surefire includes naming convention maven will execute those tests in every build (as this is the best practice). If you also want to write integration tests then there is the failsafe plugin. That plugin is not enabled by default and runs in different maven phases.
So the tests just run your production code - in fact they just do what you implement in the tests. They don't alter it in any way.
The maven introduction documentation has step by step explanations: Maven in 5 Minutes and the Getting Started Guide.
Starting from scratch this is probably a lot. So don't rush this. The build setup and test setup are very important things to have.
I am trying to find a solution for the following puzzle. I have java projects, managed by maven, which needs some native dependencies to work (run unit and integration tests). Those are provided in form of deb packages, which needs to be installed prior to running a build.
I use Jenkins for CI. Native dependencies can not be installed on Jenkins nodes, because of conflicts with other builds and they can change often. What I do now is not to create a Jenkins job type 'maven', but 'freestyle' and use a pbuilder to create an clean sandbox, install all that is necessary and invoke maven build.
This is working great, but I am loosing Jenkins maven goodies like automatic upstream projects, trigger build when dependency change, etc. Jenkins simply does not know that maven is there.
Finally, my question. Is there a way how to achieve both, isolate build so installed libraries does not affect other builds and leverage Jenkins's 'magic' applied to maven builds and their dependencies?
You could split your build in three jobs, which trigger the next one.
Create needed environment
Run maven job
Clean Up
Even a Freestyle job has "Invoke top-level Maven targets". You could use that to get "maven goodies" while also having ability to run other build steps.
There is an option to "use private Maven repository" which will make sure it will use the .m2/repository folder location relative to the workspace. If you need to separate into multiple jobs, you can use "Custom/shared workspace" between those jobs.
Even in Maven-style job, there is an option to use private repository, so that one job does not affect another.
The problem can be solved by using distributed Jenkins builds. Slave agents can be configured to provision clean environment (e.g. via VMs, docker,...) for each build and tear it down after build is done. This way Jenkins job can be of Maven type and any changes done by pre-build step will not affect others.
More information can be found here.
Consider docker. There you can run processes in isolated environments just as you want. Docker works in a way that it easily communicates with Jenkins.
As a benefit you can also use that docker container to run local builds in the same environment as they run in Jenkins.
I had been introduced to concept of CI lately and was trying to work on jenkins CI. I was stuck up in one thing . How to trigger executable testng files in jenkins CI. For ex locally in our machines we just run testng.xml to execute couple of test cases. In the same way how can we trigger this xml file to run in jenkins CI ?
In most cases with jenkins you wouldn't use an executable. Normally you'd run the wrapper for the tests (Junit/Nunit etc.) which Jenkins is fully capable of running on it's own.
You can use this article to run TestNG tests using Maven:
Running TestNG tests using maven
After configuration is completed just add Invoke top-level Maven targets step to the Build Steps in Jenkins (Maven plugin should be installed). The target should be test in this case.
If you will face with any errors during configuration, try to google them.
If you are not using any build tool like maven or ant, you can invoke it from command line as we'll and specify your suite file. Make sure to set the correct class paths http://testng.org/doc/documentation-main.html#running-testng
You can put this as a build step in Jenkins.
Add a compilation step prior to this step. I haven't ever tried it - have always used ant or maven, but that is where I would start exploring.
I have a multi-module maven project. In every module there are unit tests. When I make clean install tests run before every module and if all tests in one module are success it build successfully. If one test failure all other tests in that module run successfully (or some run successfully, other failed). The build of module in what the first failure unit test is placed failed. Other modules are skipped.
I want such thing: first to run all unit tests in all modules, and after that if there is no failed tests build all modules, or if there is one or more failed tests in one or mode modules skip building of all modules. Can you help me with it?
run:
mvn clean test
mvn install -Dmaven.test.skip=true
note, if you have inter-module dependencies (which i assume you do), you probably can't really do this, as you will need to build the dependent jars before you can run the tests in the other module.
AFAIK its impossible in maven. You are trying to change a maven build lifecycle which is not allowed in maven. However there are a couple of configuration parameters you can pass to maven and this will affect the testing.
mvn install -Dmaven.test.skip
This won't run unit tests at all
mvn install -Dmaven.test.failure.ignore=true
This will cause maven to not stop and proceed the module building process even if there were failures during the test phase.
Hope, this helps
The problem is:
the modules probably have dependencies upon each other, and to resolve those dependencies, you have to build the modules in order, or they won't compile. So there's no sane solution to your problem.
Insane solutions would somehow aggregate the sources (and external dependencies) from all child projects and run compile and test on that conglomerate, but it would be such a monstrous hack that I'm glad they didn't do it.
Let me explain some of my constraints.
We have a war that has a CXF Soap service and a Spring MVC REST Service. Both the CXF and Spring MVC implementations are in a separate jar and are brought in as dependencies. The REST service has its unit tests in its project.
I was wondering if there was any way to, while doing something like 'mvn clean test' in the REST jar, to have a local version of the war set up and then run the unit tests. Thus, when building in something like Hudson or doing releases, there won't have to be any workarounds (such as deploying a snapshot ear or running a local war manually)? I've seen this done when the tests are within the war using cargo, but not when the tests are separate from the war.
Right now, we're going to take the tests out into a separate jar but that's still not ideal as if something happens to go wrong during a release, that'd mean the REST jar and war were already released. I'd prefer do it the above way, with the tests in the same project as the REST service.
If anyone has any pointers or doc or examples that could help with this, it would be appreciated.
Honestly, I'm not sure I understood all the constraints. Anyway, the recommended way to implement integration tests with Maven is to put them in a separate module (that's much easier, especially if the module under test also have unit tests) that depends on the war/ear under test and to:
Start a container and deploy the war/ear during the pre-integration-test phase
Have Maven run the tests during integration-test
Stop the container during post-integration-test
For the steps #1 and #3, I personally use Cargo. For the step #2, using the Maven Failsafe Plugin is the preferred option (because it won't stop the build if a test fail). At least, this is what I use and I have used the resources below to build my setup.
An alternative approach would be to start/stop an embedded container from the tests. For example, this is doable with Jetty, see Embedding Jetty and Unit Test Servlets with Jetty.
Resources
Functional testing with Maven, Cargo and Selenium
Maven and Integration Testing
Maven and Selenium
Unit Test Servlets with Jetty
Maven has also integration-test phase. Use maven-jetty-plugin to start container and deploy application. Then run your integration test.
Maven Jetty Plugin
Maven and Integration Testing
Update
Tests cannot be in a jar file. Maven surefire plugin could not run them. The tests are part of the project where you run integration test. The tested war file can be set as dependency library. It will be downloaded, deployed and the you run integration tests.