Skip to content

Commit 803a51f

Browse files
committed
add test coverage and fix failures
1 parent 40f01ad commit 803a51f

File tree

3 files changed

+143
-127
lines changed

3 files changed

+143
-127
lines changed

python_testspace_xml/testspace_xml.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ def _write_suite(self, parent_node, test_suite):
279279
suite_elem.setAttribute('start_time', str(test_suite.start_time))
280280
parent_node.appendChild(suite_elem)
281281
if test_suite.duration > 0:
282-
suite_elem.setAttribute('duration', test_suite.duration)
282+
suite_elem.setAttribute('duration', str(test_suite.duration))
283283

284284
for a in test_suite.annotations:
285285
a.write_xml(suite_elem, self.dom)

tests/test_testspace_report.py

Lines changed: 0 additions & 126 deletions
This file was deleted.

tests/test_testspace_report_xsd.py

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
import os
2+
from lxml import etree, objectify
3+
from lxml.etree import XMLSyntaxError
4+
5+
from python_testspace_xml import testspace_xml
6+
7+
8+
class TestTestspaceReportXsd:
9+
annotation_tuple = [
10+
('zannotation warning example', 'warn', 'to confirm order of annotations'),
11+
('annotation info example', 'info', 'description of annotation'),
12+
('aannotation error example', 'error', 'to confirm order of annotations')]
13+
14+
string_buffer = 'Text content to be displayed in Testspace\n' \
15+
'Additional line of content'
16+
17+
duration = 1055.93
18+
19+
test_annotation = testspace_xml.Annotation('annotation with comment')
20+
test_annotation.add_comment("comment", "annotation comment")
21+
22+
@classmethod
23+
def setup_class(cls):
24+
testspace_report = testspace_xml.TestspaceReport()
25+
26+
example_suite = testspace_report.get_or_add_test_suite('Example Suite')
27+
example_suite.add_link_annotation(path='https://help.testspace.com')
28+
example_suite.add_string_buffer_annotation(
29+
'Suite string annotation as file', string_buffer=cls.string_buffer)
30+
example_suite.add_text_annotation(
31+
'Suite Text Annotation', description='This is a string annotation only')
32+
example_suite.add_file_annotation('tests/report_v1.xsd', file_path='tests/report_v1.xsd')
33+
example_suite.add_custom_metric('suite stats', '0, 3, 4')
34+
example_suite.add_annotation(cls.test_annotation)
35+
example_suite.set_duration_ms(cls.duration)
36+
37+
test_case = testspace_xml.TestCase('passing case 1', 'passed')
38+
for annotation in cls.annotation_tuple:
39+
test_case.add_text_annotation(
40+
annotation[0], level=annotation[1], description=annotation[2])
41+
example_suite.add_test_case(test_case)
42+
43+
test_case = testspace_xml.TestCase('passing case 2', 'passed')
44+
test_case.add_file_annotation('tests/report_v1.xsd', file_path='tests/report_v1.xsd')
45+
test_case.add_file_annotation('report_v1.xsd', file_path='/report_v1.xsd')
46+
test_case.add_string_buffer_annotation(
47+
'Case string annotation as file', string_buffer=cls.string_buffer)
48+
test_case.add_link_annotation(path=r'\\machine/public')
49+
test_case.add_info_annotation(cls.annotation_tuple[0][2])
50+
test_case.add_error_annotation(cls.annotation_tuple[1][2])
51+
test_case.add_warning_annotation(cls.annotation_tuple[2][2])
52+
test_case.set_duration_ms(cls.duration)
53+
example_suite.add_test_case(test_case)
54+
55+
test_case = testspace_xml.TestCase('failing case 1')
56+
test_case.fail('failing testcase') # adds annotation to testcase
57+
test_case.add_custom_metric('suite stats', '0, 3, 4')
58+
test_case.add_annotation(cls.test_annotation)
59+
example_suite.add_test_case(test_case)
60+
61+
test_case = testspace_xml.TestCase('not_applicable 1')
62+
test_case.set_status('not_applicable')
63+
example_suite.add_test_case(test_case)
64+
65+
testspace_report.write_xml('testspace.xml', to_pretty=True)
66+
67+
xml_file = open('testspace.xml', 'r')
68+
testspace_xml_string = xml_file.read()
69+
xml_file.close()
70+
71+
cls.testspace_xml_root = etree.fromstring(testspace_xml_string)
72+
73+
@classmethod
74+
def teardown_class(cls):
75+
""" teardown any state that was previously setup with a call to
76+
setup_class.
77+
"""
78+
os.remove('testspace.xml')
79+
80+
def test_number_testsuites(self):
81+
test_cases = self.testspace_xml_root.xpath("//test_suite")
82+
assert len(test_cases) is 1
83+
84+
def test_number_testsuite_annotations(self):
85+
test_cases = self.testspace_xml_root.xpath("//test_suite/annotation")
86+
assert len(test_cases) is 5
87+
88+
def test_testsuite_duration(self):
89+
suite_element = self.testspace_xml_root.xpath("//test_suite[@duration]")
90+
assert float(suite_element[0].attrib['duration']) == self.duration
91+
92+
def test_number_testcases(self):
93+
test_cases = self.testspace_xml_root.xpath("//test_suite/test_case")
94+
assert len(test_cases) is 4
95+
96+
def test_number_passed_testcases(self):
97+
test_cases = self.testspace_xml_root.xpath("//test_suite/test_case[@status='passed']")
98+
assert len(test_cases) is 2
99+
100+
def test_number_failed_testcases(self):
101+
test_cases = self.testspace_xml_root.xpath("//test_suite/test_case[@status='failed']")
102+
assert len(test_cases) is 1
103+
104+
def test_number_not_applicable_testcases(self):
105+
test_cases = self.testspace_xml_root.xpath(
106+
"//test_suite/test_case[@status='not_applicable']")
107+
assert len(test_cases) is 1
108+
109+
def test_number_testcase_annotations(self):
110+
test_cases = self.testspace_xml_root.xpath("//test_suite/test_case/annotation")
111+
assert len(test_cases) is 12
112+
113+
def test_number_testcase_file_annotations(self):
114+
test_cases = self.testspace_xml_root.xpath("//test_suite/test_case/annotation[@file]")
115+
assert len(test_cases) is 2
116+
117+
def test_number_testcase_annotation_comments(self):
118+
test_cases = self.testspace_xml_root.xpath("//test_suite/test_case/annotation/comment")
119+
assert len(test_cases) is 1
120+
121+
def test_annotation_order(self):
122+
annotations = self.testspace_xml_root.xpath(
123+
"//test_suite/test_case[@name='passing case 1']/annotation")
124+
for idx, annotation in enumerate(annotations):
125+
assert annotation.get('name') == self.annotation_tuple[idx][0]
126+
127+
def test_testcase_duration(self):
128+
suite_element = self.testspace_xml_root.xpath("//test_suite/test_case[@name='passing case 2']")
129+
assert float(suite_element[0].attrib['duration']) == self.duration
130+
131+
def test_validate_xsd(self):
132+
assert xml_validator(etree.tostring(self.testspace_xml_root), 'tests/report_v1.xsd')
133+
134+
135+
def xml_validator(some_xml_string, xsd_file):
136+
try:
137+
schema = etree.XMLSchema(file=xsd_file)
138+
parser = objectify.makeparser(schema=schema)
139+
objectify.fromstring(some_xml_string, parser)
140+
except XMLSyntaxError:
141+
return False
142+
return True

0 commit comments

Comments
 (0)