bpo-34582: Adds JUnit XML output for regression tests (GH-9210) · python/cpython@1a89cb5 (original) (raw)
`@@ -100,8 +100,11 @@ def init(self):
`
100
100
`self.next_single_test = None
`
101
101
`self.next_single_filename = None
`
102
102
``
``
103
`+
used by --junit-xml
`
``
104
`+
self.testsuite_xml = None
`
``
105
+
103
106
`def accumulate_result(self, test, result):
`
104
``
`-
ok, test_time = result
`
``
107
`+
ok, test_time, xml_data = result
`
105
108
`if ok not in (CHILD_ERROR, INTERRUPTED):
`
106
109
`self.test_times.append((test_time, test))
`
107
110
`if ok == PASSED:
`
`@@ -118,6 +121,15 @@ def accumulate_result(self, test, result):
`
118
121
`elif ok != INTERRUPTED:
`
119
122
`raise ValueError("invalid test result: %r" % ok)
`
120
123
``
``
124
`+
if xml_data:
`
``
125
`+
import xml.etree.ElementTree as ET
`
``
126
`+
for e in xml_data:
`
``
127
`+
try:
`
``
128
`+
self.testsuite_xml.append(ET.fromstring(e))
`
``
129
`+
except ET.ParseError:
`
``
130
`+
print(xml_data, file=sys.stderr)
`
``
131
`+
raise
`
``
132
+
121
133
`def display_progress(self, test_index, test):
`
122
134
`if self.ns.quiet:
`
123
135
`return
`
`@@ -164,6 +176,9 @@ def parse_args(self, kwargs):
`
164
176
`file=sys.stderr)
`
165
177
`ns.findleaks = False
`
166
178
``
``
179
`+
if ns.xmlpath:
`
``
180
`+
support.junit_xml_list = self.testsuite_xml = []
`
``
181
+
167
182
`# Strip .py extensions.
`
168
183
`removepy(ns.args)
`
169
184
``
`@@ -384,7 +399,7 @@ def run_tests_sequential(self):
`
384
399
`result = runtest(self.ns, test)
`
385
400
`except KeyboardInterrupt:
`
386
401
`self.interrupted = True
`
387
``
`-
self.accumulate_result(test, (INTERRUPTED, None))
`
``
402
`+
self.accumulate_result(test, (INTERRUPTED, None, None))
`
388
403
`break
`
389
404
`else:
`
390
405
`self.accumulate_result(test, result)
`
`@@ -508,6 +523,31 @@ def finalize(self):
`
508
523
`if self.ns.runleaks:
`
509
524
`os.system("leaks %d" % os.getpid())
`
510
525
``
``
526
`+
def save_xml_result(self):
`
``
527
`+
if not self.ns.xmlpath and not self.testsuite_xml:
`
``
528
`+
return
`
``
529
+
``
530
`+
import xml.etree.ElementTree as ET
`
``
531
`+
root = ET.Element("testsuites")
`
``
532
+
``
533
`+
Manually count the totals for the overall summary
`
``
534
`+
totals = {'tests': 0, 'errors': 0, 'failures': 0}
`
``
535
`+
for suite in self.testsuite_xml:
`
``
536
`+
root.append(suite)
`
``
537
`+
for k in totals:
`
``
538
`+
try:
`
``
539
`+
totals[k] += int(suite.get(k, 0))
`
``
540
`+
except ValueError:
`
``
541
`+
pass
`
``
542
+
``
543
`+
for k, v in totals.items():
`
``
544
`+
root.set(k, str(v))
`
``
545
+
``
546
`+
xmlpath = os.path.join(support.SAVEDCWD, self.ns.xmlpath)
`
``
547
`+
with open(xmlpath, 'wb') as f:
`
``
548
`+
for s in ET.tostringlist(root):
`
``
549
`+
f.write(s)
`
``
550
+
511
551
`def main(self, tests=None, **kwargs):
`
512
552
`global TEMPDIR
`
513
553
``
`@@ -570,6 +610,9 @@ def _main(self, tests, kwargs):
`
570
610
`self.rerun_failed_tests()
`
571
611
``
572
612
`self.finalize()
`
``
613
+
``
614
`+
self.save_xml_result()
`
``
615
+
573
616
`if self.bad:
`
574
617
`sys.exit(2)
`
575
618
`if self.interrupted:
`