Bamboo doesn't recognize test in my Spring project - maven

I have a Spring project (Apache CXF, Spring, Hibernate, Maven ...) hosted on BitBucket and I'm trying to use Bamboo as my CI server. My idea is deploying the code directly to Heroku from Bamboo so that deploying time is automated.
I made a plan with a couple of tasks to achieve this. First I have a Source Code Checkout task and a builder task. Both of them are working, code is compiling and test are passing, I can see that in the task log. The problem is that Bamboo doesn't seem to recognize the tests (it marks the task are testless).
I have also tried to create a new JUnit test task and it's even worst. Log shows that everything is working properly but Bamboo marks the plan as a failure after the test task is executed.
Any ideas?

Not sure which version of Bamboo you're using, but in the version that we have, you have to turn on unit test result evaluation on the Builder tab. Please see the attached screenshot, and make sure that this is enabled, and the directory setting is pointing to the directory where Maven Surefire creates the test results (in XML format).

Related

Running jacoco report where integration tests are in one code base and source code is in another code base

I recently started working on creating jacoco reports for maven projects including unit and integration tests and they seem to work out correctly.
Now I have encountered a different scenario which I am not sure how to approach.
I have one workspace which consists of integration test cases - application A, but the source code does not exist in the same workspace/code base. The source code which actually runs on invoking these integration test scripts are in a different workspace/code base - application B(they are invoked using rest api calls with the localhost urls. The jboss server is started for application B so that the localhost context is up) from the integration tests.
The aim is to invoke these integration tests from application A, which in turn calls the source code of these tests in application B generating the jacoco report of the code coverage for application B.
I am not actually sure how to achieve this.
Can someone provide some input.
Thanks.
If I understand you correctly, you actually have 2 different processes in your scenario:
The "client" process that runs the integration tests and for which jacoco can be easily applied, but it's not what you need
The "server" process that runs the actual JBoss server and executes the actual code.
Client process contacts the server via HTTP.
In this case, I'm afraid jacoco won't be able to provide a coverage for you if you're running the tests from maven/gradle, because jacoco instruments only bytecode on the running JVM. So you have to be "creative" here :)
I'll list here some possible approaches
Disclaimer: I haven't tried them though (didn't work with jboss/java ee), but maybe you'll be able to at least borrow some ideas
The first approach would be running the tests together with the application somehow, like its done for example in spring tests (I'm not sure whether JBoss provides similar capabilities).
The idea is simple:
You run the integration test, it runs the jboss "embedded in the same jvm" and you can inject beans / EJB session beans into the test (like autowiring with spring).
The advantage of such a method is that you'll be able just to use jacoco maven plugin and it will instrument everything for you
I don't know how easy will be achieving this architecture technically, I know that recent jboss versions support embedded mode, So maybe you'll find This link to be a useful foundation
Another direction is to take a look at Arquillian project. They have some jacoco extension that probably will help, but I've never tried it.
And the last approach I can think of is running the jboss server with jacoco agent directly instead of relying on the build system that runs jacoco for you.
The idea here is to stream the results of covered server code into some file / tcp endpoint. So you run the jboss with -javaagent:[yourpath/]jacocoagent.jar and it starts streaming the results wherever you need it to stream. After the tests you should gather these results and prepare a report. You can find Here more information about this approach

How to check test quality with Sonar?

Currently, we are using Sonar to check the quality of our production code. I would Like to check the quality of the test Code either.
How can I do it ?
I tried to change the "sonar.sources" to include test, but in this case i have an error : test folders are defined twice, one in test and one in source.
May be I can configure sonar / maven / jenkins to run 2 analysis : first one, the src code, with the test coverage, thant the tests (only quality, no coverage). But I also need to have everything run in a single jenkins job and displayed in a single Sonar Project.
And I don't know where to configure (pom ? sonar ? jenkins ?) I found some things about profiles, but it seems to be deprecated for my version.
I'm using Sonar 5.1, run from a jenkins job.
our Sonar properties in the pom are :
<project.testresult.directory>${project.build.directory}/test-results</project.testresult.directory>
<run.addResources>false</run.addResources>
<sonar-maven-plugin.version>2.6</sonar-maven-plugin.version>
<sonar.exclusions>src/main/webapp/assets/**/*.*,
src/main/webapp/bower_components/**/*.*,
src/main/webapp/dist/**/*.*</sonar.exclusions>
<sonar.jacoco.itReportPath>${project.testresult.directory}/coverage/jacoco/jacoco-it.exec</sonar.jacoco.itReportPath>
<sonar.jacoco.reportPath>${project.testresult.directory}/coverage/jacoco/jacoco.exec</sonar.jacoco.reportPath>
<sonar.java.codeCoveragePlugin>jacoco</sonar.java.codeCoveragePlugin>
<sonar.javascript.jstestdriver.reportsPath>${project.testresult.directory}/karma</sonar.javascript.jstestdriver.reportsPath>
<sonar.javascript.lcov.reportPath>${project.testresult.directory}/coverage/report-lcov/lcov.info</sonar.javascript.lcov.reportPath>
<sonar.sources>${project.basedir}/src/main/</sonar.sources>
<sonar.surefire.reportsPath>${project.testresult.directory}/surefire-reports</sonar.surefire.reportsPath>
<sonar.tests>${project.basedir}/src/test/</sonar.tests>
In the latest versions of the Java plugin there are some rules to check tests, but they are test-specific rules. I.E. they check if your #Test methods contain assertions &etc. You simply need to add those rules to your profile.
If, however, you're talking about running "code rules" on your tests, then your best bet is probably to define another project where the tests are treated as sources. Since you've already noted the difficulties of doing that with Maven, I would use SonarQube Scanner for this separate, second analysis.

How to run tests after deployment using Maven?

I'm trying to decide how to create a set of Acceptance Tests for a Java-EE web application.
Here's the setup: Maven is used to generate a WAR file and deploy it into Glassfish. On deployment, the MySQL database schema is automatically updated from model classes using Hibernate ("hbm2ddl=auto" option).
The Acceptance Tests need to test the deployed code by invoking various methods and checking the results are as expected(*). We wrote an additional set of packages to hook into an existing system so the Acceptance Tests should show how these can be integrated into the existing codebase.
(*) This may sound more like Unit/Integration Testing but they are Acceptance Tests in the sense that they should prove what we did works and they need to be run after deployment so there is a database in place.
From the above, my current thinking is to use JUnit to check expected values etc. The bit I'm struggling with is how to invoke these tests after deployment. "deploy" is Maven's last phase so not sure if this is possible?
Just because that phase is called deploy doesn't mean that you have to use it for deploying your application for testing. In fact, it should only be used for "deploying" the artifact to a maven repository. Read through the description of the Maven lifecycle phases and you'll see that there are some phases dedicated to your use case:
pre-integration-test
integration-test
post-integration-test
Have a look at the Cargo Maven plugin. It's made to deploy your WAR file to various containers for testing. They definitely show demos of use cases like the one you describe on your site. I would expect that ultimately, you can be using Cargo to deploy to your container ( from one of the earlier phases like pre-integration-test )
Note, Jenkins also has a plugin that is a wrapper around the Cargo plugin. So you might do what you need via Jenkins. Also note, you don't need to run your Jenkins build job as mvn clean deploy. You could have one build job that just runs the integration tests, and fires another "deploy" job only when it succeeds.
If you really need to do stuff after deployment, then you can either run failsafe, and by implication JUnit) as part of the deploy phase.
What I usually do, if to have seperate module. So, you can have one maven project, which contains your project and a separate 'deployment test' project. Then, building the parent project will build and run your war and then run the deployment tests. You can use junit as normal.
The second fits better into jenkins because you'll still have a single project as well.

What is the "maven way" for this ant development workflow?

How can maven be configured to support this type of workflow:
One Time Setup Invoke maven to do one time setup of a developers machine such as
Create a custom version of tomcat configured for this application
Create a local postgres database on the developers machine
load sample data into the database
run a junit test to configure other resources needed to run the application
Integration Tests Invoke maven to do run integration tests which should do the following
Create an integration test db
setup the db
Run command line integration tests against the db
Run a test version of tomcat with the application in it
Run command line junit tests that test the restful services exposed by the application
Release Build Invoke maven to do a release build of the system
do all the steps for an integration test
generate resources and configurations that are used on the server rather than production
deposit the end result in a git repo, commit, and push the changes to production
Test Build Invoke maven to do a test build of the system
do all the steps of a release build but configure the test release package with test server configuration
The main thing I am struggling with is that maven has a single build life-cycle with a well defined sequence of phases not sure if the workflow I want to build is a good fit for maven.
Can maven be configured for this type of workflow? If yes what are the key features of maven that allow for the different configurations of the four main ways that I want to use maven?
Update What I mean by this workflow, is that I want to be able to do something like
mvn setup
mvn integration
mvn prod-release
mvn test-release
I know the above example look like ant, I am long time ant user and total noob with maven.
You could setup Maven to do all that...
You probably would use (shock horror) profiles to achieve some of this...
BUT you don't want to do that
You are following ANT style thinking... if you like that style of thinking then use ANT or Gradle and be happy.
If you want to follow the Maven way, then you will solve the problem differently.
Coming from the Maven way, here are my thoughts:
Why do you need one-time setup? I usually have a run profile that dynamically provisions the correct application server and starts it with the App deployed, tearing down everything afterwards when I hit ^C. Typically this involves starting up a database server or two... hence things I have developed like the cassandra-maven-plugin. That way when I am working on a different project (which could be in 10 minutes time) I don't have to worry about background database servers eating up all my laptop's ram.
Integration tests are actually trivial when you have the above working... in fact I created the Maven Failsafe Plugin to make it easy to have plugin execution tied to the appropriate phases for integration testing. The Maven convention is to have a profile called run-its for running integration tests.
Release builds being different from test builds... ugh! You should be building environment agnostic artifacts. Have them pick up their configuration from the environment they are deployed in. That removes the worry that something has changed between the "test" build and the "production" build. If you really need to bundle the config, then I usually would resort to a separate module for taking the agnostic artifact and rebundling with the required configuration. That way it is easy to prove that you have a reproducible transformation and that nothing has changed inbetween what went to QA vs what is going to Ops.
I always make the release builds include the integration testing.
So typically I have my projects such that
$ mvn -Prun
will fire up the application starting from zero. Hitting ^C will tear everything back down again, and mvn clean or in extreme situations if I have a more complex setup process and need some caching mvn post-clean (think really clean) will remove anything that the run profile put into play
To run the integration tests I typically do
$ mvn -Prun-its verify
To make a release I typically do
$ mvn release:prepare release:perform -B
That is (in my view) the ideal way of handling the above steps you need.
HTH.
BTW I have not had to use PostgreSQL specifically (typically my integration tests and run profile can get away with a pure java database such as derby or hsqldb and because the artifacts are environment agnostic it is easy to have the integration test/dev flyweight app server inject the correct JDBC url) so you may hit some issues with regard to PostgreSQL

maven cargo integration test - how to get cargo.hostname or profile?

I'm using Maven 2 w/ cargo to deploy to different remote tomcats depending on the maven profile used.
I also have integration tests (junit w/ remote webservice calls) that I would like to automatically run.
Question: How do I setup my test code to be able to read either the cargo.hostname (preferred, changed property value based on maven profile) or the maven profile actived so it knows which url to go run the tests against?
Specifically, this is in java in the test case.
Thanks!
Either you define a fixed value for the cargo.hostname (not the best; but sometimes it workds well, cause using a fixed test server) or better define an appropriate property in Maven for it and put the information also into a properties file which will be filtered by the build process in the src/test/resources folder which can be read before the real integration tests.

Resources