Bamboo can parse any test output that conforms to standard JUnit XML format. The implementation of this is pretty simple — Bamboo looks for specific tags in the JUnit XMl output.
A failed JUnit XML report, that is successfully parsed by Bamboo.
<?xml version="1.0" encoding="UTF-8" ?>
<testsuite errors="0" tests="3" time="0.391" failures="1"
name="com.atlassian.bamboo.repository.perforce.PerforceSyncCommandTest">
<properties>
<property value="Java(TM) 2 Runtime Environment, Standard Edition" name="java.runtime.name"/>
<property value="UnicodeBig" name="sun.io.unicode.encoding"/>
.............
</properties>
<testcase time="0.001" name="testGeneratesCorrectP4CommandLine"/>
<testcase time="0" name="testGettersReturnExpectedStuff"/>
<testcase time="0.164" name="testUsingPerforceWhenNoFilesHaveChanged">
<failure type="junit.framework.AssertionFailedError"
message="Should not have any errors. [Perforce client error:, Connect to server failed; ">
junit.framework.AssertionFailedError: Should not have any errors. [Perforce client error:, Connect to server
failed; check $P4PORT., TCP connect to keg failed., keg: host unknown.] expected:<0> but was:<4>
at junit.framework.Assert.fail(Assert.java:47)
at junit.framework.Assert.failNotEquals(Assert.java:282)
at junit.framework.Assert.assertEquals(Assert.java:64)
at junit.framework.Assert.assertEquals(Assert.java:201)
at com.atlassian.bamboo.repository.perforce.PerforceSyncCommandTest.testUsingPerforceWhenNoFilesHaveChanged(PerforceSyncCommandTest.java:60)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at sun.reflect.GeneratedMethodAccessor17.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.apache.maven.surefire.battery.JUnitBattery.executeJUnit(JUnitBattery.java:242)
at org.apache.maven.surefire.battery.JUnitBattery.execute(JUnitBattery.java:216)
at org.apache.maven.surefire.Surefire.executeBattery(Surefire.java:215)
at org.apache.maven.surefire.Surefire.run(Surefire.java:163)
at org.apache.maven.surefire.Surefire.run(Surefire.java:87)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.apache.maven.surefire.SurefireBooter.runTestsInProcess(SurefireBooter.java:313)
at org.apache.maven.surefire.SurefireBooter.run(SurefireBooter.java:221)
at org.apache.maven.test.SurefirePlugin.execute(SurefirePlugin.java:371)
at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:412)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:534)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalWithLifecycle(DefaultLifecycleExecutor.java:475)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:454)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:306)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:273)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:140)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:322)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:115)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:256)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
</failure>
<system-out>
PerforceSyncCommand.command: /usr/local/bin/p4
</system-out>
</testcase>
</testsuite>
Click here to download the XML report.
A passed JUnit XML report, that is successfully parsed by Bamboo.
<?xml version="1.0" encoding="UTF-8" ?>
<testsuite errors="0" skipped="0" tests="1" time="0.045" failures="0" name="com.atlassian.bamboo.labels.LabelManagerImplTest">
<properties>
<property value="Java(TM) 2 Runtime Environment, Standard Edition" name="java.runtime.name"/>
<property value="/usr/java/jdk1.5.0_07/jre/lib/i386" name="sun.boot.library.path"/>
<property value="1.5.0_07-b03" name="java.vm.version"/>
<property value="Sun Microsystems Inc." name="java.vm.vendor"/>
<property value="http://java.sun.com/" name="java.vendor.url"/>
<property value=":" name="path.separator"/>
<property value="Java HotSpot(TM) Client VM" name="java.vm.name"/>
<property value="sun.io" name="file.encoding.pkg"/>
<property value="US" name="user.country"/>
<property value="unknown" name="sun.os.patch.level"/>
<property value="Java Virtual Machine Specification" name="java.vm.specification.name"/>
<property value="/opt/bamboo-data/bamboohome/xml-data/build-dir/BAM-MAIN" name="user.dir"/>
<property value="1.5.0_07-b03" name="java.runtime.version"/>
<property value="sun.awt.X11GraphicsEnvironment" name="java.awt.graphicsenv"/>
<property value="/opt/bamboo-data/bamboohome/xml-data/build-dir/BAM-MAIN/bamboo-core" name="basedir"/>
<property value="/usr/java/jdk1.5.0_07/jre/lib/endorsed" name="java.endorsed.dirs"/>
<property value="i386" name="os.arch"/>
<property value="/tmp" name="java.io.tmpdir"/>
<property value="Sun Microsystems Inc." name="java.vm.specification.vendor"/>
<property value="Linux" name="os.name"/>
<property value="/opt/java/tools/maven2/bin/m2.conf" name="classworlds.conf"/>
<property value="ISO-8859-1" name="sun.jnu.encoding"/>
<property value="/usr/java/jdk1.5.0_07/jre/lib/i386.." name="java.library.path"/>
<property value="Java Platform API Specification" name="java.specification.name"/>
<property value="49.0" name="java.class.version"/>
<property value="HotSpot Client Compiler" name="sun.management.compiler"/>
<property value="2.6.15-1.1833_FC4smp" name="os.version"/>
<property value="/home/bamboo" name="user.home"/>
<property value="Australia/Sydney" name="user.timezone"/>
<property value="sun.print.PSPrinterJob" name="java.awt.printerjob"/>
<property value="ISO-8859-1" name="file.encoding"/>
<property value="1.5" name="java.specification.version"/>
<property value="bamboo" name="user.name"/>
<property value="/opt/java/tools/maven2/boot/classworlds-1.1.jar" name="java.class.path"/>
<property value="1.0" name="java.vm.specification.version"/>
<property value="32" name="sun.arch.data.model"/>
<property value="/usr/java/jdk1.5.0_07/jre" name="java.home"/>
<property value="Sun Microsystems Inc." name="java.specification.vendor"/>
<property value="en" name="user.language"/>
<property value="mixed mode, sharing" name="java.vm.info"/>
<property value="1.5.0_07" name="java.version"/>
<property value="/usr/java/jdk1.5.0_07/jre/lib/ext" name="java.ext.dirs"/>
<property value="Sun Microsystems Inc." name="java.vendor"/>
<property value="/opt/java/tools/maven2" name="maven.home"/>
<property value="/home/bamboo/.m2/repository" name="localRepository"/>
<property value="/" name="file.separator"/>
<property value="http://java.sun.com/cgi-bin/bugreport.cgi" name="java.vendor.url.bug"/>
<property value="little" name="sun.cpu.endian"/>
<property value="UnicodeLittle" name="sun.io.unicode.encoding"/>
<property value="" name="sun.cpu.isalist"/>
</properties>
<testcase time="0.045" name="testBAM1436"/>
</testsuite>
Click here to download the XML report.
Click here for the AntXmlResultParser.java file which contains the Bamboo code for parsing JUnit XML output.
For those interested in the XUint XML Schema, please see this document.
9 Comments
Anonymous
Nov 11, 2010Please can you produce a XSD so that it is possible to quickly validate
Anonymous
May 14, 2012Try http://jra1mw.cvs.cern.ch:8180/cgi-bin/jra1mw.cgi/org.glite.testing.unit/config/JUnitXSchema.xsd?view=markup
Anonymous
Nov 09, 2011On my project, we use this http://windyroad.org/dl/Open%20Source/JUnit.xsd.
It works fine
Diego N. Pamio
Apr 26, 2012The link to Click here for the AntXmlResultParser.java doesn't work.
Diego N. Pamio
Apr 26, 2012Never mind, I've found it attached in this page.
Question: how do I change the URL of the link that links the current failing test to the "test page"? I want to redirect that to a custom-made page (an HTML inside the build's artifacts).
Anonymous
Apr 02, 2013Neither do the "Click here to download the XML report" links.
Which is not big deal, but I thought I'd point that one out too.
Anonymous
Nov 21, 2013How does JUnit parser figure out which test cases are the same when quarantining them? It seems class name is not the most significiant value as the source code seems to suggest.
James Dumay
Nov 21, 2013Both the class name and test method name are used to uniquely define the test and its quarantined state. If you are having troubles with quarantine (and this appears to you not to be the case) please contact support.
Vlad Bachurin
Dec 12, 2013What if class and method name pair is the same along the whole test? (in my case, if JUnit Parser is used for TestNG tests with DataProvider). Will Bamboo think that the test method was executed only once in this case? If yes, is there a way to make Bamboo display the correct count?