Skip to content

Commit 4418e5b

Browse files
Merge pull request #1703 from Kranium2002/improvement/standardize-report-format
Add a to_junit method to standardize the report format of TestSuiteResult
2 parents 35b24e7 + 42b1dee commit 4418e5b

File tree

1 file changed

+36
-1
lines changed

1 file changed

+36
-1
lines changed

giskard/core/suite.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66
from dataclasses import dataclass
77
from functools import singledispatchmethod
88

9+
from xml.etree.ElementTree import Element, SubElement, tostring
10+
from xml.dom import minidom
911
from mlflow import MlflowClient
10-
1112
from giskard.client.dtos import SuiteInfo, SuiteTestDTO, TestInputDTO, TestSuiteDTO
1213
from giskard.client.giskard_client import GiskardClient
1314
from giskard.core.core import TestFunctionMeta
@@ -156,6 +157,40 @@ def to_wandb(self, run: Optional["wandb.wandb_sdk.wandb_run.Run"] = None) -> Non
156157
run.log({"Test suite results/Test-Suite Results": wandb.Table(columns=columns, data=data)})
157158

158159

160+
def to_junit(self):
161+
"""Convert the test suite result to JUnit XML format."""
162+
testsuites = Element('testsuites', {'tests': str(len(self.results))})
163+
164+
for test_tuple in self.results:
165+
test_name, test, _ = test_tuple
166+
testsuite = SubElement(testsuites, 'testsuite', {
167+
'name': f"Test {test_name} (metric={test.metric})",
168+
})
169+
testcase = SubElement(testsuite, 'testcase', {'name': test.metric_name, 'time': str(test.metric)}) # replace with actual time
170+
171+
if not test.passed:
172+
failure = SubElement(testcase, 'failure', {
173+
'message': f"Test failed with metric of {test.metric}",
174+
'type': "TestFailed" if not test.is_error else "Error"
175+
})
176+
# Add full test result information here
177+
for k, v in test.__dict__.items():
178+
if k != 'messages' and k != 'is_error':
179+
SubElement(failure, 'detail', {'name': k, 'value': str(v)})
180+
for message in test.messages:
181+
SubElement(failure, 'detail', {'name': 'message', 'value': message})
182+
else:
183+
# Add test result information here
184+
for k, v in test.__dict__.items():
185+
if k != 'messages' and k != 'is_error':
186+
SubElement(testcase, 'detail', {'name': k, 'value': str(v)})
187+
for message in test.messages:
188+
SubElement(testcase, 'detail', {'name': 'message', 'value': message})
189+
190+
# Convert to string
191+
xml_str = minidom.parseString(tostring(testsuites)).toprettyxml(indent=" ")
192+
return xml_str
193+
159194
class SuiteInput:
160195
"""Represents an input parameter for a test suite.
161196

0 commit comments

Comments
 (0)