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:&lt;0&gt; but was:&lt;4&gt;
            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.

  • No labels

9 Comments

  1. Anonymous

    Please can you produce a XSD so that it is possible to quickly validate

  2. Anonymous

    On my project, we use this http://windyroad.org/dl/Open%20Source/JUnit.xsd.

    It works fine (wink)

  3. Diego N. Pamio

    The link to Click here for the AntXmlResultParser.java doesn't work. 

    1. Diego N. Pamio

      Never 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).

    2. Anonymous

      Neither 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. 

  4. Anonymous

    How 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.

    1. James Dumay

      Both 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.

      1. Vlad Bachurin

        What 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?