Skip to content

Commit 3e585cf

Browse files
committed
Merge pull request kyrus#9 from Ketouem/master
Handling of <skipped> xml entity that can be parsed by Jenkins
2 parents af1729f + 32c4ac4 commit 3e585cf

File tree

2 files changed

+59
-4
lines changed

2 files changed

+59
-4
lines changed

junit_xml/__init__.py

+33-4
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@
2424
the output of the testcase
2525
</error>
2626
</testcase>
27+
<testcase classname="package.directory" name="003-skipped-test" time="0">
28+
<skipped message="SKIPPED Test" type="skipped">
29+
the output of the testcase
30+
</skipped>
31+
</testcase>
2732
<testcase classname="testdb.directory" name="003-passed-test" time="10">
2833
<system-out>
2934
I am system output
@@ -63,6 +68,7 @@ def build_xml_doc(self):
6368
test_suite_attributes['name'] = str(self.name)
6469
test_suite_attributes['failures'] = str(len([c for c in self.test_cases if c.is_failure()]))
6570
test_suite_attributes['errors'] = str(len([c for c in self.test_cases if c.is_error()]))
71+
test_suite_attributes['skipped'] = str(len([c for c in self.test_cases if c.is_skipped()]))
6672
test_suite_attributes['time'] = str(sum(c.elapsed_sec for c in self.test_cases if c.elapsed_sec))
6773
test_suite_attributes['tests'] = str(len(self.test_cases))
6874

@@ -115,6 +121,16 @@ def build_xml_doc(self):
115121
error_element.text = case.error_output
116122
test_case_element.append(error_element)
117123

124+
# skippeds
125+
if case.is_skipped():
126+
attrs = {'type': 'skipped'}
127+
if case.skipped_message:
128+
attrs['message'] = case.skipped_message
129+
skipped_element = ET.Element("skipped", attrs)
130+
if case.error_output:
131+
skipped_element.text = case.skipped_output
132+
test_case_element.append(skipped_element)
133+
118134
# test stdout
119135
if case.stdout:
120136
stdout_element = ET.Element("system-out")
@@ -130,7 +146,7 @@ def build_xml_doc(self):
130146
return xml_element
131147

132148
@staticmethod
133-
def to_xml_string(test_suites, prettyprint=True):
149+
def to_xml_string(test_suites, prettyprint=True, encoding=None):
134150
"""Returns the string representation of the JUnit XML document"""
135151
try:
136152
iter(test_suites)
@@ -141,17 +157,17 @@ def to_xml_string(test_suites, prettyprint=True):
141157
for ts in test_suites:
142158
xml_element.append(ts.build_xml_doc())
143159

144-
xml_string = ET.tostring(xml_element)
160+
xml_string = ET.tostring(xml_element, encoding=encoding)
145161
xml_string = TestSuite._clean_illegal_xml_chars(xml_string)
146162

147163
if prettyprint:
148164
xml_string = xml.dom.minidom.parseString(xml_string).toprettyxml()
149165
return xml_string
150166

151167
@staticmethod
152-
def to_file(file_descriptor, test_suites, prettyprint=True):
168+
def to_file(file_descriptor, test_suites, prettyprint=True, encoding=None):
153169
"""Writes the JUnit XML document to file"""
154-
file_descriptor.write(TestSuite.to_xml_string(test_suites, prettyprint))
170+
file_descriptor.write(TestSuite.to_xml_string(test_suites, prettyprint, encoding))
155171

156172
@staticmethod
157173
def _clean_illegal_xml_chars(string_to_clean):
@@ -187,6 +203,8 @@ def __init__(self, name, classname=None, elapsed_sec=None, stdout=None, stderr=N
187203
self.error_output = None
188204
self.failure_message = None
189205
self.failure_output = None
206+
self.skipped_message = None
207+
self.skipped_output = None
190208

191209
def add_error_info(self, message=None, output=None):
192210
"""Adds an error message, output, or both to the test case"""
@@ -202,10 +220,21 @@ def add_failure_info(self, message=None, output=None):
202220
if output:
203221
self.failure_output = output
204222

223+
def add_skipped_info(self, message=None, output=None):
224+
"""Adds a skipped message, output, or both to the test case"""
225+
if message:
226+
self.skipped_message = message
227+
if output:
228+
self.skipped_output = output
229+
205230
def is_failure(self):
206231
"""returns true if this test case is a failure"""
207232
return self.failure_output or self.failure_message
208233

209234
def is_error(self):
210235
"""returns true if this test case is an error"""
211236
return self.error_output or self.error_message
237+
238+
def is_skipped(self):
239+
"""returns true if this test case has been skipped"""
240+
return self.skipped_output or self.skipped_message

tests.py

+26
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,25 @@ def test_init_error(self):
156156
verify_test_case(self, tcs[0], {'name': 'Error-Message-and-Output'},
157157
error_message="error message", error_output="I errored!")
158158

159+
def test_init_skipped_message(self):
160+
tc = TestCase('Skipped-Message')
161+
tc.add_skipped_info("skipped message")
162+
(ts, tcs) = serialize_and_read(TestSuite('test', [tc]))[0]
163+
verify_test_case(self, tcs[0], {'name': 'Skipped-Message'}, skipped_message="skipped message")
164+
165+
def test_init_skipped_output(self):
166+
tc = TestCase('Skipped-Output')
167+
tc.add_skipped_info(output="I skipped!")
168+
(ts, tcs) = serialize_and_read(TestSuite('test', [tc]))[0]
169+
verify_test_case(self, tcs[0], {'name': 'Skipped-Output'}, skipped_output="I skipped!")
170+
171+
def test_init_skipped(self):
172+
tc = TestCase('Skipped-Message-and-Output')
173+
tc.add_skipped_info("skipped message", "I skipped!")
174+
(ts, tcs) = serialize_and_read(TestSuite('test', [tc]))[0]
175+
verify_test_case(self, tcs[0], {'name': 'Skipped-Message-and-Output'},
176+
skipped_message="skipped message", skipped_output="I skipped!")
177+
159178
def test_init_legal_unicode_char(self):
160179
tc = TestCase('Failure-Message')
161180
tc.add_failure_info(u"failure message with legal unicode char: [\x22]")
@@ -174,6 +193,7 @@ def test_init_illegal_unicode_char(self):
174193
def verify_test_case(tc, test_case_element, expected_attributes,
175194
error_message=None, error_output=None,
176195
failure_message=None, failure_output=None,
196+
skipped_message=None, skipped_output=None,
177197
stdout=None, stderr=None):
178198
for k, v in expected_attributes.items():
179199
tc.assertEqual(v, test_case_element.attributes[k].value)
@@ -210,5 +230,11 @@ def verify_test_case(tc, test_case_element, expected_attributes,
210230
if failure_output:
211231
tc.assertEqual(failure_output, failures[0].firstChild.nodeValue.strip())
212232

233+
skipped = test_case_element.getElementsByTagName('skipped')
234+
if skipped_message or skipped_output:
235+
tc.assertTrue(len(skipped) > 0)
236+
else:
237+
tc.assertEqual(0, len(skipped))
238+
213239
if __name__ == '__main__':
214240
unittest.main()

0 commit comments

Comments
 (0)