Jenkins thinks failing junit test is passing - java

One stage in my Jenkins pipeline runs mvn verify. My test phase is broken into two execution stages, and in the second stage, one of the junit tests from the first stage is re-run with different parameters. This all works perfectly locally with Maven.
When Jenkins runs this with the same configs, it seems to ignore the repeated test in the second phase. If that test fails, Jenkins reports that all tests pass, even though in the Jenkins console logs I can see that the test did fail.
Is there a Jenkins-friendly way of re-running the same test in two different execution stages?
My Maven pom.xml file contains:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>default-test</id>
<goals>
<goal>test</goal>
</goals>
<configuration>
<!-- some configs -->
</configuration>
</execution>
<execution>
<id>another-test</id>
<goals>
<goal>test</goal>
</goals>
<configuration>
<!-- some configs -->
</configuration>
</execution>
</executions>
</plugin>

Related

Integration test run twice . Once due to FailSafe plugin for Jacoco and another due to Jbehave maven plugin

I have this pom file for the restful web service java project , where in we were using the Jbehave maven plugin for running integration tests and generating test execution reports . As part of a new process , i had to implement the Jacoco in project in the same pom file [ using Surefire and Failsafe plugins ] to generate code coverage reports . Now the issue is that the integration test cases are running twice causing issues in the Test Db's [ once for Jbehave and another time for Jacoco FailSafe plugin ] . IS there a way to modify the pom file to ensure Jacoco FailSafe as well as Jbehave runs as a single goal generating their respective reports [ i.e integration tests are executed only once ]
Tried commenting out either the Jacoco fail safe goal or Jbehave in which case integration tests are run only once , but unable to find a way to modify the pom file to make sure both goals get executed but integration test case is run only once
Pom file configuration if possible to make sure both Jbehave maven plugin as well as Jacoco failsafe plugin goals are executed but the integration test is run only once
<plugin>
<groupId>org.jbehave</groupId>
<artifactId>jbehave-maven-plugin</artifactId>
<version>$(jbehave.core.version)</version>
<executions>
<execution>
<id>unpack-view-resources</id>
<phase>pre-integration-test</phase>
<goals>
<goal>unpack-view-resources</goal>
</goals>
<configuration>
<scope>test</scope>
</configuration>
</execution>
<execution>
<id>embeddable-stories</id>
<phase>integration-test</phase>
<goals>
<goal>run-stories-as-embeddables</goal>
</goals>
<configuration>
<includes>
<include>**/Stories.java</include>
</includes>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.5.201505241946</version>
<executions>
<!-- The Executions required by unit tests are omitted. -->
<!--
Prepares the property pointing to the JaCoCo runtime agent which
is passed as VM argument when Maven the Failsafe plugin is executed.
-->
<execution>
<id>pre-integration-test</id>
<phase>pre-integration-test</phase>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<!-- Sets the path to the file which contains the execution data. -->
<destFile>${project.build.directory}/coverage-reports/jacoco-it.exec</destFile>
<!--
Sets the name of the property containing the settings
for JaCoCo runtime agent.
-->
<propertyName>failsafeArgLine</propertyName>
</configuration>
</execution>
<!--
Ensures that the code coverage report for integration tests after
integration tests have been run.
-->
<execution>
<id>post-integration-test</id>
<phase>post-integration-test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<!-- Sets the path to the file which contains the execution data. -->
<dataFile>${project.build.directory}/coverage-reports/jacoco-it.exec</dataFile>
<!-- Sets the output directory for the code coverage report. -->
<outputDirectory>${project.reporting.outputDirectory}/jacoco-it</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.15</version>
<executions>
<!--
Ensures that both integration-test and verify goals of the Failsafe Maven
plugin are executed.
-->
<execution>
<id>integration-tests</id>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<!-- Sets the VM argument line used when integration tests are run. -->
<argLine>${failsafeArgLine}</argLine>
<includes>
<include>**/Stories.java</include>
</includes>
<!--
Skips integration tests if the value of skip.integration.tests property
is true
-->
<skipTests>${skip.integration.tests}</skipTests>
</configuration>
</execution>
</executions>
</plugin>

Maven - run post-integration phase when CTRL-C is pressed

I am using the failsafe plugin to make sure that the post-integration phase is run when an integration test fails. This is necessary to make sure that all resources are cleaned up, such as docker containers.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.20.1</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
However, when I press CTRL-C during the integration tests, the Maven script halts immediately, without running the post-integration phase. This leaves dangling resources.
Can this behavior be overridden?

custom java action in maven phase

i am using javemelody to monitor performance of my app. i am using jetty maven plugin which starts up during mvn install and runs all test cases before generating the war. i wanted to generate a pdf report at the end of post-integration-test phase.
<execution>
<id>stop-jetty</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
i was thinking if i can access the report url of embedded jetty to access javamelody, then maybe i can download my report to some location like using
curl localserver/context/monitoring?reports=pdf
is it possible to execute a custom script/java program in the post-integration-test phase before shutting down the embedded jetty ?
I would suggest to start jetty in the pre-integration-test phase do what ever you need to do in the integration-test phase and shutdown in post-integration phase.
Everything you need to do can be run via an integration test by the usage of the maven-failsafe-plugin.
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.16</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>
with the above setup you can simply write an integration test for example WhatEverINeedToDoIT.java in src/test/java location and run it.

Code coverage of client/server web application

I am writing a multi-module application. Some of the modules are just basic Java libraries which are then included in the WAR of a webapp.
I would like to run code coverage in the following scenario:
I am running the webapp through an embedded Jetty that is started via Maven.
I have tests which are executing HTTP requests against the webapp.
I would like to get code covered in the webapp and also by the tests.
Is this possible and how can it be achieved with Cobertura, JaCoCo or Emma? From what I understand, the code coverage will only cover the client-side code in this scenario. Am I correct?
I think if you would manage to attach the JaCoCo-agent to the jvm that runs the jetty, it should be able to measure which code has been called over the time you run the integration tests against your webapp. So you should get a statistic that shows you the code coverage.
There is a JaCoCo Maven Plugin - though I'm not sure if this will help with you scenario. Just used it during unit tests.
Edit: found a blog-post that seems to point in the right direction here
Measure Code Coverage by Integration Tests with Sonar
Here's how I achieved it
Assuming you already have a minimal pom.xml config:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</
<version>0.7.4.201502262128</vers
</plugin>
Download JaCoCo's agent and copy jacocoagent.jar to a suitable location (e.g. $HOME/tools/jacocoagent0.7.4.jar)
Attach JaCoCo's agent to Maven's JVM via:
export MAVEN_OPTS="$MAVEN_OPTS \
-javaagent:$HOME/tools/jacocoagent0.7.4.jar=output=tcpserver,port=6300"
Run your application with embedded jetty server e.g. mvn jetty:run
Run your integration tests
In another shell, dump and report via mvn jacoco:dump jacoco:report
Open your report on ./target/site/index.html (by default)
You can use Jacoco plugin to generate code coverage Here is the plugin configuration I used for junit test code coverage.
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.5.10.201208310627</version>
<configuration>
<skip>${maven.test.skip}</skip>
<output>file</output>
<append>true</append>
</configuration>
<executions>
<execution>
<id>jacoco-initialize</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>jacoco-site</id>
<phase>verify</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
Note: you may get life cycle not covered error in maven while using eclipse, one way is you explicitly mention the life cycle using plugin management. I installed the jacoco plugin from the market place which resolved my problem
We had a similar scenario where integration test were run on a jetty server. Also we needed a combined report for all the tests unit and integration. The solution we implemented was to run-forked jetty and pass the jvmargs with the jacoco javaagent details. Our code coverage reports covered all the rest api's and the service layer java code.
The pom config for jacoco
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco-maven-plugin.version}</version>
<configuration>
<append>true</append>
</configuration>
<executions>
<execution>
<id>prepare-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<destFile>${project.build.directory}/jacoco.exec</destFile>
<propertyName>surefireArgLine</propertyName>
</configuration>
</execution>
<execution>
<id>prepare-integration</id>
<goals>
<goal>prepare-agent-integration</goal>
</goals>
<configuration>
<destFile>${project.build.directory}/jacoco.exec</destFile>
<propertyName>failsafeArgLine</propertyName>
</configuration>
</execution>
</executions>
</plugin>
With the above config we generated a common exec file for both unit and integration test. Next we configured jetty to run-forked
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty-maven-plugin.version}</version>
<configuration>
<stopKey>foo</stopKey>
<stopPort>9999</stopPort>
<webApp>
<contextPath>/myway</contextPath>
<descriptor>src/main/webapp/WEB-INF/web.xml</descriptor>
</webApp>
<!-- passing the jacoco plugin as a jvmarg -->
<jvmArgs>${failsafeArgLine}</jvmArgs>
</configuration>
<executions>
<execution>
<id>start-jetty</id>
<phase>pre-integration-test</phase>
<configuration>
<daemon>true</daemon>
<waitForChild>false</waitForChild>
</configuration>
<goals>
<goal>run-forked</goal>
</goals>
</execution>
<execution>
<id>stop-jetty</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
This would launch jetty in a separate jvm with the jvmargs. Finally we generated the report in the reporting tag of the pom. We noticed that adding the report to the build plugins did not capture the integration tests run by the jetty.
<reporting>
</plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco-maven-plugin.version}</version>
<reportSets>
<reportSet>
<id>jacoco-report</id>
<reports>
<report>report</report>
</reports>
</reportSet>
</reportSets>
</plugin>
</plugins>
</reporting>
The reports can be accessed at target/site/jacoco/index.html, alternately you can run it from the command line.
mvn jacoco:report
Hope it helps.

Glassfish container via Cargo isn't stopped by maven when integration tests fail

I've setup Cargo to start an instance of glassfish during the pre-integration-test phase in a maven profile. My tests are then run in the integration-test phase and, finally, cargo shuts down the tomcat instance in the post-integration-test phases.
This works great when all tests pass, but if any test fails, the maven build fails, and it appears that the post-integration-test phase is never reached, which leaves the glassfish instance running (and me unable to stop it without killing the process).
Am I doing something wrong? Is there a way to make sure cargo shuts down my glassfish instance, even if the integration-test phase fails?
My maven profile:
<profile>
<!-- run integration tests against the app deployed to a container -->
<id>integration</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<!-- override the exclusion and include integration tests -->
<excludes>
<exclude>none</exclude>
</excludes>
<includes>
<include>***IntegrationTest.java</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>${cargo.plugin.version}</version>
<executions>
<execution>
<id>start-server</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>stop-server</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
<configuration>
<container>
<containerId>glassfish3x</containerId>
<artifactInstaller>
<groupId>org.glassfish.main.distributions</groupId>
<artifactId>glassfish</artifactId>
<version>${glassfish.version}</version>
</artifactInstaller>
</container>
<configuration>
<properties>
<cargo.datasource.datasource.mysql>
cargo.datasource.jndi=jdbc/TrackerPool|
cargo.datasource.driver=com.mysql.jdbc.Driver|
cargo.datasource.url=jdbc:mysql://localhost/[database]|
cargo.datasource.transactionsupport=LOCAL_TRANSACTION|
cargo.datasource.username=[username]|
cargo.datasource.password=[password]
</cargo.datasource.datasource.mysql>
</properties>
</configuration>
</configuration>
</plugin>
</plugins>
</build>
</profile>
The problem is simply based in the wrong usage of the maven-surefire-plugin which is intended for using in relation with unit test but not for integration tests. For such purposes the maven-failsave-plugin exist which will solve your problem.
The usage of the maven-failsave-plugin release you from defining of include rule for integration tests. The usual naming convention in Maven for integration tests is like this:
IT*.java
*IT.java
*ITCase.java
So i would suggest to name your integration tests accordingly so you don't need any kind of exlude/include rule neither for maven-surefire-plugin (unit tests) nor for maven-failsafe-plugin (integration tests).
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.13</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
The verify goal is only needed if you like to fail your build in case of failing integration tests. You have to call maven like this:
mvn -Pprofile clean verify

Categories

Resources