From d255459da036fab0be3ded2e50038926e8c0c4e2 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Thu, 5 Sep 2019 17:53:07 -0600 Subject: [PATCH 1/3] Support the new XML JUnit format (e.g. for pytest 5.1). --- src/client/testing/common/xUnitParser.ts | 21 +++++++++- .../testing/common/xUnitParser.unit.test.ts | 38 ++++++++++++++++++- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/src/client/testing/common/xUnitParser.ts b/src/client/testing/common/xUnitParser.ts index 9467fb6674c8..6780826e0a83 100644 --- a/src/client/testing/common/xUnitParser.ts +++ b/src/client/testing/common/xUnitParser.ts @@ -59,8 +59,25 @@ export class XUnitParser implements IXUnitParser { ) { const data = await this.fs.readFile(outputXmlFile); - const parserResult = await parseXML(data) as { testsuite: TestSuiteResult }; - updateTests(tests, parserResult.testsuite); + const parserResult = await parseXML(data); + let junitResults: TestSuiteResult; + const fullResults = parserResult as { testsuites: { testsuite: TestSuiteResult[] }}; + if (fullResults.testsuites) { + const junitSuites = fullResults.testsuites.testsuite; + if (!Array.isArray(junitSuites)) { + throw Error('bad JUnit XML data'); + } + if (junitSuites.length === 0) { + return; + } + if (junitSuites.length > 1) { + throw Error('got multiple XML results'); + } + junitResults = junitSuites[0]; + } else { + junitResults = (parserResult as { testsuite: TestSuiteResult }).testsuite; + } + updateTests(tests, junitResults); } } diff --git a/src/test/testing/common/xUnitParser.unit.test.ts b/src/test/testing/common/xUnitParser.unit.test.ts index 9a9b5498b4ca..fc8bf2aa682c 100644 --- a/src/test/testing/common/xUnitParser.unit.test.ts +++ b/src/test/testing/common/xUnitParser.unit.test.ts @@ -38,7 +38,7 @@ suite('Testing - parse JUnit XML file', () => { node.line = line; } - test('success with single passing test', async () => { + test('legacy - success with single passing test', async () => { const tests = createDeclaratively(` ./ test_spam.py @@ -72,6 +72,42 @@ suite('Testing - parse JUnit XML file', () => { fs.verifyAll(); }); + test('success with single passing test', async () => { + const tests = createDeclaratively(` + ./ + test_spam.py + + test_spam + `); + const expected = createDeclaratively(` + ./ + test_spam.py + + test_spam P 0.001 + `); + fixResult( + expected.testFunctions[0].testFunction, + 'test_spam.py', + 3 + ); + const filename = 'x/y/z/results.xml'; + fs.setup(f => f.readFile(filename)) + .returns(() => Promise.resolve(` + + + + + + + + `)); + + await parser.updateResultsFromXmlLogFile(tests, filename); + + expect(tests).to.deep.equal(expected); + fs.verifyAll(); + }); + test('no discovered tests', async () => { const tests: Tests = createEmptyResults(); const expected: Tests = createEmptyResults(); From 51565e42b7e5e576c273510afbee92b82de2ebfd Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Fri, 6 Sep 2019 13:17:56 -0600 Subject: [PATCH 2/3] Factor out getJunitResults(). --- src/client/testing/common/xUnitParser.ts | 42 ++++++++++++++---------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/src/client/testing/common/xUnitParser.ts b/src/client/testing/common/xUnitParser.ts index 6780826e0a83..6078be80f115 100644 --- a/src/client/testing/common/xUnitParser.ts +++ b/src/client/testing/common/xUnitParser.ts @@ -60,24 +60,10 @@ export class XUnitParser implements IXUnitParser { const data = await this.fs.readFile(outputXmlFile); const parserResult = await parseXML(data); - let junitResults: TestSuiteResult; - const fullResults = parserResult as { testsuites: { testsuite: TestSuiteResult[] }}; - if (fullResults.testsuites) { - const junitSuites = fullResults.testsuites.testsuite; - if (!Array.isArray(junitSuites)) { - throw Error('bad JUnit XML data'); - } - if (junitSuites.length === 0) { - return; - } - if (junitSuites.length > 1) { - throw Error('got multiple XML results'); - } - junitResults = junitSuites[0]; - } else { - junitResults = (parserResult as { testsuite: TestSuiteResult }).testsuite; + const junitResults = getJunitResults(parserResult); + if (junitResults) { + updateTests(tests, junitResults); } - updateTests(tests, junitResults); } } @@ -97,6 +83,28 @@ async function parseXML(data: string): Promise { }); } +// Return the actual test results from the given data. +// tslint:disable-next-line:no-any +function getJunitResults(parserResult: any): TestSuiteResult | undefined { + // This is the newer JUnit XML format (e.g. pytest 5.1 and later). + const fullResults = parserResult as { testsuites: { testsuite: TestSuiteResult[] }}; + if (!fullResults.testsuites) { + return (parserResult as { testsuite: TestSuiteResult }).testsuite; + } + + const junitSuites = fullResults.testsuites.testsuite; + if (!Array.isArray(junitSuites)) { + throw Error('bad JUnit XML data'); + } + if (junitSuites.length === 0) { + return; + } + if (junitSuites.length > 1) { + throw Error('got multiple XML results'); + } + return junitSuites[0]; +} + // Update "tests" with the given results. function updateTests( tests: Tests, From d523f137c0de4f03e60500742764e9d8a18f5b28 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Fri, 6 Sep 2019 13:26:21 -0600 Subject: [PATCH 3/3] Add a NEWS entry. --- news/2 Fixes/6990.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 news/2 Fixes/6990.md diff --git a/news/2 Fixes/6990.md b/news/2 Fixes/6990.md new file mode 100644 index 000000000000..77cdab51a022 --- /dev/null +++ b/news/2 Fixes/6990.md @@ -0,0 +1 @@ +Add support for the new JUnit XML format used by pytest 5.1+.