How to upload Junit results to build through Java API
I'm currently running suites of tests in a bespoke Java test harness that collates the results into the appropriate XML format, after which an Ant script invokes the JunitLogPublisherTask to upload the results to the Jazz build that originally launched the test run.
This is working fine but test runs can be very long and uploading the results at the very end of the run means I have no visibility of passed/failed tests until then. I'd like to be able to update the test results in the Jazz build after each individual test completes, as the test run progresses. I'm already updating build activities for each running test and uploading log files from the tests dynamically using the Jazz Java API, but I can't seem to figure out how to get the Junit results updated.
So far I've tried the following:
1) Creating an IJUnitTestSuiteContribution and an IJUnitTestClass, populating their fields and then saving them via the build client, as below. These calls seem to complete successfully, but nothing appears in the test results.
IJUnitTestSuiteContribution contribution = BuildItemFactory.createJUnitTestSuiteContribution();
...
contribution = buildClient.save(contribution, null);
IJUnitTestClass testClass = BuildItemFactory.createJUnitTestClass();
...
testClass = buildClient.save(testClass, null);
There is also IJUnitTestCase, which I can create in a similar fashion but not save. It's not clear to me how all these objects tie together and how they should be used.
2) Create an IBuildResultContribution of IJUnitTestSuiteContribution type and populate its properties. It's not clear to me what format the properties should take (e.g. PROPERTY_TEST_CLASSES).
IBuildResultContribution contribution2 = BuildItemFactory.createBuildResultContribution();
contribution2.setExtendedContributionTypeId(IJUnitTestSuiteContribution.EXTENDED_CONTRIBUTION_TYPE_ID);
...
buildClient.addBuildResultContribution(resultHandle, contribution2, null);
This approach has some effect, in that my "Tests" tab for the relevant build in Eclipse displays an error message "An error occurred during the initialization of this page's contribution provider" with the following stack trace in the details:
java.lang.IllegalArgumentException: itemHandles contains a null element
at java.lang.Throwable.<init>(Throwable.java:67)
at com.ibm.team.repository.client.internal.ItemManager.validateItemHandles(ItemManager.java:2009)
at com.ibm.team.repository.client.internal.ItemManager.fetchPartialItems(ItemManager.java:1124)
at com.ibm.team.build.internal.java.ui.editors.result.junit.JUnitContributionProvider.initializeContributionProvider(JUnitContributionProvider.java:71)
at com.ibm.team.build.internal.ui.editors.result.BuildResultContributionProviderBase.doInitialization(BuildResultContributionProviderBase.java:85)
at com.ibm.team.build.internal.ui.editors.result.BuildResultContributionProviderBase$1.run(BuildResultContributionProviderBase.java:74)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)
Obviously what I've done has had some effect in the tab I want the results to appear in, but I'm not going about it in the right way!
Can anyone help resolve the above, or is there any example code on how to upload junit results through the Java API?
Thanks for any help you can give!
This is working fine but test runs can be very long and uploading the results at the very end of the run means I have no visibility of passed/failed tests until then. I'd like to be able to update the test results in the Jazz build after each individual test completes, as the test run progresses. I'm already updating build activities for each running test and uploading log files from the tests dynamically using the Jazz Java API, but I can't seem to figure out how to get the Junit results updated.
So far I've tried the following:
1) Creating an IJUnitTestSuiteContribution and an IJUnitTestClass, populating their fields and then saving them via the build client, as below. These calls seem to complete successfully, but nothing appears in the test results.
IJUnitTestSuiteContribution contribution = BuildItemFactory.createJUnitTestSuiteContribution();
...
contribution = buildClient.save(contribution, null);
IJUnitTestClass testClass = BuildItemFactory.createJUnitTestClass();
...
testClass = buildClient.save(testClass, null);
There is also IJUnitTestCase, which I can create in a similar fashion but not save. It's not clear to me how all these objects tie together and how they should be used.
2) Create an IBuildResultContribution of IJUnitTestSuiteContribution type and populate its properties. It's not clear to me what format the properties should take (e.g. PROPERTY_TEST_CLASSES).
IBuildResultContribution contribution2 = BuildItemFactory.createBuildResultContribution();
contribution2.setExtendedContributionTypeId(IJUnitTestSuiteContribution.EXTENDED_CONTRIBUTION_TYPE_ID);
...
buildClient.addBuildResultContribution(resultHandle, contribution2, null);
This approach has some effect, in that my "Tests" tab for the relevant build in Eclipse displays an error message "An error occurred during the initialization of this page's contribution provider" with the following stack trace in the details:
java.lang.IllegalArgumentException: itemHandles contains a null element
at java.lang.Throwable.<init>(Throwable.java:67)
at com.ibm.team.repository.client.internal.ItemManager.validateItemHandles(ItemManager.java:2009)
at com.ibm.team.repository.client.internal.ItemManager.fetchPartialItems(ItemManager.java:1124)
at com.ibm.team.build.internal.java.ui.editors.result.junit.JUnitContributionProvider.initializeContributionProvider(JUnitContributionProvider.java:71)
at com.ibm.team.build.internal.ui.editors.result.BuildResultContributionProviderBase.doInitialization(BuildResultContributionProviderBase.java:85)
at com.ibm.team.build.internal.ui.editors.result.BuildResultContributionProviderBase$1.run(BuildResultContributionProviderBase.java:74)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)
Obviously what I've done has had some effect in the tab I want the results to appear in, but I'm not going about it in the right way!
Can anyone help resolve the above, or is there any example code on how to upload junit results through the Java API?
Thanks for any help you can give!
2 answers
Thanks to Ralph and Sam above who pointed me to how I could discover the correct sequence of calls. I now have the updates working via the Java API. For anyone who is interested, the calls required are as follows:
IBuildResultContribution buildResultContribution = BuildItemFactory.createBuildResultContribution();
buildResultContribution.setExtendedContributionTypeId(IJUnitTestSuiteContribution.EXTENDED_CONTRIBUTION_TYPE_ID);
... // Set buildResultContribution fields for label, time taken, whether it impacts the primary build result and the status
IJUnitTestSuiteContribution junitTestSuiteContribution = BuildItemFactory.createJUnitTestSuiteContribution();
... // Set the build result and various failure/error fields on junitTestSuiteContribution
buildResultContribution.setExtendedContribution(junitTestSuiteContribution);
IJUnitTestClass junitTestClass = BuildItemFactory.createJUnitTestClass();
... // Set the build result and various failure/error fields on junitTestClass
junitTestSuiteContribution.getTestClasses().add(junitTestClass );
// Create one of the following for each test method in the above class
IJUnitTestCase junitTestCase = BuildItemFactory.createJUnitTestCase();
... // Set all the fields on junitTestCas
junitTestClass.getTestCases().add(testCase);
buildClient.save(junitTestSuiteContribution, null);
buildClient.save(junitTestClass, null);
buildClient.addBuildResultContribution(buildResultHandle, buildResultContribution, null);
Once the above calls are made, the results will appear in the Jazz build results.
IBuildResultContribution buildResultContribution = BuildItemFactory.createBuildResultContribution();
buildResultContribution.setExtendedContributionTypeId(IJUnitTestSuiteContribution.EXTENDED_CONTRIBUTION_TYPE_ID);
... // Set buildResultContribution fields for label, time taken, whether it impacts the primary build result and the status
IJUnitTestSuiteContribution junitTestSuiteContribution = BuildItemFactory.createJUnitTestSuiteContribution();
... // Set the build result and various failure/error fields on junitTestSuiteContribution
buildResultContribution.setExtendedContribution(junitTestSuiteContribution);
IJUnitTestClass junitTestClass = BuildItemFactory.createJUnitTestClass();
... // Set the build result and various failure/error fields on junitTestClass
junitTestSuiteContribution.getTestClasses().add(junitTestClass );
// Create one of the following for each test method in the above class
IJUnitTestCase junitTestCase = BuildItemFactory.createJUnitTestCase();
... // Set all the fields on junitTestCas
junitTestClass.getTestCases().add(testCase);
buildClient.save(junitTestSuiteContribution, null);
buildClient.save(junitTestClass, null);
buildClient.addBuildResultContribution(buildResultHandle, buildResultContribution, null);
Once the above calls are made, the results will appear in the Jazz build results.
I can't say from the information I have. As there is no documentation, you could search the SDK for example code. If you setup the SDK with the plain Java Client libraries as described in https://rsjazz.wordpress.com/2013/02/28/setting-up-rational-team-concert-for-api-development/ and https://rsjazz.wordpress.com/2013/03/20/understanding-and-using-the-rtc-java-client-api/ you can search for usage of the methods above. I was able to find its usage in com.ibm.team.build.client.tests.AbstractTeamBuildClientTests. It is usually a good idea to look into the SDK and the provided code for examples.
As an alternative, I was usually successful by looking at example data (e.g. build results with JUnit data published) and analyzing the content. I would suggest to go that path. You can also search the forums e.g. using the internal search or a search engine. I have looked quickly, but was not very successful. Maybe my search expression is not good enough.
As an alternative, I was usually successful by looking at example data (e.g. build results with JUnit data published) and analyzing the content. I would suggest to go that path. You can also search the forums e.g. using the internal search or a search engine. I have looked quickly, but was not very successful. Maybe my search expression is not good enough.
Comments
Thanks Ralph - I'll have a look in the SDK and see if I can find some examples. I was also unsuccessful searching for previous questions or examples on this topic. I'll report back here if I find anything.
Load the SDK
in eclipse,
set up SDK as the plugin target platform (window->preferences->plugin dev->target platform, new...)
import plugin com.ibm.team.build.toolkit as source
window->show view->plugins
find com.ibm.team.build.toolkit, right click, import as source
seeĀ com.ibm.team.build.internal.publishing.JUnitLogPublisher
Comments
Ralph Schoon
FORUM ADMINISTRATOR / FORUM MODERATOR / JAZZ DEVELOPER May 26 '14, 3:18 a.m.The build system toolkit has an ANT task for that. I'd suggest to use it.
With respect to the error, it appears that there is an ItemHandle in the data that is not valid.
Oliver Deakin
May 26 '14, 4:54 a.m.Thanks for the response Ralph.
I'm already using the JunitLogPublisherTask from Ant to publish results at the end of the run, but I'm looking for a way to upload the results as my tests are in progress. Calling out from our Java harness to Ant to execute the upload of results doesn't feel right when I'm already uploading logs and starting/completing activities through the Java API. It seems there should be a way to upload the Junit results directly through the Java API too - I expect this is exactly what the Ant task is doing, but I can't find any description or examples of how to do it.
I think you're absolutely right about that something in the itemHandles is not valid, but I don't really know what that means or how to resolve it! :)