8000 Support the new JUnit XML format. (#7265) · microsoft/vscode-python@6a57280 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6a57280

Browse files
Support the new JUnit XML format. (#7265)
The JUnit XML format used by pytest was updated in version 5.1.0. This PR adds support for that format, and falls back to the old one.
1 parent efcdeb4 commit 6a57280

File tree

3 files changed

+65
-3
lines changed

3 files changed

+65
-3
lines changed

news/2 Fixes/6990.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add support for the new JUnit XML format used by pytest 5.1+.

src/client/testing/common/xUnitParser.ts

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,11 @@ export class XUnitParser implements IXUnitParser {
5959
) {
6060
const data = await this.fs.readFile(outputXmlFile);
6161

62-
const parserResult = await parseXML(data) as { testsuite: TestSuiteResult };
63-
updateTests(tests, parserResult.testsuite);
62+
const parserResult = await parseXML(data);
63+
const junitResults = getJunitResults(parserResult);
64+
if (junitResults) {
65+
updateTests(tests, junitResults);
66+
}
6467
}
6568
}
6669

@@ -80,6 +83,28 @@ async function parseXML(data: string): Promise<any> {
8083
});
8184
}
8285

86+
// Return the actual test results from the given data.
87+
// tslint:disable-next-line:no-any
88+
function getJunitResults(parserResult: any): TestSuiteResult | undefined {
89+
// This is the newer JUnit XML format (e.g. pytest 5.1 and later).
90+
const fullResults = parserResult as { testsuites: { testsuite: TestSuiteResult[] }};
91+
if (!fullResults.testsuites) {
92+
return (parserResult as { testsuite: TestSuiteResult }).testsuite;
93+
}
94+
95+
const junitSuites = fullResults.testsuites.testsuite;
96+
if (!Array.isArray(junitSuites)) {
97+
throw Error('bad JUnit XML data');
98+
}
99+
if (junitSuites.length === 0) {
100+
return;
101+
}
102+
if (junitSuites.length > 1) {
103+
throw Error('got multiple XML results');
104+
}
105+
return junitSuites[0];
106+
}
107+
83108
// Update "tests" with the given results.
84109
function updateTests(
85110
tests: Tests,

src/test/testing/common/xUnitParser.unit.test.ts

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ suite('Testing - parse JUnit XML file', () => {
3838
node.line = line;
3939
}
4040

41-
test('success with single passing test', async () => {
41+
test('legacy - success with single passing test', async () => {
4242
const tests = createDeclaratively(`
4343
./
4444
test_spam.py
@@ -72,6 +72,42 @@ suite('Testing - parse JUnit XML file', () => {
7272
fs.verifyAll();
7373
});
7474

75+
test('success with single passing test', async () => {
76+
const tests = createDeclaratively(`
77+
./
78+
test_spam.py
79+
<Tests>
80+
test_spam
81+
`);
82+
const expected = createDeclaratively(`
83+
./
84+
test_spam.py
85+
<Tests>
86+
test_spam P 0.001
87+
`);
88+
fixResult(
89+
expected.testFunctions[0].testFunction,
90+
'test_spam.py',
91+
3
92+
);
93+
const filename = 'x/y/z/results.xml';
94+
fs.setup(f => f.readFile(filename))
95+
.returns(() => Promise.resolve(`
96+
<?xml version="1.0" encoding="utf-8"?>
97+
<testsuites>
98+
<testsuite errors="0" failures="0" hostname="vm-dev-linux-desktop" name="pytest" skipped="0" tests="1" time="0.011" timestamp="2019-09-05T17:17:35.868863">
99+
<testcase classname="test_spam.Tests" file="test_spam.py" line="3" name="test_spam" time="0.001">
100+
</testcase>
101+
</testsuite>
102+
</testsuites>
103+
`));
104+
105+
await parser.updateResultsFromXmlLogFile(tests, filename);
106+
107+
expect(tests).to.deep.equal(expected);
108+
fs.verifyAll();
109+
});
110+
75111
test('no discovered tests', async () => {
76112
const tests: Tests = createEmptyResults();
77113
const expected: Tests = createEmptyResults();

0 commit comments

Comments
 (0)
0