Add failure tag to JUnit report

When generate JUnit report, add <failure/> tag to failed test case.
Criterion and detail from sla is also added as type and message with failure tag.

Closes-Bug: #1470286

Change-Id: I5def62501b419317eef18045e85626db692628b1
This commit is contained in:
Hiroki Aramaki 2015-07-01 10:05:42 +09:00
parent f5f3e4159e
commit 4389a97af9
3 changed files with 26 additions and 14 deletions

View File

@ -532,6 +532,7 @@ class TaskCommands(object):
tasks = isinstance(tasks, list) and tasks or [tasks] tasks = isinstance(tasks, list) and tasks or [tasks]
results = [] results = []
message = []
processed_names = {} processed_names = {}
for task_file_or_uuid in tasks: for task_file_or_uuid in tasks:
if os.path.exists(os.path.expanduser(task_file_or_uuid)): if os.path.exists(os.path.expanduser(task_file_or_uuid)):
@ -585,14 +586,15 @@ class TaskCommands(object):
elif out_format == "junit": elif out_format == "junit":
test_suite = junit.JUnit("Rally test suite") test_suite = junit.JUnit("Rally test suite")
for result in results: for result in results:
if (isinstance(result["sla"], list) and if isinstance(result["sla"], list):
not all([sla["success"] for sla in result["sla"]])): message = ",".join([sla["detail"] for sla in
result["sla"] if not sla["success"]])
if message:
outcome = junit.JUnit.FAILURE outcome = junit.JUnit.FAILURE
else: else:
outcome = junit.JUnit.SUCCESS outcome = junit.JUnit.SUCCESS
test_suite.add_test(result["key"]["name"], test_suite.add_test(result["key"]["name"],
result["full_duration"], result["full_duration"], outcome, message)
outcome=outcome)
with open(output_file, "w+") as f: with open(output_file, "w+") as f:
f.write(test_suite.to_xml()) f.write(test_suite.to_xml())
else: else:

View File

@ -17,9 +17,9 @@ import xml.etree.ElementTree as ET
class JUnit(object): class JUnit(object):
SUCCESS = 0 SUCCESS = "success"
FAILURE = 1 FAILURE = "failure"
ERROR = 2 ERROR = "error"
def __init__(self, test_suite_name): def __init__(self, test_suite_name):
self.test_suite_name = test_suite_name self.test_suite_name = test_suite_name
@ -29,12 +29,14 @@ class JUnit(object):
self.n_errors = 0 self.n_errors = 0
self.total_time = 0.0 self.total_time = 0.0
def add_test(self, test_name, time, outcome=SUCCESS): def add_test(self, test_name, time, outcome=SUCCESS, message=""):
class_name, name = test_name.split(".", 1) class_name, name = test_name.split(".", 1)
self.test_cases.append({ self.test_cases.append({
"classname": class_name, "classname": class_name,
"name": name, "name": name,
"time": str("%.2f" % time), "time": str("%.2f" % time),
"outcome": outcome,
"message": message
}) })
if outcome == JUnit.FAILURE: if outcome == JUnit.FAILURE:
@ -56,5 +58,11 @@ class JUnit(object):
"errors": str(self.n_errors), "errors": str(self.n_errors),
}) })
for test_case in self.test_cases: for test_case in self.test_cases:
xml.append(ET.Element("testcase", test_case)) outcome = test_case.pop("outcome")
message = test_case.pop("message")
if outcome in [JUnit.FAILURE, JUnit.ERROR]:
sub = ET.SubElement(xml, "testcase", test_case)
sub.append(ET.Element(outcome, {"message": message}))
else:
xml.append(ET.Element("testcase", test_case))
return ET.tostring(xml, encoding="utf-8").decode("utf-8") return ET.tostring(xml, encoding="utf-8").decode("utf-8")

View File

@ -20,16 +20,18 @@ from tests.unit import test
class JUnitTestCase(test.TestCase): class JUnitTestCase(test.TestCase):
def test_basic_testsuite(self): def test_basic_testsuite(self):
j = junit.JUnit("test") j = junit.JUnit("test")
j.add_test("Foo.Bar", 3.14) j.add_test("Foo.Bar", 3.14, outcome=junit.JUnit.SUCCESS)
j.add_test("Foo.Baz", 13.37, outcome=junit.JUnit.FAILURE) j.add_test("Foo.Baz", 13.37, outcome=junit.JUnit.FAILURE,
message="fail_message")
j.add_test("Eggs.Spam", 42.00, outcome=junit.JUnit.ERROR) j.add_test("Eggs.Spam", 42.00, outcome=junit.JUnit.ERROR)
expected = """ expected = """
<testsuite errors="1" failures="1" name="test" tests="3" time="58.51"> <testsuite errors="1" failures="1" name="test" tests="3" time="58.51">
<testcase classname="Foo" name="Bar" time="3.14" /> <testcase classname="Foo" name="Bar" time="3.14" />
<testcase classname="Foo" name="Baz" time="13.37" /> <testcase classname="Foo" name="Baz" time="13.37">
<testcase classname="Eggs" name="Spam" time="42.00" /> <failure message="fail_message" /></testcase>
</testsuite>""" <testcase classname="Eggs" name="Spam" time="42.00">
<error message="" /></testcase></testsuite>"""
self.assertEqual(expected.replace("\n", ""), j.to_xml()) self.assertEqual(expected.replace("\n", ""), j.to_xml())
def test_empty_testsuite(self): def test_empty_testsuite(self):