unittest-xml-reporting
unittest-xml-reporting is a unittest-based test runner that generates XML reports in the xUnit format. These reports are widely compatible with various tools, including build systems, IDEs, and continuous integration servers like Jenkins or GitLab. The library is actively maintained with regular releases; its current major version is 4.0.0.
Warnings
- breaking Version 4.0.0 of `unittest-xml-reporting` requires Python 3.10 or newer. If you are using an older Python version (e.g., 3.7-3.9), you must use an earlier version of the library (e.g., 3.2.0).
- gotcha The `unittest.TestCase.subTest` feature has limited support. Sub-test granularity may be lost in the generated XML reports as it does not map directly to the xUnit schema, and successful sub-tests might not be explicitly reported.
- gotcha Malformed JUnit XML reports are a common issue, leading to parsing errors in CI/CD systems like GitLab or Jenkins. This can be caused by invalid XML, encoding problems, or missing test data.
- gotcha When consuming reports in Jenkins, different versions of the Jenkins xUnit plugin may have varying levels of XSD validation strictness. This can cause valid reports for one plugin version to be rejected by another.
Install
-
pip install unittest-xml-reporting
Imports
- XMLTestRunner
import xmlrunner # ... xmlrunner.XMLTestRunner(...)
Quickstart
import unittest
import xmlrunner
import os
class MyTests(unittest.TestCase):
def test_success(self):
self.assertTrue(True)
def test_failure(self):
self.assertEqual(1, 2, "1 is not equal to 2")
@unittest.skip("demonstrating skipping")
def test_skipped(self):
self.fail("shouldn't run this")
if __name__ == '__main__':
output_dir = os.environ.get('TEST_OUTPUT_DIR', 'test-reports')
os.makedirs(output_dir, exist_ok=True)
# Run tests and generate XML report in the specified directory
unittest.main(
testRunner=xmlrunner.XMLTestRunner(output=output_dir),
# Using exit=False allows the script to continue after tests,
# which can be useful in some CI/CD setups or when integrating.
exit=False
)
print(f"Test reports generated in: {os.path.abspath(output_dir)}")