00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 """Unit test for the gtest_xml_output module"""
00033
00034 __author__ = 'eefacm@gmail.com (Sean Mcafee)'
00035
00036 import datetime
00037 import errno
00038 import os
00039 import re
00040 import sys
00041 from xml.dom import minidom, Node
00042
00043 import gtest_test_utils
00044 import gtest_xml_test_utils
00045
00046
00047 GTEST_FILTER_FLAG = '--gtest_filter'
00048 GTEST_LIST_TESTS_FLAG = '--gtest_list_tests'
00049 GTEST_OUTPUT_FLAG = "--gtest_output"
00050 GTEST_DEFAULT_OUTPUT_FILE = "test_detail.xml"
00051 GTEST_PROGRAM_NAME = "gtest_xml_output_unittest_"
00052
00053 SUPPORTS_STACK_TRACES = False
00054
00055 if SUPPORTS_STACK_TRACES:
00056 STACK_TRACE_TEMPLATE = '\nStack trace:\n*'
00057 else:
00058 STACK_TRACE_TEMPLATE = ''
00059
00060 EXPECTED_NON_EMPTY_XML = """<?xml version="1.0" encoding="UTF-8"?>
00061 <testsuites tests="23" failures="4" disabled="2" errors="0" time="*" timestamp="*" name="AllTests" ad_hoc_property="42">
00062 <testsuite name="SuccessfulTest" tests="1" failures="0" disabled="0" errors="0" time="*">
00063 <testcase name="Succeeds" status="run" time="*" classname="SuccessfulTest"/>
00064 </testsuite>
00065 <testsuite name="FailedTest" tests="1" failures="1" disabled="0" errors="0" time="*">
00066 <testcase name="Fails" status="run" time="*" classname="FailedTest">
00067 <failure message="gtest_xml_output_unittest_.cc:*
Value of: 2
Expected: 1" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
00068 Value of: 2
00069 Expected: 1%(stack)s]]></failure>
00070 </testcase>
00071 </testsuite>
00072 <testsuite name="MixedResultTest" tests="3" failures="1" disabled="1" errors="0" time="*">
00073 <testcase name="Succeeds" status="run" time="*" classname="MixedResultTest"/>
00074 <testcase name="Fails" status="run" time="*" classname="MixedResultTest">
00075 <failure message="gtest_xml_output_unittest_.cc:*
Value of: 2
Expected: 1" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
00076 Value of: 2
00077 Expected: 1%(stack)s]]></failure>
00078 <failure message="gtest_xml_output_unittest_.cc:*
Value of: 3
Expected: 2" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
00079 Value of: 3
00080 Expected: 2%(stack)s]]></failure>
00081 </testcase>
00082 <testcase name="DISABLED_test" status="notrun" time="*" classname="MixedResultTest"/>
00083 </testsuite>
00084 <testsuite name="XmlQuotingTest" tests="1" failures="1" disabled="0" errors="0" time="*">
00085 <testcase name="OutputsCData" status="run" time="*" classname="XmlQuotingTest">
00086 <failure message="gtest_xml_output_unittest_.cc:*
Failed
XML output: <?xml encoding="utf-8"><top><![CDATA[cdata text]]></top>" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
00087 Failed
00088 XML output: <?xml encoding="utf-8"><top><![CDATA[cdata text]]>]]><![CDATA[</top>%(stack)s]]></failure>
00089 </testcase>
00090 </testsuite>
00091 <testsuite name="InvalidCharactersTest" tests="1" failures="1" disabled="0" errors="0" time="*">
00092 <testcase name="InvalidCharactersInMessage" status="run" time="*" classname="InvalidCharactersTest">
00093 <failure message="gtest_xml_output_unittest_.cc:*
Failed
Invalid characters in brackets []" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
00094 Failed
00095 Invalid characters in brackets []%(stack)s]]></failure>
00096 </testcase>
00097 </testsuite>
00098 <testsuite name="DisabledTest" tests="1" failures="0" disabled="1" errors="0" time="*">
00099 <testcase name="DISABLED_test_not_run" status="notrun" time="*" classname="DisabledTest"/>
00100 </testsuite>
00101 <testsuite name="PropertyRecordingTest" tests="4" failures="0" disabled="0" errors="0" time="*" SetUpTestCase="yes" TearDownTestCase="aye">
00102 <testcase name="OneProperty" status="run" time="*" classname="PropertyRecordingTest" key_1="1"/>
00103 <testcase name="IntValuedProperty" status="run" time="*" classname="PropertyRecordingTest" key_int="1"/>
00104 <testcase name="ThreeProperties" status="run" time="*" classname="PropertyRecordingTest" key_1="1" key_2="2" key_3="3"/>
00105 <testcase name="TwoValuesForOneKeyUsesLastValue" status="run" time="*" classname="PropertyRecordingTest" key_1="2"/>
00106 </testsuite>
00107 <testsuite name="NoFixtureTest" tests="3" failures="0" disabled="0" errors="0" time="*">
00108 <testcase name="RecordProperty" status="run" time="*" classname="NoFixtureTest" key="1"/>
00109 <testcase name="ExternalUtilityThatCallsRecordIntValuedProperty" status="run" time="*" classname="NoFixtureTest" key_for_utility_int="1"/>
00110 <testcase name="ExternalUtilityThatCallsRecordStringValuedProperty" status="run" time="*" classname="NoFixtureTest" key_for_utility_string="1"/>
00111 </testsuite>
00112 <testsuite name="Single/ValueParamTest" tests="4" failures="0" disabled="0" errors="0" time="*">
00113 <testcase name="HasValueParamAttribute/0" value_param="33" status="run" time="*" classname="Single/ValueParamTest" />
00114 <testcase name="HasValueParamAttribute/1" value_param="42" status="run" time="*" classname="Single/ValueParamTest" />
00115 <testcase name="AnotherTestThatHasValueParamAttribute/0" value_param="33" status="run" time="*" classname="Single/ValueParamTest" />
00116 <testcase name="AnotherTestThatHasValueParamAttribute/1" value_param="42" status="run" time="*" classname="Single/ValueParamTest" />
00117 </testsuite>
00118 <testsuite name="TypedTest/0" tests="1" failures="0" disabled="0" errors="0" time="*">
00119 <testcase name="HasTypeParamAttribute" type_param="*" status="run" time="*" classname="TypedTest/0" />
00120 </testsuite>
00121 <testsuite name="TypedTest/1" tests="1" failures="0" disabled="0" errors="0" time="*">
00122 <testcase name="HasTypeParamAttribute" type_param="*" status="run" time="*" classname="TypedTest/1" />
00123 </testsuite>
00124 <testsuite name="Single/TypeParameterizedTestCase/0" tests="1" failures="0" disabled="0" errors="0" time="*">
00125 <testcase name="HasTypeParamAttribute" type_param="*" status="run" time="*" classname="Single/TypeParameterizedTestCase/0" />
00126 </testsuite>
00127 <testsuite name="Single/TypeParameterizedTestCase/1" tests="1" failures="0" disabled="0" errors="0" time="*">
00128 <testcase name="HasTypeParamAttribute" type_param="*" status="run" time="*" classname="Single/TypeParameterizedTestCase/1" />
00129 </testsuite>
00130 </testsuites>""" % {'stack': STACK_TRACE_TEMPLATE}
00131
00132 EXPECTED_FILTERED_TEST_XML = """<?xml version="1.0" encoding="UTF-8"?>
00133 <testsuites tests="1" failures="0" disabled="0" errors="0" time="*"
00134 timestamp="*" name="AllTests" ad_hoc_property="42">
00135 <testsuite name="SuccessfulTest" tests="1" failures="0" disabled="0"
00136 errors="0" time="*">
00137 <testcase name="Succeeds" status="run" time="*" classname="SuccessfulTest"/>
00138 </testsuite>
00139 </testsuites>"""
00140
00141 EXPECTED_EMPTY_XML = """<?xml version="1.0" encoding="UTF-8"?>
00142 <testsuites tests="0" failures="0" disabled="0" errors="0" time="*"
00143 timestamp="*" name="AllTests">
00144 </testsuites>"""
00145
00146 GTEST_PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath(GTEST_PROGRAM_NAME)
00147
00148 SUPPORTS_TYPED_TESTS = 'TypedTest' in gtest_test_utils.Subprocess(
00149 [GTEST_PROGRAM_PATH, GTEST_LIST_TESTS_FLAG], capture_stderr=False).output
00150
00151
00152 class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase):
00153 """
00154 Unit test for Google Test's XML output functionality.
00155 """
00156
00157
00158
00159 if SUPPORTS_TYPED_TESTS:
00160 def testNonEmptyXmlOutput(self):
00161 """
00162 Runs a test program that generates a non-empty XML output, and
00163 tests that the XML output is expected.
00164 """
00165 self._TestXmlOutput(GTEST_PROGRAM_NAME, EXPECTED_NON_EMPTY_XML, 1)
00166
00167 def testEmptyXmlOutput(self):
00168 """Verifies XML output for a Google Test binary without actual tests.
00169
00170 Runs a test program that generates an empty XML output, and
00171 tests that the XML output is expected.
00172 """
00173
00174 self._TestXmlOutput('gtest_no_test_unittest', EXPECTED_EMPTY_XML, 0)
00175
00176 def testTimestampValue(self):
00177 """Checks whether the timestamp attribute in the XML output is valid.
00178
00179 Runs a test program that generates an empty XML output, and checks if
00180 the timestamp attribute in the testsuites tag is valid.
00181 """
00182 actual = self._GetXmlOutput('gtest_no_test_unittest', [], 0)
00183 date_time_str = actual.documentElement.getAttributeNode('timestamp').value
00184
00185
00186 match = re.match(r'(\d+)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)', date_time_str)
00187 self.assertTrue(
00188 re.match,
00189 'XML datettime string %s has incorrect format' % date_time_str)
00190 date_time_from_xml = datetime.datetime(
00191 year=int(match.group(1)), month=int(match.group(2)),
00192 day=int(match.group(3)), hour=int(match.group(4)),
00193 minute=int(match.group(5)), second=int(match.group(6)))
00194
00195 time_delta = abs(datetime.datetime.now() - date_time_from_xml)
00196
00197 self.assertTrue(time_delta < datetime.timedelta(seconds=600),
00198 'time_delta is %s' % time_delta)
00199 actual.unlink()
00200
00201 def testDefaultOutputFile(self):
00202 """
00203 Confirms that Google Test produces an XML output file with the expected
00204 default name if no name is explicitly specified.
00205 """
00206 output_file = os.path.join(gtest_test_utils.GetTempDir(),
00207 GTEST_DEFAULT_OUTPUT_FILE)
00208 gtest_prog_path = gtest_test_utils.GetTestExecutablePath(
00209 'gtest_no_test_unittest')
00210 try:
00211 os.remove(output_file)
00212 except OSError, e:
00213 if e.errno != errno.ENOENT:
00214 raise
00215
00216 p = gtest_test_utils.Subprocess(
00217 [gtest_prog_path, '%s=xml' % GTEST_OUTPUT_FLAG],
00218 working_dir=gtest_test_utils.GetTempDir())
00219 self.assert_(p.exited)
00220 self.assertEquals(0, p.exit_code)
00221 self.assert_(os.path.isfile(output_file))
00222
00223 def testSuppressedXmlOutput(self):
00224 """
00225 Tests that no XML file is generated if the default XML listener is
00226 shut down before RUN_ALL_TESTS is invoked.
00227 """
00228
00229 xml_path = os.path.join(gtest_test_utils.GetTempDir(),
00230 GTEST_PROGRAM_NAME + 'out.xml')
00231 if os.path.isfile(xml_path):
00232 os.remove(xml_path)
00233
00234 command = [GTEST_PROGRAM_PATH,
00235 '%s=xml:%s' % (GTEST_OUTPUT_FLAG, xml_path),
00236 '--shut_down_xml']
00237 p = gtest_test_utils.Subprocess(command)
00238 if p.terminated_by_signal:
00239
00240 self.assertFalse(
00241 p.terminated_by_signal,
00242 '%s was killed by signal %d' % (GTEST_PROGRAM_NAME, p.signal))
00243 else:
00244 self.assert_(p.exited)
00245 self.assertEquals(1, p.exit_code,
00246 "'%s' exited with code %s, which doesn't match "
00247 'the expected exit code %s.'
00248 % (command, p.exit_code, 1))
00249
00250 self.assert_(not os.path.isfile(xml_path))
00251
00252 def testFilteredTestXmlOutput(self):
00253 """Verifies XML output when a filter is applied.
00254
00255 Runs a test program that executes only some tests and verifies that
00256 non-selected tests do not show up in the XML output.
00257 """
00258
00259 self._TestXmlOutput(GTEST_PROGRAM_NAME, EXPECTED_FILTERED_TEST_XML, 0,
00260 extra_args=['%s=SuccessfulTest.*' % GTEST_FILTER_FLAG])
00261
00262 def _GetXmlOutput(self, gtest_prog_name, extra_args, expected_exit_code):
00263 """
00264 Returns the xml output generated by running the program gtest_prog_name.
00265 Furthermore, the program's exit code must be expected_exit_code.
00266 """
00267 xml_path = os.path.join(gtest_test_utils.GetTempDir(),
00268 gtest_prog_name + 'out.xml')
00269 gtest_prog_path = gtest_test_utils.GetTestExecutablePath(gtest_prog_name)
00270
00271 command = ([gtest_prog_path, '%s=xml:%s' % (GTEST_OUTPUT_FLAG, xml_path)] +
00272 extra_args)
00273 p = gtest_test_utils.Subprocess(command)
00274 if p.terminated_by_signal:
00275 self.assert_(False,
00276 '%s was killed by signal %d' % (gtest_prog_name, p.signal))
00277 else:
00278 self.assert_(p.exited)
00279 self.assertEquals(expected_exit_code, p.exit_code,
00280 "'%s' exited with code %s, which doesn't match "
00281 'the expected exit code %s.'
00282 % (command, p.exit_code, expected_exit_code))
00283 actual = minidom.parse(xml_path)
00284 return actual
00285
00286 def _TestXmlOutput(self, gtest_prog_name, expected_xml,
00287 expected_exit_code, extra_args=None):
00288 """
00289 Asserts that the XML document generated by running the program
00290 gtest_prog_name matches expected_xml, a string containing another
00291 XML document. Furthermore, the program's exit code must be
00292 expected_exit_code.
00293 """
00294
00295 actual = self._GetXmlOutput(gtest_prog_name, extra_args or [],
00296 expected_exit_code)
00297 expected = minidom.parseString(expected_xml)
00298 self.NormalizeXml(actual.documentElement)
00299 self.AssertEquivalentNodes(expected.documentElement,
00300 actual.documentElement)
00301 expected.unlink()
00302 actual.unlink()
00303
00304
00305 if __name__ == '__main__':
00306 os.environ['GTEST_STACK_TRACE_DEPTH'] = '1'
00307 gtest_test_utils.Main()