Skip to content

support test case properties #84

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 44 additions & 51 deletions junit_xml/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ def __init__(
url=None,
stdout=None,
stderr=None,
attributes=None,
):
self.name = name
if not test_cases:
Expand All @@ -113,6 +114,15 @@ def __init__(
self.stdout = stdout
self.stderr = stderr
self.properties = properties
self.attributes = attributes

@staticmethod
def _add_properties(properties, element, encoding=None):
if properties:
props_element = ET.SubElement(element, "properties")
for k, v in properties.items():
attrs = {"name": decode(k, encoding), "value": decode(v, encoding)}
ET.SubElement(props_element, "property", attrs)

def build_xml_doc(self, encoding=None):
"""
Expand Down Expand Up @@ -148,15 +158,14 @@ def build_xml_doc(self, encoding=None):
test_suite_attributes["log"] = decode(self.log, encoding)
if self.url:
test_suite_attributes["url"] = decode(self.url, encoding)
if self.attributes:
test_suite_attributes.update(self.attributes)


xml_element = ET.Element("testsuite", test_suite_attributes)

# add any properties
if self.properties:
props_element = ET.SubElement(xml_element, "properties")
for k, v in self.properties.items():
attrs = {"name": decode(k, encoding), "value": decode(v, encoding)}
ET.SubElement(props_element, "property", attrs)
self._add_properties(self.properties, xml_element, encoding)

# add test suite stdout
if self.stdout:
Expand Down Expand Up @@ -193,9 +202,14 @@ def build_xml_doc(self, encoding=None):
test_case_attributes["log"] = decode(case.log, encoding)
if case.url:
test_case_attributes["url"] = decode(case.url, encoding)
if case.attributes:
test_case_attributes.update(case.attributes)

test_case_element = ET.SubElement(xml_element, "testcase", test_case_attributes)

# add test case properties
self._add_properties(case.properties, test_case_element, encoding)

# failures
for failure in case.failures:
if failure["output"] or failure["message"]:
Expand All @@ -222,7 +236,7 @@ def build_xml_doc(self, encoding=None):
error_element.text = decode(error["output"], encoding)
test_case_element.append(error_element)

# skippeds
# skipped
for skipped in case.skipped:
attrs = {"type": "skipped"}
if skipped["message"]:
Expand Down Expand Up @@ -380,6 +394,8 @@ def __init__(
log=None,
url=None,
allow_multiple_subelements=False,
properties=None,
attributes=None,
):
self.name = name
self.assertions = assertions
Expand All @@ -399,61 +415,38 @@ def __init__(
self.errors = []
self.failures = []
self.skipped = []
self.allow_multiple_subalements = allow_multiple_subelements
self.allow_multiple_subelements = allow_multiple_subelements
self.properties = properties
self.attributes = attributes

def add_error_info(self, message=None, output=None, error_type=None):
"""Adds an error message, output, or both to the test case"""
error = {}
error["message"] = message
error["output"] = output
error["type"] = error_type
if self.allow_multiple_subalements:
def _add_info(self, infos, message=None, output=None, type_=None):
info = {"message": message, "output": output}
if type_ is not None:
info["type"] = type_
if self.allow_multiple_subelements:
if message or output:
self.errors.append(error)
elif not len(self.errors):
self.errors.append(error)
infos.append(info)
elif not len(infos):
infos.append(info)
else:
if message:
self.errors[0]["message"] = message
infos[0]["message"] = message
if output:
self.errors[0]["output"] = output
if error_type:
self.errors[0]["type"] = error_type
infos[0]["output"] = output
if type_:
infos[0]["type"] = type_

def add_failure_info(self, message=None, output=None, failure_type=None):
def add_error_info(self, message=None, output=None, error_type=""):
"""Adds an error message, output, or both to the test case"""
self._add_info(self.errors, message, output, error_type)

def add_failure_info(self, message=None, output=None, failure_type=""):
"""Adds a failure message, output, or both to the test case"""
failure = {}
failure["message"] = message
failure["output"] = output
failure["type"] = failure_type
if self.allow_multiple_subalements:
if message or output:
self.failures.append(failure)
elif not len(self.failures):
self.failures.append(failure)
else:
if message:
self.failures[0]["message"] = message
if output:
self.failures[0]["output"] = output
if failure_type:
self.failures[0]["type"] = failure_type
self._add_info(self.failures, message, output, failure_type)

def add_skipped_info(self, message=None, output=None):
"""Adds a skipped message, output, or both to the test case"""
skipped = {}
skipped["message"] = message
skipped["output"] = output
if self.allow_multiple_subalements:
if message or output:
self.skipped.append(skipped)
elif not len(self.skipped):
self.skipped.append(skipped)
else:
if message:
self.skipped[0]["message"] = message
if output:
self.skipped[0]["output"] = output
self._add_info(self.skipped, message, output)

def is_failure(self):
"""returns true if this test case is a failure"""
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def read(fname):
packages=find_packages(exclude=["tests"]),
description="Creates JUnit XML test result documents that can be read by tools such as Jenkins",
long_description=read("README.rst"),
version="1.9",
version="1.10",
classifiers=[
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
Expand Down
17 changes: 14 additions & 3 deletions tests/test_test_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@

from six import u

from .asserts import verify_test_case
from junit_xml import TestCase as Case
from junit_xml import TestSuite as Suite
from junit_xml import decode
from .asserts import verify_test_case
from .serializer import serialize_and_read


Expand All @@ -15,9 +15,14 @@ def test_init():
verify_test_case(tcs[0], {"name": "Test1"})


def test_init_classname():
ts, tcs = serialize_and_read(Suite("test", [Case(name="Test1", classname="some.class.name")]))[0]
def test_init_classname_properties():
properties = {decode("foö", "utf-8"): decode("bär", "utf-8")}
ts, tcs = serialize_and_read(
Suite("test", [Case(name="Test1", classname="some.class.name", properties=properties)]))[0]
verify_test_case(tcs[0], {"name": "Test1", "classname": "some.class.name"})
a = tcs[0].firstChild.firstChild.attributes
assert a["name"].value == decode("foö", "utf-8")
assert a["value"].value == decode("bär", "utf-8")


def test_init_classname_time():
Expand Down Expand Up @@ -322,3 +327,9 @@ def test_multiple_skipped():
{"message": "Second skipped", "output": "Second skipped message"},
],
)


def test_init_attributes():
tc = Case("Attributes", attributes={"xml:id": "1"})
ts, tcs = serialize_and_read(Suite("test", [tc]))[0]
verify_test_case(tcs[0], {"name": "Attributes", "xml:id": "1"})
6 changes: 6 additions & 0 deletions tests/test_test_suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,12 @@ def test_attribute_disable():
assert suites[0][0].attributes["disabled"].value == "1"


def test_init_attributes():
tss = [Suite("suite1", attributes={"xml:id": "1"})]
suites = serialize_and_read(tss)
assert suites[0][0].attributes["xml:id"].value == "1"


def test_stderr():
suites = serialize_and_read(Suite(name="test", stderr="I am stderr!", test_cases=[Case(name="Test1")]))[0]
assert suites[0].getElementsByTagName("system-err")[0].firstChild.data == "I am stderr!"
Expand Down