Package: unittest-xml-reporting
unittest-xml-reporting (aka xmlrunner)A unittest test runner that can save test results to XML files in xUnit format.
The files can be consumed by a wide range of tools, such as build systems, IDEs
and continuous integration servers.RequirementsPython 3.7+Please note Python 3.6 end-of-life was in Dec 2021, last version supporting 3.6 was 3.1.0Please note Python 3.5 end-of-life was in Sep 2020, last version supporting 3.5 was 3.1.0Please note Python 2.7 end-of-life was in Jan 2020, last version supporting 2.7 was 2.5.2Please note Python 3.4 end-of-life was in Mar 2019, last version supporting 3.4 was 2.5.2Please note Python 2.6 end-of-life was in Oct 2013, last version supporting 2.6 was 1.14.0Limited support forunittest.TestCase.subTesthttps://docs.python.org/3/library/unittest.html#unittest.TestCase.subTestunittesthas the concept of sub-tests for aunittest.TestCase; this doesn't map well to an existing xUnit concept, so you won't find it in the schema. What that means, is that you lose some granularity
in the reports for sub-tests.unittestalso does not report successful sub-tests, so the accounting won't be exact.Jenkins pluginsJenkins JUnit plugin :https://plugins.jenkins.io/junit/Jenkins xUnit plugin :https://plugins.jenkins.io/xunit/Jenkins JUnit pluginThis plugin does not perform XSD validation (at time of writing) and should parse the XML file without issues.Jenkins xUnit plugin version 1.100Jenkins (junit-10.xsd), xunit plugin (2014-2018), version1.100.This plugin does perfom XSD validation and uses the more lax XSD. This should parse the XML file without issues.Jenkins xUnit plugin version 1.104+Jenkins (junit-10.xsd), xunit plugin (2018-current), version1.104+.This plugin does perfom XSD validation and uses the more strict XSD.Seehttps://github.com/xmlrunner/unittest-xml-reporting/issues/209import io
import unittest
import xmlrunner

# run the tests storing results in memory
out = io.BytesIO()
unittest.main(
    testRunner=xmlrunner.XMLTestRunner(output=out),
    failfast=False, buffer=False, catchbreak=False, exit=False)Transform the results removing extra attributes.from xmlrunner.extra.xunit_plugin import transform

with open('TEST-report.xml', 'wb') as report:
    report.write(transform(out.getvalue()))JUnit Schema ?There are many tools claiming to write JUnit reports, so you will find many schemas with minor differences.We used the XSD that was available in the Jenkins xUnit plugin version1.100; a copy is available undertests/vendor/jenkins/xunit-plugin/.../junit-10.xsd(see attached license).You may also find these resources useful:https://stackoverflow.com/questions/4922867/what-is-the-junit-xml-format-specification-that-hudson-supportshttps://stackoverflow.com/questions/11241781/python-unittests-in-jenkinsJUnit-Schema (JUnit.xsd)Windyroad (JUnit.xsd)a gist (Jenkins xUnit test result schema)InstallationThe easiest way to install unittest-xml-reporting is viaPip:$pipinstallunittest-xml-reportingIf you use Git and want to get the latestdevelopmentversion:$gitclonehttps://github.com/xmlrunner/unittest-xml-reporting.git
$cdunittest-xml-reporting
$sudopythonsetup.pyinstallOr get the latestdevelopmentversion as a tarball:$wgethttps://github.com/xmlrunner/unittest-xml-reporting/archive/master.zip
$unzipmaster.zip
$cdunittest-xml-reporting
$sudopythonsetup.pyinstallOr you can manually download the latest released version fromPyPI.Command-linepython-mxmlrunner[options]python-mxmlrunnerdiscover[options]# helppython-mxmlrunner-he.g.python-mxmlrunnerdiscover-t~/mycode/tests-o/tmp/build/junit-reportsUsageThe script below, adapted from theunittest, shows how to useXMLTestRunnerin a very simple way. In fact, the only difference between
this script and the original one is the last line:importrandomimportunittestimportxmlrunnerclassTestSequenceFunctions(unittest.TestCase):defsetUp(self):self.seq=list(range(10))@unittest.skip("demonstrating skipping")deftest_skipped(self):self.fail("shouldn't happen")deftest_shuffle(self):# make sure the shuffled sequence does not lose any elementsrandom.shuffle(self.seq)self.seq.sort()self.assertEqual(self.seq,list(range(10)))# should raise an exception for an immutable sequenceself.assertRaises(TypeError,random.shuffle,(1,2,3))deftest_choice(self):element=random.choice(self.seq)self.assertTrue(elementinself.seq)deftest_sample(self):withself.assertRaises(ValueError):random.sample(self.seq,20)forelementinrandom.sample(self.seq,5):self.assertTrue(elementinself.seq)if__name__=='__main__':unittest.main(testRunner=xmlrunner.XMLTestRunner(output='test-reports'),# these make sure that some options that are not applicable# remain hidden from the help menu.failfast=False,buffer=False,catchbreak=False)Reporting to a single fileif__name__=='__main__':withopen('/path/to/results.xml','wb')asoutput:unittest.main(testRunner=xmlrunner.XMLTestRunner(output=output),failfast=False,buffer=False,catchbreak=False)Doctest supportThe XMLTestRunner can also be used to report on docstrings style tests.importdoctestimportxmlrunnerdeftwice(n):""">>> twice(5)10"""return2*nclassMultiplicator(object):defthreetimes(self,n):""">>> Multiplicator().threetimes(5)15"""return3*nif__name__=="__main__":suite=doctest.DocTestSuite()xmlrunner.XMLTestRunner().run(suite)Django supportIn order to plugXMLTestRunnerto a Django project, add the following
to yoursettings.py:TEST_RUNNER='xmlrunner.extra.djangotestrunner.XMLTestRunner'Also, the following settings are provided so you can fine tune the reports:settingdefaultvaluesdescriptionTEST_OUTPUT_VERBOSE10|1|2Besides the XML reports generated by the test runner, a bunch of useful information is printed to thesys.stderrstream, just like theTextTestRunnerdoes. Use this setting to choose between a verbose and a non-verbose output.TEST_OUTPUT_DESCRIPTIONSFalseTrue|FalseIf your test methods contains docstrings, you can display such docstrings instead of display the test name (ex:module.TestCase.test_method).In order to use this feature, you have to enable verbose output by settingTEST_OUTPUT_VERBOSE = 2.Only effects stdout and not XML output.TEST_OUTPUT_DIR"."<str>Tells the test runner where to put the XML reports. If the directory couldn't be found, the test runner will try to create it before generate the XML files.TEST_OUTPUT_FILE_NAMENone<str>Tells the test runner to output a single XML report with this filename underos.path.join(TEST_OUTPUT_DIR, TEST_OUTPUT_FILE_NAME).Please note that for long running tests, this will keep the results in memory for a longer time than multiple reports, and may use up more resources.ContributingWe are always looking for good contributions, so please just fork the
repository and send pull requests (with tests!).If you would like write access to the repository, or become a maintainer,
feel free to get in touch.Testing changes withtoxPlease usetoxto test your changes before sending a pull request.
You can find more information abouttoxathttps://testrun.org/tox/latest/.$pipinstalltox# basic sanity test, friendly output$tox-epytest# all combinations$tox