introduce a new --junitprefix option to influence xml reporting.
also internally avoid some redundant code. --HG-- branch : trunk
This commit is contained in:
		
							parent
							
								
									0c04577f9f
								
							
						
					
					
						commit
						bc6ead1a3c
					
				|  | @ -17,6 +17,9 @@ New features | ||||||
| 
 | 
 | ||||||
|   (thanks Ronny Pfannschmidt)  |   (thanks Ronny Pfannschmidt)  | ||||||
| 
 | 
 | ||||||
|  | - introduce '--junitprefix=STR' option to prepend a prefix  | ||||||
|  |   to all reports in the junitxml file.  | ||||||
|  | 
 | ||||||
| - Funcarg factories can now dynamically apply a marker to a  | - Funcarg factories can now dynamically apply a marker to a  | ||||||
|   test invocation.  This is particularly useful if a factory |   test invocation.  This is particularly useful if a factory | ||||||
|   provides parameters to a test which you expect-to-fail: |   provides parameters to a test which you expect-to-fail: | ||||||
|  |  | ||||||
|  | @ -11,11 +11,14 @@ def pytest_addoption(parser): | ||||||
|     group.addoption('--junitxml', action="store", dest="xmlpath",  |     group.addoption('--junitxml', action="store", dest="xmlpath",  | ||||||
|            metavar="path", default=None, |            metavar="path", default=None, | ||||||
|            help="create junit-xml style report file at given path.") |            help="create junit-xml style report file at given path.") | ||||||
|  |     group.addoption('--junitprefix', action="store", dest="junitprefix",  | ||||||
|  |            metavar="str", default=None, | ||||||
|  |            help="prepend prefix to classnames in junit-xml output") | ||||||
| 
 | 
 | ||||||
| def pytest_configure(config): | def pytest_configure(config): | ||||||
|     xmlpath = config.option.xmlpath |     xmlpath = config.option.xmlpath | ||||||
|     if xmlpath: |     if xmlpath: | ||||||
|         config._xml = LogXML(xmlpath) |         config._xml = LogXML(xmlpath, config.option.junitprefix) | ||||||
|         config.pluginmanager.register(config._xml) |         config.pluginmanager.register(config._xml) | ||||||
| 
 | 
 | ||||||
| def pytest_unconfigure(config): | def pytest_unconfigure(config): | ||||||
|  | @ -25,18 +28,25 @@ def pytest_unconfigure(config): | ||||||
|         config.pluginmanager.unregister(xml) |         config.pluginmanager.unregister(xml) | ||||||
| 
 | 
 | ||||||
| class LogXML(object): | class LogXML(object): | ||||||
|     def __init__(self, logfile): |     def __init__(self, logfile, prefix): | ||||||
|         self.logfile = logfile |         self.logfile = logfile | ||||||
|  |         self.prefix = prefix | ||||||
|         self.test_logs = [] |         self.test_logs = [] | ||||||
|         self.passed = self.skipped = 0 |         self.passed = self.skipped = 0 | ||||||
|         self.failed = self.errors = 0 |         self.failed = self.errors = 0 | ||||||
|         self._durations = {} |         self._durations = {} | ||||||
|    |    | ||||||
|     def _opentestcase(self, report): |     def _opentestcase(self, report): | ||||||
|         node = report.item  |         if hasattr(report, 'item'): | ||||||
|         d = {'time': self._durations.pop(report.item, "0")} |             node = report.item | ||||||
|  |         else: | ||||||
|  |             node = report.collector | ||||||
|  |         d = {'time': self._durations.pop(node, "0")} | ||||||
|         names = [x.replace(".py", "") for x in node.listnames() if x != "()"] |         names = [x.replace(".py", "") for x in node.listnames() if x != "()"] | ||||||
|         d['classname'] = ".".join(names[:-1]) |         classnames = names[:-1] | ||||||
|  |         if self.prefix: | ||||||
|  |             classnames.insert(0, self.prefix) | ||||||
|  |         d['classname'] = ".".join(classnames) | ||||||
|         d['name'] = py.xml.escape(names[-1]) |         d['name'] = py.xml.escape(names[-1]) | ||||||
|         attrs = ['%s="%s"' % item for item in sorted(d.items())] |         attrs = ['%s="%s"' % item for item in sorted(d.items())] | ||||||
|         self.test_logs.append("\n<testcase %s>" % " ".join(attrs)) |         self.test_logs.append("\n<testcase %s>" % " ".join(attrs)) | ||||||
|  | @ -66,17 +76,8 @@ class LogXML(object): | ||||||
|             self.failed += 1 |             self.failed += 1 | ||||||
|         self._closetestcase() |         self._closetestcase() | ||||||
| 
 | 
 | ||||||
|     def _opentestcase_collectfailure(self, report): |  | ||||||
|         node = report.collector |  | ||||||
|         d = {'time': '???'} |  | ||||||
|         names = [x.replace(".py", "") for x in node.listnames() if x != "()"] |  | ||||||
|         d['classname'] = ".".join(names[:-1]) |  | ||||||
|         d['name'] = py.xml.escape(names[-1]) |  | ||||||
|         attrs = ['%s="%s"' % item for item in sorted(d.items())] |  | ||||||
|         self.test_logs.append("\n<testcase %s>" % " ".join(attrs)) |  | ||||||
| 
 |  | ||||||
|     def append_collect_failure(self, report): |     def append_collect_failure(self, report): | ||||||
|         self._opentestcase_collectfailure(report) |         self._opentestcase(report) | ||||||
|         #msg = str(report.longrepr.reprtraceback.extraline) |         #msg = str(report.longrepr.reprtraceback.extraline) | ||||||
|         self.appendlog('<failure message="collection failure">%s</failure>',  |         self.appendlog('<failure message="collection failure">%s</failure>',  | ||||||
|             report.longrepr) |             report.longrepr) | ||||||
|  | @ -84,7 +85,7 @@ class LogXML(object): | ||||||
|         self.errors += 1 |         self.errors += 1 | ||||||
| 
 | 
 | ||||||
|     def append_collect_skipped(self, report): |     def append_collect_skipped(self, report): | ||||||
|         self._opentestcase_collectfailure(report) |         self._opentestcase(report) | ||||||
|         #msg = str(report.longrepr.reprtraceback.extraline) |         #msg = str(report.longrepr.reprtraceback.extraline) | ||||||
|         self.appendlog('<skipped message="collection skipped">%s</skipped>', |         self.appendlog('<skipped message="collection skipped">%s</skipped>', | ||||||
|             report.longrepr) |             report.longrepr) | ||||||
|  |  | ||||||
|  | @ -119,6 +119,28 @@ class TestPython: | ||||||
|             classname="test_failure_escape.test_failure_escape",  |             classname="test_failure_escape.test_failure_escape",  | ||||||
|             name="test_func[&]") |             name="test_func[&]") | ||||||
| 
 | 
 | ||||||
|  |     def test_junit_prefixing(self, testdir): | ||||||
|  |         testdir.makepyfile(""" | ||||||
|  |             def test_func():  | ||||||
|  |                 assert 0 | ||||||
|  |             class TestHello: | ||||||
|  |                 def test_hello(self): | ||||||
|  |                     pass | ||||||
|  |         """) | ||||||
|  |         result, dom = runandparse(testdir, "--junitprefix=xyz") | ||||||
|  |         assert result.ret  | ||||||
|  |         node = dom.getElementsByTagName("testsuite")[0] | ||||||
|  |         assert_attr(node, failures=1, tests=2) | ||||||
|  |         tnode = node.getElementsByTagName("testcase")[0] | ||||||
|  |         assert_attr(tnode,  | ||||||
|  |             classname="xyz.test_junit_prefixing.test_junit_prefixing", | ||||||
|  |             name="test_func") | ||||||
|  |         tnode = node.getElementsByTagName("testcase")[1] | ||||||
|  |         assert_attr(tnode,  | ||||||
|  |             classname="xyz.test_junit_prefixing.test_junit_prefixing." | ||||||
|  |                       "TestHello",  | ||||||
|  |             name="test_hello") | ||||||
|  | 
 | ||||||
|     def test_xfailure_function(self, testdir): |     def test_xfailure_function(self, testdir): | ||||||
|         testdir.makepyfile(""" |         testdir.makepyfile(""" | ||||||
|             import py |             import py | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue