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:

`