gtest_xml_output_unittest.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 #
3 # Copyright 2006, Google Inc.
4 # All rights reserved.
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions are
8 # met:
9 #
10 # * Redistributions of source code must retain the above copyright
11 # notice, this list of conditions and the following disclaimer.
12 # * Redistributions in binary form must reproduce the above
13 # copyright notice, this list of conditions and the following disclaimer
14 # in the documentation and/or other materials provided with the
15 # distribution.
16 # * Neither the name of Google Inc. nor the names of its
17 # contributors may be used to endorse or promote products derived from
18 # this software without specific prior written permission.
19 #
20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 
32 """Unit test for the gtest_xml_output module"""
33 
34 import datetime
35 import errno
36 import os
37 import re
38 import sys
39 from xml.dom import minidom, Node
40 
41 import gtest_test_utils
42 import gtest_xml_test_utils
43 
44 GTEST_FILTER_FLAG = '--gtest_filter'
45 GTEST_LIST_TESTS_FLAG = '--gtest_list_tests'
46 GTEST_OUTPUT_FLAG = '--gtest_output'
47 GTEST_DEFAULT_OUTPUT_FILE = 'test_detail.xml'
48 GTEST_PROGRAM_NAME = 'gtest_xml_output_unittest_'
49 
50 # The flag indicating stacktraces are not supported
51 NO_STACKTRACE_SUPPORT_FLAG = '--no_stacktrace_support'
52 
53 # The environment variables for test sharding.
54 TOTAL_SHARDS_ENV_VAR = 'GTEST_TOTAL_SHARDS'
55 SHARD_INDEX_ENV_VAR = 'GTEST_SHARD_INDEX'
56 SHARD_STATUS_FILE_ENV_VAR = 'GTEST_SHARD_STATUS_FILE'
57 
58 SUPPORTS_STACK_TRACES = NO_STACKTRACE_SUPPORT_FLAG not in sys.argv
59 
60 if SUPPORTS_STACK_TRACES:
61  STACK_TRACE_TEMPLATE = '\nStack trace:\n*'
62 else:
63  STACK_TRACE_TEMPLATE = ''
64  # unittest.main() can't handle unknown flags
65  sys.argv.remove(NO_STACKTRACE_SUPPORT_FLAG)
66 
67 EXPECTED_NON_EMPTY_XML = """<?xml version="1.0" encoding="UTF-8"?>
68 <testsuites tests="24" failures="4" disabled="2" errors="0" time="*" timestamp="*" name="AllTests" ad_hoc_property="42">
69  <testsuite name="SuccessfulTest" tests="1" failures="0" disabled="0" errors="0" time="*">
70  <testcase name="Succeeds" status="run" time="*" classname="SuccessfulTest"/>
71  </testsuite>
72  <testsuite name="FailedTest" tests="1" failures="1" disabled="0" errors="0" time="*">
73  <testcase name="Fails" status="run" time="*" classname="FailedTest">
74  <failure message="gtest_xml_output_unittest_.cc:*&#x0A;Expected equality of these values:&#x0A; 1&#x0A; 2" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
75 Expected equality of these values:
76  1
77  2%(stack)s]]></failure>
78  </testcase>
79  </testsuite>
80  <testsuite name="MixedResultTest" tests="3" failures="1" disabled="1" errors="0" time="*">
81  <testcase name="Succeeds" status="run" time="*" classname="MixedResultTest"/>
82  <testcase name="Fails" status="run" time="*" classname="MixedResultTest">
83  <failure message="gtest_xml_output_unittest_.cc:*&#x0A;Expected equality of these values:&#x0A; 1&#x0A; 2" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
84 Expected equality of these values:
85  1
86  2%(stack)s]]></failure>
87  <failure message="gtest_xml_output_unittest_.cc:*&#x0A;Expected equality of these values:&#x0A; 2&#x0A; 3" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
88 Expected equality of these values:
89  2
90  3%(stack)s]]></failure>
91  </testcase>
92  <testcase name="DISABLED_test" status="notrun" time="*" classname="MixedResultTest"/>
93  </testsuite>
94  <testsuite name="XmlQuotingTest" tests="1" failures="1" disabled="0" errors="0" time="*">
95  <testcase name="OutputsCData" status="run" time="*" classname="XmlQuotingTest">
96  <failure message="gtest_xml_output_unittest_.cc:*&#x0A;Failed&#x0A;XML output: &lt;?xml encoding=&quot;utf-8&quot;&gt;&lt;top&gt;&lt;![CDATA[cdata text]]&gt;&lt;/top&gt;" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
97 Failed
98 XML output: <?xml encoding="utf-8"><top><![CDATA[cdata text]]>]]&gt;<![CDATA[</top>%(stack)s]]></failure>
99  </testcase>
100  </testsuite>
101  <testsuite name="InvalidCharactersTest" tests="1" failures="1" disabled="0" errors="0" time="*">
102  <testcase name="InvalidCharactersInMessage" status="run" time="*" classname="InvalidCharactersTest">
103  <failure message="gtest_xml_output_unittest_.cc:*&#x0A;Failed&#x0A;Invalid characters in brackets []" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
104 Failed
105 Invalid characters in brackets []%(stack)s]]></failure>
106  </testcase>
107  </testsuite>
108  <testsuite name="DisabledTest" tests="1" failures="0" disabled="1" errors="0" time="*">
109  <testcase name="DISABLED_test_not_run" status="notrun" time="*" classname="DisabledTest"/>
110  </testsuite>
111  <testsuite name="SkippedTest" tests="1" failures="0" disabled="0" errors="0" time="*">
112  <testcase name="Skipped" status="skipped" time="*" classname="SkippedTest"/>
113  </testsuite>
114  <testsuite name="PropertyRecordingTest" tests="4" failures="0" disabled="0" errors="0" time="*" SetUpTestSuite="yes" TearDownTestSuite="aye">
115  <testcase name="OneProperty" status="run" time="*" classname="PropertyRecordingTest">
116  <properties>
117  <property name="key_1" value="1"/>
118  </properties>
119  </testcase>
120  <testcase name="IntValuedProperty" status="run" time="*" classname="PropertyRecordingTest">
121  <properties>
122  <property name="key_int" value="1"/>
123  </properties>
124  </testcase>
125  <testcase name="ThreeProperties" status="run" time="*" classname="PropertyRecordingTest">
126  <properties>
127  <property name="key_1" value="1"/>
128  <property name="key_2" value="2"/>
129  <property name="key_3" value="3"/>
130  </properties>
131  </testcase>
132  <testcase name="TwoValuesForOneKeyUsesLastValue" status="run" time="*" classname="PropertyRecordingTest">
133  <properties>
134  <property name="key_1" value="2"/>
135  </properties>
136  </testcase>
137  </testsuite>
138  <testsuite name="NoFixtureTest" tests="3" failures="0" disabled="0" errors="0" time="*">
139  <testcase name="RecordProperty" status="run" time="*" classname="NoFixtureTest">
140  <properties>
141  <property name="key" value="1"/>
142  </properties>
143  </testcase>
144  <testcase name="ExternalUtilityThatCallsRecordIntValuedProperty" status="run" time="*" classname="NoFixtureTest">
145  <properties>
146  <property name="key_for_utility_int" value="1"/>
147  </properties>
148  </testcase>
149  <testcase name="ExternalUtilityThatCallsRecordStringValuedProperty" status="run" time="*" classname="NoFixtureTest">
150  <properties>
151  <property name="key_for_utility_string" value="1"/>
152  </properties>
153  </testcase>
154  </testsuite>
155  <testsuite name="Single/ValueParamTest" tests="4" failures="0" disabled="0" errors="0" time="*">
156  <testcase name="HasValueParamAttribute/0" value_param="33" status="run" time="*" classname="Single/ValueParamTest" />
157  <testcase name="HasValueParamAttribute/1" value_param="42" status="run" time="*" classname="Single/ValueParamTest" />
158  <testcase name="AnotherTestThatHasValueParamAttribute/0" value_param="33" status="run" time="*" classname="Single/ValueParamTest" />
159  <testcase name="AnotherTestThatHasValueParamAttribute/1" value_param="42" status="run" time="*" classname="Single/ValueParamTest" />
160  </testsuite>
161  <testsuite name="TypedTest/0" tests="1" failures="0" disabled="0" errors="0" time="*">
162  <testcase name="HasTypeParamAttribute" type_param="*" status="run" time="*" classname="TypedTest/0" />
163  </testsuite>
164  <testsuite name="TypedTest/1" tests="1" failures="0" disabled="0" errors="0" time="*">
165  <testcase name="HasTypeParamAttribute" type_param="*" status="run" time="*" classname="TypedTest/1" />
166  </testsuite>
167  <testsuite name="Single/TypeParameterizedTestSuite/0" tests="1" failures="0" disabled="0" errors="0" time="*">
168  <testcase name="HasTypeParamAttribute" type_param="*" status="run" time="*" classname="Single/TypeParameterizedTestSuite/0" />
169  </testsuite>
170  <testsuite name="Single/TypeParameterizedTestSuite/1" tests="1" failures="0" disabled="0" errors="0" time="*">
171  <testcase name="HasTypeParamAttribute" type_param="*" status="run" time="*" classname="Single/TypeParameterizedTestSuite/1" />
172  </testsuite>
173 </testsuites>""" % {'stack': STACK_TRACE_TEMPLATE}
174 
175 EXPECTED_FILTERED_TEST_XML = """<?xml version="1.0" encoding="UTF-8"?>
176 <testsuites tests="1" failures="0" disabled="0" errors="0" time="*"
177  timestamp="*" name="AllTests" ad_hoc_property="42">
178  <testsuite name="SuccessfulTest" tests="1" failures="0" disabled="0"
179  errors="0" time="*">
180  <testcase name="Succeeds" status="run" time="*" classname="SuccessfulTest"/>
181  </testsuite>
182 </testsuites>"""
183 
184 EXPECTED_SHARDED_TEST_XML = """<?xml version="1.0" encoding="UTF-8"?>
185 <testsuites tests="3" failures="0" disabled="0" errors="0" time="*" timestamp="*" name="AllTests" ad_hoc_property="42">
186  <testsuite name="SuccessfulTest" tests="1" failures="0" disabled="0" errors="0" time="*">
187  <testcase name="Succeeds" status="run" time="*" classname="SuccessfulTest"/>
188  </testsuite>
189  <testsuite name="PropertyRecordingTest" tests="1" failures="0" disabled="0" errors="0" time="*" SetUpTestSuite="yes" TearDownTestSuite="aye">
190  <testcase name="TwoValuesForOneKeyUsesLastValue" status="run" time="*" classname="PropertyRecordingTest">
191  <properties>
192  <property name="key_1" value="2"/>
193  </properties>
194  </testcase>
195  </testsuite>
196  <testsuite name="Single/ValueParamTest" tests="1" failures="0" disabled="0" errors="0" time="*">
197  <testcase name="AnotherTestThatHasValueParamAttribute/0" value_param="33" status="run" time="*" classname="Single/ValueParamTest" />
198  </testsuite>
199 </testsuites>"""
200 
201 EXPECTED_EMPTY_XML = """<?xml version="1.0" encoding="UTF-8"?>
202 <testsuites tests="0" failures="0" disabled="0" errors="0" time="*"
203  timestamp="*" name="AllTests">
204 </testsuites>"""
205 
206 GTEST_PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath(GTEST_PROGRAM_NAME)
207 
208 SUPPORTS_TYPED_TESTS = 'TypedTest' in gtest_test_utils.Subprocess(
209  [GTEST_PROGRAM_PATH, GTEST_LIST_TESTS_FLAG], capture_stderr=False).output
210 
211 
213  """
214  Unit test for Google Test's XML output functionality.
215  """
216 
217  # This test currently breaks on platforms that do not support typed and
218  # type-parameterized tests, so we don't run it under them.
219  if SUPPORTS_TYPED_TESTS:
221  """
222  Runs a test program that generates a non-empty XML output, and
223  tests that the XML output is expected.
224  """
225  self._TestXmlOutput(GTEST_PROGRAM_NAME, EXPECTED_NON_EMPTY_XML, 1)
226 
228  """Verifies XML output for a Google Test binary without actual tests.
229 
230  Runs a test program that generates an empty XML output, and
231  tests that the XML output is expected.
232  """
233 
234  self._TestXmlOutput('gtest_no_test_unittest', EXPECTED_EMPTY_XML, 0)
235 
237  """Checks whether the timestamp attribute in the XML output is valid.
238 
239  Runs a test program that generates an empty XML output, and checks if
240  the timestamp attribute in the testsuites tag is valid.
241  """
242  actual = self._GetXmlOutput('gtest_no_test_unittest', [], {}, 0)
243  date_time_str = actual.documentElement.getAttributeNode('timestamp').value
244  # datetime.strptime() is only available in Python 2.5+ so we have to
245  # parse the expected datetime manually.
246  match = re.match(r'(\d+)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)', date_time_str)
247  self.assertTrue(
248  re.match,
249  'XML datettime string %s has incorrect format' % date_time_str)
250  date_time_from_xml = datetime.datetime(
251  year=int(match.group(1)), month=int(match.group(2)),
252  day=int(match.group(3)), hour=int(match.group(4)),
253  minute=int(match.group(5)), second=int(match.group(6)))
254 
255  time_delta = abs(datetime.datetime.now() - date_time_from_xml)
256  # timestamp value should be near the current local time
257  self.assertTrue(time_delta < datetime.timedelta(seconds=600),
258  'time_delta is %s' % time_delta)
259  actual.unlink()
260 
262  """
263  Confirms that Google Test produces an XML output file with the expected
264  default name if no name is explicitly specified.
265  """
266  output_file = os.path.join(gtest_test_utils.GetTempDir(),
267  GTEST_DEFAULT_OUTPUT_FILE)
268  gtest_prog_path = gtest_test_utils.GetTestExecutablePath(
269  'gtest_no_test_unittest')
270  try:
271  os.remove(output_file)
272  except OSError:
273  e = sys.exc_info()[1]
274  if e.errno != errno.ENOENT:
275  raise
276 
278  [gtest_prog_path, '%s=xml' % GTEST_OUTPUT_FLAG],
279  working_dir=gtest_test_utils.GetTempDir())
280  self.assert_(p.exited)
281  self.assertEquals(0, p.exit_code)
282  self.assert_(os.path.isfile(output_file))
283 
285  """
286  Tests that no XML file is generated if the default XML listener is
287  shut down before RUN_ALL_TESTS is invoked.
288  """
289 
290  xml_path = os.path.join(gtest_test_utils.GetTempDir(),
291  GTEST_PROGRAM_NAME + 'out.xml')
292  if os.path.isfile(xml_path):
293  os.remove(xml_path)
294 
295  command = [GTEST_PROGRAM_PATH,
296  '%s=xml:%s' % (GTEST_OUTPUT_FLAG, xml_path),
297  '--shut_down_xml']
298  p = gtest_test_utils.Subprocess(command)
299  if p.terminated_by_signal:
300  # p.signal is available only if p.terminated_by_signal is True.
301  self.assertFalse(
302  p.terminated_by_signal,
303  '%s was killed by signal %d' % (GTEST_PROGRAM_NAME, p.signal))
304  else:
305  self.assert_(p.exited)
306  self.assertEquals(1, p.exit_code,
307  "'%s' exited with code %s, which doesn't match "
308  'the expected exit code %s.'
309  % (command, p.exit_code, 1))
310 
311  self.assert_(not os.path.isfile(xml_path))
312 
314  """Verifies XML output when a filter is applied.
315 
316  Runs a test program that executes only some tests and verifies that
317  non-selected tests do not show up in the XML output.
318  """
319 
320  self._TestXmlOutput(GTEST_PROGRAM_NAME, EXPECTED_FILTERED_TEST_XML, 0,
321  extra_args=['%s=SuccessfulTest.*' % GTEST_FILTER_FLAG])
322 
324  """Verifies XML output when run using multiple shards.
325 
326  Runs a test program that executes only one shard and verifies that tests
327  from other shards do not show up in the XML output.
328  """
329 
330  self._TestXmlOutput(
331  GTEST_PROGRAM_NAME,
332  EXPECTED_SHARDED_TEST_XML,
333  0,
334  extra_env={SHARD_INDEX_ENV_VAR: '0',
335  TOTAL_SHARDS_ENV_VAR: '10'})
336 
337  def _GetXmlOutput(self, gtest_prog_name, extra_args, extra_env,
338  expected_exit_code):
339  """
340  Returns the xml output generated by running the program gtest_prog_name.
341  Furthermore, the program's exit code must be expected_exit_code.
342  """
343  xml_path = os.path.join(gtest_test_utils.GetTempDir(),
344  gtest_prog_name + 'out.xml')
345  gtest_prog_path = gtest_test_utils.GetTestExecutablePath(gtest_prog_name)
346 
347  command = ([gtest_prog_path, '%s=xml:%s' % (GTEST_OUTPUT_FLAG, xml_path)] +
348  extra_args)
349  environ_copy = os.environ.copy()
350  if extra_env:
351  environ_copy.update(extra_env)
352  p = gtest_test_utils.Subprocess(command, env=environ_copy)
353 
354  if p.terminated_by_signal:
355  self.assert_(False,
356  '%s was killed by signal %d' % (gtest_prog_name, p.signal))
357  else:
358  self.assert_(p.exited)
359  self.assertEquals(expected_exit_code, p.exit_code,
360  "'%s' exited with code %s, which doesn't match "
361  'the expected exit code %s.'
362  % (command, p.exit_code, expected_exit_code))
363  actual = minidom.parse(xml_path)
364  return actual
365 
366  def _TestXmlOutput(self, gtest_prog_name, expected_xml,
367  expected_exit_code, extra_args=None, extra_env=None):
368  """
369  Asserts that the XML document generated by running the program
370  gtest_prog_name matches expected_xml, a string containing another
371  XML document. Furthermore, the program's exit code must be
372  expected_exit_code.
373  """
374 
375  actual = self._GetXmlOutput(gtest_prog_name, extra_args or [],
376  extra_env or {}, expected_exit_code)
377  expected = minidom.parseString(expected_xml)
378  self.NormalizeXml(actual.documentElement)
379  self.AssertEquivalentNodes(expected.documentElement,
380  actual.documentElement)
381  expected.unlink()
382  actual.unlink()
383 
384 
385 if __name__ == '__main__':
386  os.environ['GTEST_STACK_TRACE_DEPTH'] = '1'
gtest_xml_output_unittest.GTestXMLOutputUnitTest.testSuppressedXmlOutput
def testSuppressedXmlOutput(self)
Definition: gtest_xml_output_unittest.py:284
gtest_xml_output_unittest.GTestXMLOutputUnitTest._GetXmlOutput
def _GetXmlOutput(self, gtest_prog_name, extra_args, extra_env, expected_exit_code)
Definition: gtest_xml_output_unittest.py:337
gtest_test_utils.Main
def Main()
Definition: gtest_test_utils.py:301
gtest_xml_output_unittest.GTestXMLOutputUnitTest.testNonEmptyXmlOutput
def testNonEmptyXmlOutput(self)
Definition: gtest_xml_output_unittest.py:220
gtest_xml_output_unittest.GTestXMLOutputUnitTest.testDefaultOutputFile
def testDefaultOutputFile(self)
Definition: gtest_xml_output_unittest.py:261
gtest_test_utils.Subprocess
Definition: gtest_test_utils.py:202
gtest_xml_output_unittest.GTestXMLOutputUnitTest
Definition: gtest_xml_output_unittest.py:212
gtest_xml_output_unittest.GTestXMLOutputUnitTest.testEmptyXmlOutput
def testEmptyXmlOutput(self)
Definition: gtest_xml_output_unittest.py:227
gtest_xml_test_utils.GTestXMLTestCase.AssertEquivalentNodes
def AssertEquivalentNodes(self, expected_node, actual_node)
Definition: gtest_xml_test_utils.py:44
gtest_xml_test_utils.GTestXMLTestCase.NormalizeXml
def NormalizeXml(self, element)
Definition: gtest_xml_test_utils.py:152
gtest_test_utils.GetTempDir
def GetTempDir()
Definition: gtest_test_utils.py:144
gtest_xml_output_unittest.GTestXMLOutputUnitTest.testTimestampValue
def testTimestampValue(self)
Definition: gtest_xml_output_unittest.py:236
gtest_xml_output_unittest.GTestXMLOutputUnitTest.testFilteredTestXmlOutput
def testFilteredTestXmlOutput(self)
Definition: gtest_xml_output_unittest.py:313
gtest_test_utils.GetTestExecutablePath
def GetTestExecutablePath(executable_name, build_dir=None)
Definition: gtest_test_utils.py:151
gtest_xml_output_unittest.GTestXMLOutputUnitTest._TestXmlOutput
def _TestXmlOutput(self, gtest_prog_name, expected_xml, expected_exit_code, extra_args=None, extra_env=None)
Definition: gtest_xml_output_unittest.py:366
gtest_xml_output_unittest.GTestXMLOutputUnitTest.testShardedTestXmlOutput
def testShardedTestXmlOutput(self)
Definition: gtest_xml_output_unittest.py:323
gtest_xml_test_utils.GTestXMLTestCase
Definition: gtest_xml_test_utils.py:38


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:54