From d201456903f3ecae1f7794edfab0d5678e642265 Mon Sep 17 00:00:00 2001 From: shiqian Date: Thu, 3 Jul 2008 22:38:12 +0000 Subject: Initial import. --- test/gtest_xml_test_utils.py | 138 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100755 test/gtest_xml_test_utils.py (limited to 'test/gtest_xml_test_utils.py') diff --git a/test/gtest_xml_test_utils.py b/test/gtest_xml_test_utils.py new file mode 100755 index 00000000..c2ea9c1d --- /dev/null +++ b/test/gtest_xml_test_utils.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python +# +# Copyright 2006, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Unit test utilities for gtest_xml_output""" + +__author__ = 'eefacm@gmail.com (Sean Mcafee)' + +import re +import unittest + +from xml.dom import minidom, Node + +GTEST_OUTPUT_FLAG = "--gtest_output" +GTEST_DEFAULT_OUTPUT_FILE = "test_detail.xml" + +class GTestXMLTestCase(unittest.TestCase): + """ + Base class for tests of Google Test's XML output functionality. + """ + + + def _AssertEquivalentElements(self, expected_element, actual_element): + """ + Asserts that actual_element (a DOM element object) is equivalent to + expected_element (another DOM element object), in that it meets all + of the following conditions: + * It has the same tag name as expected_element. + * It has the same set of attributes as expected_element, each with + the same value as the corresponding attribute of expected_element. + An exception is any attribute named "time", which need only be + convertible to a long integer. + * Each child element is equivalent to a child element of + expected_element. Child elements are matched according to an + attribute that varies depending on the element; "name" for + and elements, "message" for + elements. This matching is necessary because child elements are + not guaranteed to be ordered in any particular way. + """ + self.assertEquals(expected_element.tagName, actual_element.tagName) + + expected_attributes = expected_element.attributes + actual_attributes = actual_element .attributes + self.assertEquals(expected_attributes.length, actual_attributes.length) + for i in range(expected_attributes.length): + expected_attr = expected_attributes.item(i) + actual_attr = actual_attributes.get(expected_attr.name) + self.assert_(actual_attr is not None) + self.assertEquals(expected_attr.value, actual_attr.value) + + expected_child = self._GetChildElements(expected_element) + actual_child = self._GetChildElements(actual_element) + self.assertEquals(len(expected_child), len(actual_child)) + for child_id, element in expected_child.iteritems(): + self.assert_(child_id in actual_child, + '<%s> is not in <%s>' % (child_id, actual_child)) + self._AssertEquivalentElements(element, actual_child[child_id]) + + identifying_attribute = { + "testsuite": "name", + "testcase": "name", + "failure": "message", + } + + def _GetChildElements(self, element): + """ + Fetches all of the Element type child nodes of element, a DOM + Element object. Returns them as the values of a dictionary keyed by + the value of one of the node's attributes. For and + elements, the identifying attribute is "name"; for + elements, it is "message". An exception is raised if + any element other than the above three is encountered, if two + child elements with the same identifying attributes are encountered, + or if any other type of node is encountered, other than Text nodes + containing only whitespace. + """ + children = {} + for child in element.childNodes: + if child.nodeType == Node.ELEMENT_NODE: + self.assert_(child.tagName in self.identifying_attribute, + "Encountered unknown element <%s>" % child.tagName) + childID = child.getAttribute(self.identifying_attribute[child.tagName]) + self.assert_(childID not in children) + children[childID] = child + elif child.nodeType == Node.TEXT_NODE: + self.assert_(child.nodeValue.isspace()) + else: + self.fail("Encountered unexpected node type %d" % child.nodeType) + return children + + def _NormalizeXml(self, element): + """ + Normalizes Google Test's XML output to eliminate references to transient + information that may change from run to run. + + * The "time" attribute of and elements is + replaced with a single asterisk, if it contains only digit + characters. + * The line number reported in the first line of the "message" + attribute of elements is replaced with a single asterisk. + * The directory names in file paths are removed. + """ + if element.tagName in ("testsuite", "testcase"): + time = element.getAttributeNode("time") + time.value = re.sub(r"^\d+$", "*", time.value) + elif element.tagName == "failure": + message = element.getAttributeNode("message") + message.value = re.sub(r"^.*/(.*:)\d+\n", "\\1*\n", message.value) + for child in element.childNodes: + if child.nodeType == Node.ELEMENT_NODE: + self._NormalizeXml(child) -- cgit v1.2.3 From 64cdcb69b28fc26e78d95c574187f7dd9830c84c Mon Sep 17 00:00:00 2001 From: shiqian Date: Fri, 26 Sep 2008 16:08:30 +0000 Subject: Lots of changes: * changes the XML report format to match JUnit/Ant's. * improves file path handling. * allows the user to disable RTTI using the GTEST_HAS_RTTI macro. * makes the code compile with -Wswitch-enum. --- test/gtest_xml_test_utils.py | 100 ++++++++++++++++++++++++++----------------- 1 file changed, 60 insertions(+), 40 deletions(-) (limited to 'test/gtest_xml_test_utils.py') diff --git a/test/gtest_xml_test_utils.py b/test/gtest_xml_test_utils.py index c2ea9c1d..5694dff9 100755 --- a/test/gtest_xml_test_utils.py +++ b/test/gtest_xml_test_utils.py @@ -47,27 +47,35 @@ class GTestXMLTestCase(unittest.TestCase): """ - def _AssertEquivalentElements(self, expected_element, actual_element): + def AssertEquivalentNodes(self, expected_node, actual_node): """ - Asserts that actual_element (a DOM element object) is equivalent to - expected_element (another DOM element object), in that it meets all - of the following conditions: - * It has the same tag name as expected_element. - * It has the same set of attributes as expected_element, each with - the same value as the corresponding attribute of expected_element. - An exception is any attribute named "time", which need only be - convertible to a long integer. - * Each child element is equivalent to a child element of - expected_element. Child elements are matched according to an - attribute that varies depending on the element; "name" for - and elements, "message" for - elements. This matching is necessary because child elements are - not guaranteed to be ordered in any particular way. + Asserts that actual_node (a DOM node object) is equivalent to + expected_node (another DOM node object), in that either both of + them are CDATA nodes and have the same value, or both are DOM + elements and actual_node meets all of the following conditions: + + * It has the same tag name as expected_node. + * It has the same set of attributes as expected_node, each with + the same value as the corresponding attribute of expected_node. + An exception is any attribute named "time", which needs only be + convertible to a floating-point number. + * It has an equivalent set of child nodes (including elements and + CDATA sections) as expected_node. Note that we ignore the + order of the children as they are not guaranteed to be in any + particular order. """ - self.assertEquals(expected_element.tagName, actual_element.tagName) - expected_attributes = expected_element.attributes - actual_attributes = actual_element .attributes + if expected_node.nodeType == Node.CDATA_SECTION_NODE: + self.assertEquals(Node.CDATA_SECTION_NODE, actual_node.nodeType) + self.assertEquals(expected_node.nodeValue, actual_node.nodeValue) + return + + self.assertEquals(Node.ELEMENT_NODE, actual_node.nodeType) + self.assertEquals(Node.ELEMENT_NODE, expected_node.nodeType) + self.assertEquals(expected_node.tagName, actual_node.tagName) + + expected_attributes = expected_node.attributes + actual_attributes = actual_node .attributes self.assertEquals(expected_attributes.length, actual_attributes.length) for i in range(expected_attributes.length): expected_attr = expected_attributes.item(i) @@ -75,13 +83,13 @@ class GTestXMLTestCase(unittest.TestCase): self.assert_(actual_attr is not None) self.assertEquals(expected_attr.value, actual_attr.value) - expected_child = self._GetChildElements(expected_element) - actual_child = self._GetChildElements(actual_element) - self.assertEquals(len(expected_child), len(actual_child)) - for child_id, element in expected_child.iteritems(): - self.assert_(child_id in actual_child, - '<%s> is not in <%s>' % (child_id, actual_child)) - self._AssertEquivalentElements(element, actual_child[child_id]) + expected_children = self._GetChildren(expected_node) + actual_children = self._GetChildren(actual_node) + self.assertEquals(len(expected_children), len(actual_children)) + for child_id, child in expected_children.iteritems(): + self.assert_(child_id in actual_children, + '<%s> is not in <%s>' % (child_id, actual_children)) + self.AssertEquivalentNodes(child, actual_children[child_id]) identifying_attribute = { "testsuite": "name", @@ -89,18 +97,20 @@ class GTestXMLTestCase(unittest.TestCase): "failure": "message", } - def _GetChildElements(self, element): + def _GetChildren(self, element): """ - Fetches all of the Element type child nodes of element, a DOM - Element object. Returns them as the values of a dictionary keyed by - the value of one of the node's attributes. For and - elements, the identifying attribute is "name"; for - elements, it is "message". An exception is raised if - any element other than the above three is encountered, if two - child elements with the same identifying attributes are encountered, - or if any other type of node is encountered, other than Text nodes - containing only whitespace. + Fetches all of the child nodes of element, a DOM Element object. + Returns them as the values of a dictionary keyed by the IDs of the + children. For and elements, the ID is the + value of their "name" attribute; for elements, it is the + value of the "message" attribute; for CDATA section node, it is + "detail". An exception is raised if any element other than the + above four is encountered, if two child elements with the same + identifying attributes are encountered, or if any other type of + node is encountered, other than Text nodes containing only + whitespace. """ + children = {} for child in element.childNodes: if child.nodeType == Node.ELEMENT_NODE: @@ -111,11 +121,14 @@ class GTestXMLTestCase(unittest.TestCase): children[childID] = child elif child.nodeType == Node.TEXT_NODE: self.assert_(child.nodeValue.isspace()) + elif child.nodeType == Node.CDATA_SECTION_NODE: + self.assert_("detail" not in children) + children["detail"] = child else: self.fail("Encountered unexpected node type %d" % child.nodeType) return children - def _NormalizeXml(self, element): + def NormalizeXml(self, element): """ Normalizes Google Test's XML output to eliminate references to transient information that may change from run to run. @@ -126,13 +139,20 @@ class GTestXMLTestCase(unittest.TestCase): * The line number reported in the first line of the "message" attribute of elements is replaced with a single asterisk. * The directory names in file paths are removed. + * The stack traces are removed. """ + if element.tagName in ("testsuite", "testcase"): time = element.getAttributeNode("time") - time.value = re.sub(r"^\d+$", "*", time.value) + time.value = re.sub(r"^\d+(\.\d+)?$", "*", time.value) elif element.tagName == "failure": - message = element.getAttributeNode("message") - message.value = re.sub(r"^.*/(.*:)\d+\n", "\\1*\n", message.value) + for child in element.childNodes: + if child.nodeType == Node.CDATA_SECTION_NODE: + # Removes the source line number. + cdata = re.sub(r"^.*/(.*:)\d+\n", "\\1*\n", child.nodeValue) + # Removes the actual stack trace. + child.nodeValue = re.sub(r"\nStack trace:\n(.|\n)*", + "", cdata) for child in element.childNodes: if child.nodeType == Node.ELEMENT_NODE: - self._NormalizeXml(child) + self.NormalizeXml(child) -- cgit v1.2.3 From 2c0fc6d415343b732a4ae39cce1458be1170b9f6 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Tue, 24 Mar 2009 20:39:44 +0000 Subject: Cleans up death test implementation (by Vlad Losev); changes the XML format to be closer to junitreport (by Zhanyong Wan). --- test/gtest_xml_test_utils.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'test/gtest_xml_test_utils.py') diff --git a/test/gtest_xml_test_utils.py b/test/gtest_xml_test_utils.py index 5694dff9..00a56cbf 100755 --- a/test/gtest_xml_test_utils.py +++ b/test/gtest_xml_test_utils.py @@ -92,6 +92,7 @@ class GTestXMLTestCase(unittest.TestCase): self.AssertEquivalentNodes(child, actual_children[child_id]) identifying_attribute = { + "testsuites": "name", "testsuite": "name", "testcase": "name", "failure": "message", @@ -101,14 +102,14 @@ class GTestXMLTestCase(unittest.TestCase): """ Fetches all of the child nodes of element, a DOM Element object. Returns them as the values of a dictionary keyed by the IDs of the - children. For and elements, the ID is the - value of their "name" attribute; for elements, it is the - value of the "message" attribute; for CDATA section node, it is - "detail". An exception is raised if any element other than the - above four is encountered, if two child elements with the same - identifying attributes are encountered, or if any other type of - node is encountered, other than Text nodes containing only - whitespace. + children. For , and elements, + the ID is the value of their "name" attribute; for + elements, it is the value of the "message" attribute; for CDATA + section node, it is "detail". An exception is raised if any + element other than the above four is encountered, if two child + elements with the same identifying attributes are encountered, or + if any other type of node is encountered, other than Text nodes + containing only whitespace. """ children = {} @@ -133,16 +134,16 @@ class GTestXMLTestCase(unittest.TestCase): Normalizes Google Test's XML output to eliminate references to transient information that may change from run to run. - * The "time" attribute of and elements is - replaced with a single asterisk, if it contains only digit - characters. + * The "time" attribute of , and + elements is replaced with a single asterisk, if it contains + only digit characters. * The line number reported in the first line of the "message" attribute of elements is replaced with a single asterisk. * The directory names in file paths are removed. * The stack traces are removed. """ - if element.tagName in ("testsuite", "testcase"): + if element.tagName in ("testsuites", "testsuite", "testcase"): time = element.getAttributeNode("time") time.value = re.sub(r"^\d+(\.\d+)?$", "*", time.value) elif element.tagName == "failure": -- cgit v1.2.3 From 7fa242a44b47ce74d7246440b14571f7a5dd1b17 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Thu, 9 Apr 2009 02:57:38 +0000 Subject: Makes the Python tests more stable (by Vlad Losev); fixes a memory leak in GetThreadCount() on Mac (by Vlad Losev); improves fuse_gtest_files.py to support fusing Google Mock files (by Zhanyong Wan). --- test/gtest_xml_test_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/gtest_xml_test_utils.py') diff --git a/test/gtest_xml_test_utils.py b/test/gtest_xml_test_utils.py index 00a56cbf..64eebb10 100755 --- a/test/gtest_xml_test_utils.py +++ b/test/gtest_xml_test_utils.py @@ -150,7 +150,7 @@ class GTestXMLTestCase(unittest.TestCase): for child in element.childNodes: if child.nodeType == Node.CDATA_SECTION_NODE: # Removes the source line number. - cdata = re.sub(r"^.*/(.*:)\d+\n", "\\1*\n", child.nodeValue) + cdata = re.sub(r"^.*[/\\](.*:)\d+\n", "\\1*\n", child.nodeValue) # Removes the actual stack trace. child.nodeValue = re.sub(r"\nStack trace:\n(.|\n)*", "", cdata) -- cgit v1.2.3 From 532dc2de35f2cef191bc91c3587a9f8f4974756f Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 17 Jun 2009 21:06:27 +0000 Subject: Implements a subset of TR1 tuple needed by gtest and gmock (by Zhanyong Wan); cleaned up the Python tests (by Vlad Losev); made run_tests.py invokable from any directory (by Vlad Losev). --- test/gtest_xml_test_utils.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'test/gtest_xml_test_utils.py') diff --git a/test/gtest_xml_test_utils.py b/test/gtest_xml_test_utils.py index 64eebb10..1811c408 100755 --- a/test/gtest_xml_test_utils.py +++ b/test/gtest_xml_test_utils.py @@ -34,14 +34,15 @@ __author__ = 'eefacm@gmail.com (Sean Mcafee)' import re -import unittest - from xml.dom import minidom, Node +import gtest_test_utils + + GTEST_OUTPUT_FLAG = "--gtest_output" GTEST_DEFAULT_OUTPUT_FILE = "test_detail.xml" -class GTestXMLTestCase(unittest.TestCase): +class GTestXMLTestCase(gtest_test_utils.TestCase): """ Base class for tests of Google Test's XML output functionality. """ -- cgit v1.2.3 From f8b268ee86ca74bba3276352f1e7de53d1336c3e Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 30 Sep 2009 20:23:50 +0000 Subject: Makes gtest compile cleanly with MSVC's /W4 (by Zhanyong Wan). Renames EventListenrs to TestEventListeners (by Zhanyong Wan). Fixes invalid characters in XML report (by Vlad Losev). Refacotrs SConscript (by Vlad Losev). --- test/gtest_xml_test_utils.py | 48 +++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 18 deletions(-) (limited to 'test/gtest_xml_test_utils.py') diff --git a/test/gtest_xml_test_utils.py b/test/gtest_xml_test_utils.py index 1811c408..c83c3b7e 100755 --- a/test/gtest_xml_test_utils.py +++ b/test/gtest_xml_test_utils.py @@ -77,19 +77,29 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): expected_attributes = expected_node.attributes actual_attributes = actual_node .attributes - self.assertEquals(expected_attributes.length, actual_attributes.length) + self.assertEquals( + expected_attributes.length, actual_attributes.length, + "attribute numbers differ in element " + actual_node.tagName) for i in range(expected_attributes.length): expected_attr = expected_attributes.item(i) actual_attr = actual_attributes.get(expected_attr.name) - self.assert_(actual_attr is not None) - self.assertEquals(expected_attr.value, actual_attr.value) + self.assert_( + actual_attr is not None, + "expected attribute %s not found in element %s" % + (expected_attr.name, actual_node.tagName)) + self.assertEquals(expected_attr.value, actual_attr.value, + " values of attribute %s in element %s differ" % + (expected_attr.name, actual_node.tagName)) expected_children = self._GetChildren(expected_node) actual_children = self._GetChildren(actual_node) - self.assertEquals(len(expected_children), len(actual_children)) + self.assertEquals( + len(expected_children), len(actual_children), + "number of child elements differ in element " + actual_node.tagName) for child_id, child in expected_children.iteritems(): self.assert_(child_id in actual_children, - '<%s> is not in <%s>' % (child_id, actual_children)) + '<%s> is not in <%s> (in element %s)' % + (child_id, actual_children, actual_node.tagName)) self.AssertEquivalentNodes(child, actual_children[child_id]) identifying_attribute = { @@ -103,14 +113,13 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): """ Fetches all of the child nodes of element, a DOM Element object. Returns them as the values of a dictionary keyed by the IDs of the - children. For , and elements, - the ID is the value of their "name" attribute; for - elements, it is the value of the "message" attribute; for CDATA - section node, it is "detail". An exception is raised if any - element other than the above four is encountered, if two child - elements with the same identifying attributes are encountered, or - if any other type of node is encountered, other than Text nodes - containing only whitespace. + children. For , and elements, the ID + is the value of their "name" attribute; for elements, it is + the value of the "message" attribute; CDATA sections and non-whitespace + text nodes are concatenated into a single CDATA section with ID + "detail". An exception is raised if any element other than the above + four is encountered, if two child elements with the same identifying + attributes are encountered, or if any other type of node is encountered. """ children = {} @@ -121,11 +130,14 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): childID = child.getAttribute(self.identifying_attribute[child.tagName]) self.assert_(childID not in children) children[childID] = child - elif child.nodeType == Node.TEXT_NODE: - self.assert_(child.nodeValue.isspace()) - elif child.nodeType == Node.CDATA_SECTION_NODE: - self.assert_("detail" not in children) - children["detail"] = child + elif child.nodeType in [Node.TEXT_NODE, Node.CDATA_SECTION_NODE]: + if "detail" not in children: + if (child.nodeType == Node.CDATA_SECTION_NODE or + not child.nodeValue.isspace()): + children["detail"] = child.ownerDocument.createCDATASection( + child.nodeValue) + else: + children["detail"].nodeValue += child.nodeValue else: self.fail("Encountered unexpected node type %d" % child.nodeType) return children -- cgit v1.2.3 From 9bcf4d0a654b27732e2fa901fe98c09aba71773a Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 2 Feb 2011 00:49:33 +0000 Subject: Adds type_param and value_param as attributes to the XML report; also removes the comment() and test_case_comment() fields of TestInfo. Proposed and initally implemented by Joey Oravec. Re-implemented by Vlad Losev. --- test/gtest_xml_test_utils.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'test/gtest_xml_test_utils.py') diff --git a/test/gtest_xml_test_utils.py b/test/gtest_xml_test_utils.py index c83c3b7e..0f55c164 100755 --- a/test/gtest_xml_test_utils.py +++ b/test/gtest_xml_test_utils.py @@ -58,8 +58,9 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): * It has the same tag name as expected_node. * It has the same set of attributes as expected_node, each with the same value as the corresponding attribute of expected_node. - An exception is any attribute named "time", which needs only be - convertible to a floating-point number. + Exceptions are any attribute named "time", which needs only be + convertible to a floating-point number and any attribute named + "type_param" which only has to be non-empty. * It has an equivalent set of child nodes (including elements and CDATA sections) as expected_node. Note that we ignore the order of the children as they are not guaranteed to be in any @@ -150,6 +151,9 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): * The "time" attribute of , and elements is replaced with a single asterisk, if it contains only digit characters. + * The "type_param" attribute of elements is replaced with a + single asterisk (if it sn non-empty) as it is the type name returned + by the compiler and is platform dependent. * The line number reported in the first line of the "message" attribute of elements is replaced with a single asterisk. * The directory names in file paths are removed. @@ -159,6 +163,9 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): if element.tagName in ("testsuites", "testsuite", "testcase"): time = element.getAttributeNode("time") time.value = re.sub(r"^\d+(\.\d+)?$", "*", time.value) + type_param = element.getAttributeNode("type_param") + if type_param and type_param.value: + type_param.value = "*" elif element.tagName == "failure": for child in element.childNodes: if child.nodeType == Node.CDATA_SECTION_NODE: -- cgit v1.2.3 From 431a8be1662a3bc9601240914f412b0436d94703 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Wed, 5 Oct 2011 05:52:34 +0000 Subject: Implements the timestamp attribute for the testsuites element in the output XML (external contribution by Dirk Meister). --- test/gtest_xml_test_utils.py | 54 ++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 24 deletions(-) (limited to 'test/gtest_xml_test_utils.py') diff --git a/test/gtest_xml_test_utils.py b/test/gtest_xml_test_utils.py index 0f55c164..f94d634b 100755 --- a/test/gtest_xml_test_utils.py +++ b/test/gtest_xml_test_utils.py @@ -39,8 +39,8 @@ from xml.dom import minidom, Node import gtest_test_utils -GTEST_OUTPUT_FLAG = "--gtest_output" -GTEST_DEFAULT_OUTPUT_FILE = "test_detail.xml" +GTEST_OUTPUT_FLAG = '--gtest_output' +GTEST_DEFAULT_OUTPUT_FILE = 'test_detail.xml' class GTestXMLTestCase(gtest_test_utils.TestCase): """ @@ -80,23 +80,23 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): actual_attributes = actual_node .attributes self.assertEquals( expected_attributes.length, actual_attributes.length, - "attribute numbers differ in element " + actual_node.tagName) + 'attribute numbers differ in element ' + actual_node.tagName) for i in range(expected_attributes.length): expected_attr = expected_attributes.item(i) actual_attr = actual_attributes.get(expected_attr.name) self.assert_( actual_attr is not None, - "expected attribute %s not found in element %s" % + 'expected attribute %s not found in element %s' % (expected_attr.name, actual_node.tagName)) self.assertEquals(expected_attr.value, actual_attr.value, - " values of attribute %s in element %s differ" % + ' values of attribute %s in element %s differ' % (expected_attr.name, actual_node.tagName)) expected_children = self._GetChildren(expected_node) actual_children = self._GetChildren(actual_node) self.assertEquals( len(expected_children), len(actual_children), - "number of child elements differ in element " + actual_node.tagName) + 'number of child elements differ in element ' + actual_node.tagName) for child_id, child in expected_children.iteritems(): self.assert_(child_id in actual_children, '<%s> is not in <%s> (in element %s)' % @@ -104,10 +104,10 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): self.AssertEquivalentNodes(child, actual_children[child_id]) identifying_attribute = { - "testsuites": "name", - "testsuite": "name", - "testcase": "name", - "failure": "message", + 'testsuites': 'name', + 'testsuite': 'name', + 'testcase': 'name', + 'failure': 'message', } def _GetChildren(self, element): @@ -127,20 +127,20 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): for child in element.childNodes: if child.nodeType == Node.ELEMENT_NODE: self.assert_(child.tagName in self.identifying_attribute, - "Encountered unknown element <%s>" % child.tagName) + 'Encountered unknown element <%s>' % child.tagName) childID = child.getAttribute(self.identifying_attribute[child.tagName]) self.assert_(childID not in children) children[childID] = child elif child.nodeType in [Node.TEXT_NODE, Node.CDATA_SECTION_NODE]: - if "detail" not in children: + if 'detail' not in children: if (child.nodeType == Node.CDATA_SECTION_NODE or not child.nodeValue.isspace()): - children["detail"] = child.ownerDocument.createCDATASection( + children['detail'] = child.ownerDocument.createCDATASection( child.nodeValue) else: - children["detail"].nodeValue += child.nodeValue + children['detail'].nodeValue += child.nodeValue else: - self.fail("Encountered unexpected node type %d" % child.nodeType) + self.fail('Encountered unexpected node type %d' % child.nodeType) return children def NormalizeXml(self, element): @@ -151,6 +151,8 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): * The "time" attribute of , and elements is replaced with a single asterisk, if it contains only digit characters. + * The "timestamp" attribute of elements is replaced with a + single asterisk, if it contains a valid ISO8601 datetime value. * The "type_param" attribute of elements is replaced with a single asterisk (if it sn non-empty) as it is the type name returned by the compiler and is platform dependent. @@ -160,20 +162,24 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): * The stack traces are removed. """ - if element.tagName in ("testsuites", "testsuite", "testcase"): - time = element.getAttributeNode("time") - time.value = re.sub(r"^\d+(\.\d+)?$", "*", time.value) - type_param = element.getAttributeNode("type_param") + if element.tagName == 'testsuites': + timestamp = element.getAttributeNode('timestamp') + timestamp.value = re.sub(r'^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d$', + '*', timestamp.value) + if element.tagName in ('testsuites', 'testsuite', 'testcase'): + time = element.getAttributeNode('time') + time.value = re.sub(r'^\d+(\.\d+)?$', '*', time.value) + type_param = element.getAttributeNode('type_param') if type_param and type_param.value: - type_param.value = "*" - elif element.tagName == "failure": + type_param.value = '*' + elif element.tagName == 'failure': for child in element.childNodes: if child.nodeType == Node.CDATA_SECTION_NODE: # Removes the source line number. - cdata = re.sub(r"^.*[/\\](.*:)\d+\n", "\\1*\n", child.nodeValue) + cdata = re.sub(r'^.*[/\\](.*:)\d+\n', '\\1*\n', child.nodeValue) # Removes the actual stack trace. - child.nodeValue = re.sub(r"\nStack trace:\n(.|\n)*", - "", cdata) + child.nodeValue = re.sub(r'\nStack trace:\n(.|\n)*', + '', cdata) for child in element.childNodes: if child.nodeType == Node.ELEMENT_NODE: self.NormalizeXml(child) -- cgit v1.2.3 From 4d6f296e8e5d3f839ef4868390bbec27cb12e068 Mon Sep 17 00:00:00 2001 From: jgm Date: Tue, 17 Jan 2012 15:11:32 +0000 Subject: Adds file and line information to the "message", which is used as the summary of a failure. --- test/gtest_xml_test_utils.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'test/gtest_xml_test_utils.py') diff --git a/test/gtest_xml_test_utils.py b/test/gtest_xml_test_utils.py index f94d634b..0e5a1089 100755 --- a/test/gtest_xml_test_utils.py +++ b/test/gtest_xml_test_utils.py @@ -156,8 +156,9 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): * The "type_param" attribute of elements is replaced with a single asterisk (if it sn non-empty) as it is the type name returned by the compiler and is platform dependent. - * The line number reported in the first line of the "message" - attribute of elements is replaced with a single asterisk. + * The line info reported in the first line of the "message" + attribute and CDATA section of elements is replaced with the + file's basename and a single asterisk for the line number. * The directory names in file paths are removed. * The stack traces are removed. """ @@ -173,10 +174,14 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): if type_param and type_param.value: type_param.value = '*' elif element.tagName == 'failure': + source_line_pat = r'^.*[/\\](.*:)\d+\n' + # Replaces the source line information with a normalized form. + message = element.getAttributeNode('message') + message.value = re.sub(source_line_pat, '\\1*\n', message.value) for child in element.childNodes: if child.nodeType == Node.CDATA_SECTION_NODE: - # Removes the source line number. - cdata = re.sub(r'^.*[/\\](.*:)\d+\n', '\\1*\n', child.nodeValue) + # Replaces the source line information with a normalized form. + cdata = re.sub(source_line_pat, '\\1*\n', child.nodeValue) # Removes the actual stack trace. child.nodeValue = re.sub(r'\nStack trace:\n(.|\n)*', '', cdata) -- cgit v1.2.3 From f5fa71f728ce77c5d5c1a940a9bd8bb1d64c9f78 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Fri, 5 Apr 2013 20:50:46 +0000 Subject: Implements support for calling Test::RecordProperty() outside of a test. --- test/gtest_xml_test_utils.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'test/gtest_xml_test_utils.py') diff --git a/test/gtest_xml_test_utils.py b/test/gtest_xml_test_utils.py index 0e5a1089..35458f88 100755 --- a/test/gtest_xml_test_utils.py +++ b/test/gtest_xml_test_utils.py @@ -80,7 +80,9 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): actual_attributes = actual_node .attributes self.assertEquals( expected_attributes.length, actual_attributes.length, - 'attribute numbers differ in element ' + actual_node.tagName) + 'attribute numbers differ in element %s:\nExpected: %r\nActual: %r' % ( + actual_node.tagName, expected_attributes.keys(), + actual_attributes.keys())) for i in range(expected_attributes.length): expected_attr = expected_attributes.item(i) actual_attr = actual_attributes.get(expected_attr.name) -- cgit v1.2.3 From c506784b08473f3ba8f37d588fd08d8d3f948245 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Thu, 25 Apr 2013 17:58:52 +0000 Subject: When --gtest_filter is specified, XML report now doesn't contain information about tests that are filtered out (issue 141). --- test/gtest_xml_test_utils.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'test/gtest_xml_test_utils.py') diff --git a/test/gtest_xml_test_utils.py b/test/gtest_xml_test_utils.py index 35458f88..3d0c3b2c 100755 --- a/test/gtest_xml_test_utils.py +++ b/test/gtest_xml_test_utils.py @@ -90,9 +90,11 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): actual_attr is not None, 'expected attribute %s not found in element %s' % (expected_attr.name, actual_node.tagName)) - self.assertEquals(expected_attr.value, actual_attr.value, - ' values of attribute %s in element %s differ' % - (expected_attr.name, actual_node.tagName)) + self.assertEquals( + expected_attr.value, actual_attr.value, + ' values of attribute %s in element %s differ: %s vs %s' % + (expected_attr.name, actual_node.tagName, + expected_attr.value, actual_attr.value)) expected_children = self._GetChildren(expected_node) actual_children = self._GetChildren(actual_node) -- cgit v1.2.3