Skip to content

Commit 119da7f

Browse files
authored
Merge pull request #69 from TeamSPoon/main
JUnit reports, Allure report, and test comparison reports are availab…
2 parents d81f75d + 8458078 commit 119da7f

File tree

1 file changed

+29
-20
lines changed

1 file changed

+29
-20
lines changed

scripts/into_junit.py

+29-20
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,80 @@
11
import xml.etree.ElementTree as ET
22
import sys
33
import re
4+
from collections import defaultdict
45

56
def create_testcase_element(testclass, testname, stdout, identifier, got, expected, status, url):
7+
# Create the testcase XML element with the class and test name attributes
68
testcase = ET.Element("testcase", classname=testclass, name=testname)
7-
8-
description = f"Test {identifier} with URL: {url}"
9-
9+
1010
if status == "PASS":
11+
# If the test passed, add system-out with a clickable link and details
1112
system_out = ET.SubElement(testcase, "system-out")
1213
system_out.text = f"<![CDATA[\n<a href=\"{url}\">Test Report</a>\n\nAssertion: {stdout}\nExpected: {expected}\nActual: {got}\n]]>"
1314
else: # status == "FAIL"
15+
# If the test failed, add a failure element with details and a clickable link
1416
failure_message = f"Test failed: Expected '{expected}' but got '{got}'"
1517
failure = ET.SubElement(testcase, "failure", message=failure_message, type="AssertionError")
1618
failure.text = f"<![CDATA[\nAssertionError: {failure_message}\n]]>"
1719
system_out = ET.SubElement(testcase, "system-out")
1820
system_out.text = f"<![CDATA[\n<a href=\"{url}\">Test Report</a>\n\nAssertion: {stdout}\nExpected: {expected}\nActual: {got}\n]]>"
19-
21+
2022
return testcase
2123

2224
def parse_test_line(line):
25+
# Split the line into parts based on the table format
2326
parts = re.split(r'\s*\|\s*(?![^()]*\))', line.strip())
2427
if len(parts) < 7:
2528
raise ValueError(f"Line does not have the expected number of parts: {len(parts)} found")
2629

27-
full_identifier = parts[1].strip() # The second field contains the test class and name
30+
full_identifier = parts[1].strip() # The second field contains the test package/class and name
2831
status = parts[2].strip() # The third field contains the pass/fail status
2932
url = re.search(r'\((.*?)\)', parts[3]).group(1).strip() # Extract the URL inside the parentheses
3033
stdout = parts[4].strip() # The fifth field contains the assertion
31-
got = parts[5].strip()
32-
expected = parts[6].strip()
34+
got = parts[5].strip() # The sixth field contains the actual result
35+
expected = parts[6].strip() # The seventh field contains the expected result
3336

3437
try:
35-
testclass, testname = full_identifier.rsplit('.', 1)
36-
if '.' in testclass:
37-
testname = f"{testclass.split('.')[-1]}.{testname}" # Combine to form the correct testname
38-
if not testclass or not testname:
39-
raise ValueError("Test class or test name is empty after splitting.")
38+
# Split the identifier into the package, class, and test names
39+
testpackage, testname = full_identifier.split('.', 1)
40+
if not testpackage or not testname:
41+
raise ValueError("Test package or test name is empty after splitting.")
4042
except ValueError as e:
4143
raise ValueError(f"Identifier does not contain the expected format: {full_identifier}. Error: {str(e)}")
4244

43-
return testclass, testname, stdout, full_identifier, got, expected, status, url
45+
return testpackage, testname, stdout, full_identifier, got, expected, status, url
4446

4547
def generate_junit_xml(input_file):
4648
testsuites = ET.Element("testsuites")
47-
testsuite = ET.Element("testsuite", name="Metta Tests")
48-
testsuites.append(testsuite)
49+
packages_dict = defaultdict(list) # Dictionary to group test cases by their testpackage
4950

5051
with open(input_file, 'r') as file:
5152
for line in file:
5253
parts = None
5354
if line.startswith("|"):
5455
try:
5556
parts = re.split(r'\s*\|\s*(?![^()]*\))', line.strip())
56-
testclass, testname, stdout, full_identifier, got, expected, status, url = parse_test_line(line)
57-
testcase = create_testcase_element(testclass, testname, stdout, full_identifier, got, expected, status, url)
58-
testsuite.append(testcase)
59-
print(f"Processing {testclass}.{testname}: {status}", file=sys.stderr)
57+
testpackage, testname, stdout, full_identifier, got, expected, status, url = parse_test_line(line)
58+
testcase = create_testcase_element(testpackage, testname, stdout, full_identifier, got, expected, status, url)
59+
packages_dict[testpackage].append(testcase)
60+
print(f"Processing {testpackage}.{testname}: {status}", file=sys.stderr)
6061
except ValueError as e:
6162
print(f"Skipping line due to error: {e}\nLine: {line}\nParts: {parts}", file=sys.stderr)
6263

64+
# Create a testsuite for each testpackage group
65+
for testpackage, testcases in packages_dict.items():
66+
testsuite = ET.Element("testsuite", name=testpackage)
67+
for testcase in testcases:
68+
testsuite.append(testcase)
69+
testsuites.append(testsuite)
70+
71+
# Generate the XML tree and return it as a string
6372
tree = ET.ElementTree(testsuites)
6473
return ET.tostring(testsuites, encoding="utf-8", xml_declaration=True).decode("utf-8")
6574

6675
if __name__ == "__main__":
6776
if len(sys.argv) != 2:
68-
print("Usage: python generate_junit.py <input_file>")
77+
print("Usage: python scripts/into_junit.py <input_file>")
6978
sys.exit(1)
7079

7180
input_file = sys.argv[1]

0 commit comments

Comments
 (0)