mirror of
https://github.com/google/googletest.git
synced 2025-03-10 09:16:48 +00:00
Googletest export
gtest: Output a canned test suite for environment failures in XML/JSON This surfaces useful information about the environment failure in a structured form. As we can see from the updated test, previously unsurfaced information is now present. PiperOrigin-RevId: 362292322
This commit is contained in:
parent
3bd41ab23f
commit
ac1d60c2b5
@ -3928,6 +3928,12 @@ class XmlUnitTestResultPrinter : public EmptyTestEventListener {
|
||||
// Streams an XML CDATA section, escaping invalid CDATA sequences as needed.
|
||||
static void OutputXmlCDataSection(::std::ostream* stream, const char* data);
|
||||
|
||||
// Streams a test suite XML stanza containing the given test result.
|
||||
//
|
||||
// Requires: result.Failed()
|
||||
static void OutputXmlTestSuiteForTestResult(::std::ostream* stream,
|
||||
const TestResult& result);
|
||||
|
||||
// Streams an XML representation of a TestResult object.
|
||||
static void OutputXmlTestResult(::std::ostream* stream,
|
||||
const TestResult& result);
|
||||
@ -4147,6 +4153,43 @@ void XmlUnitTestResultPrinter::OutputXmlAttribute(
|
||||
*stream << " " << name << "=\"" << EscapeXmlAttribute(value) << "\"";
|
||||
}
|
||||
|
||||
// Streams a test suite XML stanza containing the given test result.
|
||||
void XmlUnitTestResultPrinter::OutputXmlTestSuiteForTestResult(
|
||||
::std::ostream* stream, const TestResult& result) {
|
||||
// Output the boilerplate for a minimal test suite with one test.
|
||||
*stream << " <testsuite";
|
||||
OutputXmlAttribute(stream, "testsuite", "name", "NonTestSuiteFailure");
|
||||
OutputXmlAttribute(stream, "testsuite", "tests", "1");
|
||||
OutputXmlAttribute(stream, "testsuite", "failures", "1");
|
||||
OutputXmlAttribute(stream, "testsuite", "disabled", "0");
|
||||
OutputXmlAttribute(stream, "testsuite", "skipped", "0");
|
||||
OutputXmlAttribute(stream, "testsuite", "errors", "0");
|
||||
OutputXmlAttribute(stream, "testsuite", "time",
|
||||
FormatTimeInMillisAsSeconds(result.elapsed_time()));
|
||||
OutputXmlAttribute(
|
||||
stream, "testsuite", "timestamp",
|
||||
FormatEpochTimeInMillisAsIso8601(result.start_timestamp()));
|
||||
*stream << ">";
|
||||
|
||||
// Output the boilerplate for a minimal test case with a single test.
|
||||
*stream << " <testcase";
|
||||
OutputXmlAttribute(stream, "testcase", "name", "");
|
||||
OutputXmlAttribute(stream, "testcase", "status", "run");
|
||||
OutputXmlAttribute(stream, "testcase", "result", "completed");
|
||||
OutputXmlAttribute(stream, "testcase", "classname", "");
|
||||
OutputXmlAttribute(stream, "testcase", "time",
|
||||
FormatTimeInMillisAsSeconds(result.elapsed_time()));
|
||||
OutputXmlAttribute(
|
||||
stream, "testcase", "timestamp",
|
||||
FormatEpochTimeInMillisAsIso8601(result.start_timestamp()));
|
||||
|
||||
// Output the actual test result.
|
||||
OutputXmlTestResult(stream, result);
|
||||
|
||||
// Complete the test suite.
|
||||
*stream << " </testsuite>\n";
|
||||
}
|
||||
|
||||
// Prints an XML representation of a TestInfo object.
|
||||
void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,
|
||||
const char* test_suite_name,
|
||||
@ -4309,6 +4352,13 @@ void XmlUnitTestResultPrinter::PrintXmlUnitTest(std::ostream* stream,
|
||||
if (unit_test.GetTestSuite(i)->reportable_test_count() > 0)
|
||||
PrintXmlTestSuite(stream, *unit_test.GetTestSuite(i));
|
||||
}
|
||||
|
||||
// If there was a test failure outside of one of the test suites (like in a
|
||||
// test environment) include that in the output.
|
||||
if (unit_test.ad_hoc_test_result().Failed()) {
|
||||
OutputXmlTestSuiteForTestResult(stream, unit_test.ad_hoc_test_result());
|
||||
}
|
||||
|
||||
*stream << "</" << kTestsuites << ">\n";
|
||||
}
|
||||
|
||||
@ -4399,6 +4449,12 @@ class JsonUnitTestResultPrinter : public EmptyTestEventListener {
|
||||
const std::string& indent,
|
||||
bool comma = true);
|
||||
|
||||
// Streams a test suite JSON stanza containing the given test result.
|
||||
//
|
||||
// Requires: result.Failed()
|
||||
static void OutputJsonTestSuiteForTestResult(::std::ostream* stream,
|
||||
const TestResult& result);
|
||||
|
||||
// Streams a JSON representation of a TestResult object.
|
||||
static void OutputJsonTestResult(::std::ostream* stream,
|
||||
const TestResult& result);
|
||||
@ -4553,6 +4609,48 @@ void JsonUnitTestResultPrinter::OutputJsonKey(
|
||||
*stream << ",\n";
|
||||
}
|
||||
|
||||
// Streams a test suite JSON stanza containing the given test result.
|
||||
void JsonUnitTestResultPrinter::OutputJsonTestSuiteForTestResult(
|
||||
::std::ostream* stream, const TestResult& result) {
|
||||
// Output the boilerplate for a new test suite.
|
||||
*stream << Indent(4) << "{\n";
|
||||
OutputJsonKey(stream, "testsuite", "name", "NonTestSuiteFailure", Indent(6));
|
||||
OutputJsonKey(stream, "testsuite", "tests", 1, Indent(6));
|
||||
if (!GTEST_FLAG(list_tests)) {
|
||||
OutputJsonKey(stream, "testsuite", "failures", 1, Indent(6));
|
||||
OutputJsonKey(stream, "testsuite", "disabled", 0, Indent(6));
|
||||
OutputJsonKey(stream, "testsuite", "skipped", 0, Indent(6));
|
||||
OutputJsonKey(stream, "testsuite", "errors", 0, Indent(6));
|
||||
OutputJsonKey(stream, "testsuite", "time",
|
||||
FormatTimeInMillisAsDuration(result.elapsed_time()),
|
||||
Indent(6));
|
||||
OutputJsonKey(stream, "testsuite", "timestamp",
|
||||
FormatEpochTimeInMillisAsRFC3339(result.start_timestamp()),
|
||||
Indent(6));
|
||||
}
|
||||
*stream << Indent(6) << "\"testsuite\": [\n";
|
||||
|
||||
// Output the boilerplate for a new test case.
|
||||
*stream << Indent(8) << "{\n";
|
||||
OutputJsonKey(stream, "testcase", "name", "", Indent(10));
|
||||
OutputJsonKey(stream, "testcase", "status", "RUN", Indent(10));
|
||||
OutputJsonKey(stream, "testcase", "result", "COMPLETED", Indent(10));
|
||||
OutputJsonKey(stream, "testcase", "timestamp",
|
||||
FormatEpochTimeInMillisAsRFC3339(result.start_timestamp()),
|
||||
Indent(10));
|
||||
OutputJsonKey(stream, "testcase", "time",
|
||||
FormatTimeInMillisAsDuration(result.elapsed_time()),
|
||||
Indent(10));
|
||||
OutputJsonKey(stream, "testcase", "classname", "", Indent(10), false);
|
||||
*stream << TestPropertiesAsJson(result, Indent(10));
|
||||
|
||||
// Output the actual test result.
|
||||
OutputJsonTestResult(stream, result);
|
||||
|
||||
// Finish the test suite.
|
||||
*stream << "\n" << Indent(6) << "]\n" << Indent(4) << "}";
|
||||
}
|
||||
|
||||
// Prints a JSON representation of a TestInfo object.
|
||||
void JsonUnitTestResultPrinter::OutputJsonTestInfo(::std::ostream* stream,
|
||||
const char* test_suite_name,
|
||||
@ -4712,6 +4810,12 @@ void JsonUnitTestResultPrinter::PrintJsonUnitTest(std::ostream* stream,
|
||||
}
|
||||
}
|
||||
|
||||
// If there was a test failure outside of one of the test suites (like in a
|
||||
// test environment) include that in the output.
|
||||
if (unit_test.ad_hoc_test_result().Failed()) {
|
||||
OutputJsonTestSuiteForTestResult(stream, unit_test.ad_hoc_test_result());
|
||||
}
|
||||
|
||||
*stream << "\n" << kIndent << "]\n" << "}\n";
|
||||
}
|
||||
|
||||
|
@ -612,15 +612,59 @@ EXPECTED_FILTERED = {
|
||||
}],
|
||||
}
|
||||
|
||||
EXPECTED_EMPTY = {
|
||||
u'tests': 0,
|
||||
u'failures': 0,
|
||||
u'disabled': 0,
|
||||
u'errors': 0,
|
||||
u'time': u'*',
|
||||
u'timestamp': u'*',
|
||||
u'name': u'AllTests',
|
||||
u'testsuites': [],
|
||||
EXPECTED_NO_TEST = {
|
||||
u'tests':
|
||||
0,
|
||||
u'failures':
|
||||
0,
|
||||
u'disabled':
|
||||
0,
|
||||
u'errors':
|
||||
0,
|
||||
u'time':
|
||||
u'*',
|
||||
u'timestamp':
|
||||
u'*',
|
||||
u'name':
|
||||
u'AllTests',
|
||||
u'testsuites': [{
|
||||
u'name':
|
||||
u'NonTestSuiteFailure',
|
||||
u'tests':
|
||||
1,
|
||||
u'failures':
|
||||
1,
|
||||
u'disabled':
|
||||
0,
|
||||
u'skipped':
|
||||
0,
|
||||
u'errors':
|
||||
0,
|
||||
u'time':
|
||||
u'*',
|
||||
u'timestamp':
|
||||
u'*',
|
||||
u'testsuite': [{
|
||||
u'name':
|
||||
u'',
|
||||
u'status':
|
||||
u'RUN',
|
||||
u'result':
|
||||
u'COMPLETED',
|
||||
u'time':
|
||||
u'*',
|
||||
u'timestamp':
|
||||
u'*',
|
||||
u'classname':
|
||||
u'',
|
||||
u'failures': [{
|
||||
u'failure': u'gtest_no_test_unittest.cc:*\n'
|
||||
u'Expected equality of these values:\n'
|
||||
u' 1\n 2' + STACK_TRACE_TEMPLATE,
|
||||
u'type': u'',
|
||||
}]
|
||||
}]
|
||||
}],
|
||||
}
|
||||
|
||||
GTEST_PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath(GTEST_PROGRAM_NAME)
|
||||
@ -645,14 +689,14 @@ class GTestJsonOutputUnitTest(gtest_test_utils.TestCase):
|
||||
"""
|
||||
self._TestJsonOutput(GTEST_PROGRAM_NAME, EXPECTED_NON_EMPTY, 1)
|
||||
|
||||
def testEmptyJsonOutput(self):
|
||||
def testNoTestJsonOutput(self):
|
||||
"""Verifies JSON output for a Google Test binary without actual tests.
|
||||
|
||||
Runs a test program that generates an empty JSON output, and
|
||||
tests that the JSON output is expected.
|
||||
Runs a test program that generates an JSON output for a binary with no
|
||||
tests, and tests that the JSON output is expected.
|
||||
"""
|
||||
|
||||
self._TestJsonOutput('gtest_no_test_unittest', EXPECTED_EMPTY, 0)
|
||||
self._TestJsonOutput('gtest_no_test_unittest', EXPECTED_NO_TEST, 0)
|
||||
|
||||
def testTimestampValue(self):
|
||||
"""Checks whether the timestamp attribute in the JSON output is valid.
|
||||
|
@ -216,10 +216,20 @@ EXPECTED_SHARDED_TEST_XML = """<?xml version="1.0" encoding="UTF-8"?>
|
||||
</testsuite>
|
||||
</testsuites>"""
|
||||
|
||||
EXPECTED_EMPTY_XML = """<?xml version="1.0" encoding="UTF-8"?>
|
||||
EXPECTED_NO_TEST_XML = """<?xml version="1.0" encoding="UTF-8"?>
|
||||
<testsuites tests="0" failures="0" disabled="0" errors="0" time="*"
|
||||
timestamp="*" name="AllTests">
|
||||
</testsuites>"""
|
||||
<testsuite name="NonTestSuiteFailure" tests="1" failures="1" disabled="0" skipped="0" errors="0" time="*" timestamp="*">
|
||||
<testcase name="" status="run" result="completed" time="*" timestamp="*" classname="">
|
||||
<failure message="gtest_no_test_unittest.cc:*
Expected equality of these values:
 1
 2" type=""><![CDATA[gtest_no_test_unittest.cc:*
|
||||
Expected equality of these values:
|
||||
1
|
||||
2%(stack)s]]></failure>
|
||||
</testcase>
|
||||
</testsuite>
|
||||
</testsuites>""" % {
|
||||
'stack': STACK_TRACE_TEMPLATE
|
||||
}
|
||||
|
||||
GTEST_PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath(GTEST_PROGRAM_NAME)
|
||||
|
||||
@ -242,14 +252,14 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase):
|
||||
"""
|
||||
self._TestXmlOutput(GTEST_PROGRAM_NAME, EXPECTED_NON_EMPTY_XML, 1)
|
||||
|
||||
def testEmptyXmlOutput(self):
|
||||
def testNoTestXmlOutput(self):
|
||||
"""Verifies XML output for a Google Test binary without actual tests.
|
||||
|
||||
Runs a test program that generates an empty XML output, and
|
||||
tests that the XML output is expected.
|
||||
Runs a test program that generates an XML output for a binary without tests,
|
||||
and tests that the XML output is expected.
|
||||
"""
|
||||
|
||||
self._TestXmlOutput('gtest_no_test_unittest', EXPECTED_EMPTY_XML, 0)
|
||||
self._TestXmlOutput('gtest_no_test_unittest', EXPECTED_NO_TEST_XML, 0)
|
||||
|
||||
def testTimestampValue(self):
|
||||
"""Checks whether the timestamp attribute in the XML output is valid.
|
||||
|
Loading…
x
Reference in New Issue
Block a user