#3684: bug fix in time accumulation and addition of unit test from kruset

This commit is contained in:
Ken Conley 2011-09-22 18:33:18 +00:00
parent 9f56a76361
commit c11b088006
3 changed files with 198 additions and 6 deletions

View File

@ -37,6 +37,8 @@
Library for reading and manipulating Ant JUnit XML result files.
"""
from __future__ import print_function
import os
import sys
import cStringIO
@ -180,6 +182,7 @@ class Result(object):
self.num_errors += r.num_errors
self.num_failures += r.num_failures
self.num_tests += r.num_tests
self.time += r.time
self.test_case_results.extend(r.test_case_results)
if r.system_out:
self.system_out += '\n'+r.system_out
@ -240,7 +243,7 @@ def _load_suite_results(test_suite_name, test_suite, result):
elif not classname.startswith(result.name):
classname = "%s.%s"%(result.name,classname)
time = node.getAttribute('time') or 0.0
time = float(node.getAttribute('time')) or 0.0
tc_result = TestCaseResult("%s/%s"%(test_suite_name,name))
tc_result.classname = classname
tc_result.time = time
@ -310,14 +313,14 @@ def read(test_file, test_name):
try:
xml_str = _read_file_safe_xml(test_file)
if not xml_str.strip():
print "WARN: test result file is empty [%s]"%(test_file)
print("WARN: test result file is empty [%s]"%(test_file))
return Result(test_name, 0, 0, 0)
test_suites = parseString(xml_str).getElementsByTagName('testsuite')
except Exception as e:
print "WARN: cannot read test result file [%s]: %s"%(test_file, str(e))
print("WARN: cannot read test result file [%s]: %s"%(test_file, str(e)))
return Result(test_name, 0, 0, 0)
if not test_suites:
print "WARN: test result file [%s] contains no results"%(test_file)
print("WARN: test result file [%s] contains no results"%(test_file))
return Result(test_name, 0, 0, 0)
results = Result(test_name, 0, 0, 0)
@ -328,7 +331,7 @@ def read(test_file, test_name):
err, fail, tests = [string.atoi(val) for val in vals]
result = Result(test_name, err, fail, tests)
result.time = test_suite.getAttribute('time') or 0.0
result.time = float(test_suite.getAttribute('time')) or 0.0
# Create a prefix based on the test result filename. The idea is to
# disambiguate the case when tests of the same name are provided in
@ -447,5 +450,5 @@ def print_summary(junit_results, runner_name='ROSUNIT'):
else:
buff.write(" * FAILURES: 0\n")
print buff.getvalue()
print(buff.getvalue())

View File

View File

@ -0,0 +1,189 @@
#!/usr/bin/env python
# Software License Agreement (BSD License)
#
# Copyright (c) 2008, Willow Garage, 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 Willow Garage, 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.
#
# Revision $Id: $
import os
import io
import sys
import unittest
import tempfile
import shutil
junitxml = None
## Basic test of xmlresult functionality of reading gtest xml files and
## summarizing their results into a new file.
class MockResult():
def __init__(self, directory, filename, suites = [], noSuitesRoot = False):
self.filename = os.path.join(directory, filename)
self.suites = suites
# whether to suppress <testsuites> root node
self.noSuitesRoot = noSuitesRoot
class MockSuite():
def __init__(self, cases, name, tests = 0, errors = 0, fail = 0, time = 1):
self.cases = cases
self.tests = tests
self.time = time
self.fail = fail
self.errors = errors
self.name = name
class MockCase():
def __init__(self, name, errorList = [], classname="", time = 1):
self.classname = classname
self.name = name
self.time = time
self.errorList = errorList
class MockErrorType(Exception):
def __init__(self, value, etype = ''):
self.value = value
self.__name__ = value
self.type = etype
def _writeMockResultFile(result):
"writes a test result as a gtest compatible test runner would do"
with open(result.filename, 'w') as f:
f.write(u"""<?xml version="1.0" encoding="UTF-8"?>""")
if len(result.suites) > 1 or result.noSuitesRoot == False:
f.write(u"""<testsuites>\n""")
for suite in result.suites:
f.write('<testsuite tests="'+str(suite.tests)+'" failures="'+str(suite.fail)+'" time="'+str(suite.time)+'" errors="'+str(suite.errors)+'" name="'+suite.name+'">\n')
for case in suite.cases:
f.write('<testcase name="'+case.name+'" status="run" time="'+str(case.time)+'" classname="'+case.classname+'">\n')
for error in case.errorList:
f.write('<failure message="'+error.value+'" type="'+error.value+'"/>\n')
f.write('</testcase>\n')
f.write('</testsuite>\n')
if len(result.suites) > 1 or result.noSuitesRoot == False:
f.write(u"""</testsuites>\n""")
class XmlResultTestRead(unittest.TestCase):
def setUp(self):
# lazy-import to get coverage
global junitxml
if junitxml is None:
import rosunit.junitxml
junitxml = rosunit.junitxml
self.directory = tempfile.mkdtemp()
# setting up mock results as dict so results can be checked individually
self.mockresults={
"empty": MockResult(self.directory, "empty.xml", []),
"emptysuite": MockResult(self.directory, "emptysuite.xml", [MockSuite([], "emptySuite", 0, 0, 0, 0)]),
"succ1": MockResult(self.directory, "succ1.xml", [MockSuite([MockCase("succCase")],"succ1suite", 1, 0, 0, 1)]),
"err1": MockResult(self.directory, "err1.xml", [MockSuite([MockCase("errCase")],"err1suite", 1, 1, 0, 1)]),
"fail1": MockResult(self.directory, "fail1.xml", [MockSuite([MockCase("failCase")],"fail1suite", 1, 0, 1, 1)]),
"noroot": MockResult(self.directory, "succ1.xml", [MockSuite([MockCase("succCase")],"succ1suite", 1, 0, 0, 1)], noSuitesRoot = True),
"multicase": MockResult(self.directory,
"multicase.xml",
[MockSuite([MockCase("succCase"),
MockCase("errCase"),
MockCase("failCase")],
"succ1suite", 3, 1, 1, time = 3)]),
"multisuite": MockResult(self.directory,
"multisuite.xml",
[MockSuite([MockCase("succCase")],"succ1suite", 1, 0, 0, 1),
MockSuite([MockCase("errCase")],"err1suite", 1, 1, 0, 1),
MockSuite([MockCase("failCase")],"fail1suite", 1, 0, 1, 1)])
}
for name, result in self.mockresults.items():
_writeMockResultFile(result)
def tearDown(self):
shutil.rmtree(self.directory)
#pass
def testReadNoSuites(self):
result = junitxml.read(self.mockresults["empty"].filename, "fooname")
self.assert_(result is not None)
self.assertEquals(0.0, result.time)
self.assertEquals(0, result.num_tests)
self.assertEquals(0, result.num_errors)
self.assertEquals(0, result.num_failures)
def testReadEmptySuite(self):
result = junitxml.read(self.mockresults["emptysuite"].filename, "fooname")
self.assert_(result is not None)
self.assertEquals(0.0, result.time)
self.assertEquals(0, result.num_tests)
self.assertEquals(0, result.num_errors)
self.assertEquals(0, result.num_failures)
def testReadSuccess(self):
result = junitxml.read(self.mockresults["succ1"].filename, "fooname")
self.assert_(result is not None)
self.assertEquals(1.0, result.time)
self.assertEquals(1, result.num_tests)
self.assertEquals(0, result.num_errors)
self.assertEquals(0, result.num_failures)
def testReadError(self):
result = junitxml.read(self.mockresults["err1"].filename, "fooname")
self.assert_(result is not None)
self.assertEquals(1.0, result.time)
self.assertEquals(1, result.num_tests)
self.assertEquals(1, result.num_errors)
self.assertEquals(0, result.num_failures)
def testReadFail(self):
result = junitxml.read(self.mockresults["fail1"].filename, "fooname")
self.assert_(result is not None)
self.assertEquals(1.0, result.time)
self.assertEquals(1, result.num_tests)
self.assertEquals(0, result.num_errors)
self.assertEquals(1, result.num_failures)
def testReadMulticase(self):
result = junitxml.read(self.mockresults["multicase"].filename, "fooname")
self.assert_(result is not None)
self.assertEquals(3.0, result.time)
self.assertEquals(3, result.num_tests)
self.assertEquals(1, result.num_errors)
self.assertEquals(1, result.num_failures)
def testReadMultisuite(self):
result = junitxml.read(self.mockresults["multisuite"].filename, "fooname")
self.assert_(result is not None)
self.assertEquals(3.0, result.time)
self.assertEquals(3, result.num_tests)
self.assertEquals(1, result.num_errors)
self.assertEquals(1, result.num_failures)