Skip to content
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

JUnit reports, Allure report, and test comparison reports are availab… #69

Merged
merged 3 commits into from
Aug 14, 2024
Merged
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
49 changes: 29 additions & 20 deletions scripts/into_junit.py
Original file line number Diff line number Diff line change
@@ -1,71 +1,80 @@
import xml.etree.ElementTree as ET
import sys
import re
from collections import defaultdict

def create_testcase_element(testclass, testname, stdout, identifier, got, expected, status, url):
# Create the testcase XML element with the class and test name attributes
testcase = ET.Element("testcase", classname=testclass, name=testname)

description = f"Test {identifier} with URL: {url}"


if status == "PASS":
# If the test passed, add system-out with a clickable link and details
system_out = ET.SubElement(testcase, "system-out")
system_out.text = f"<![CDATA[\n<a href=\"{url}\">Test Report</a>\n\nAssertion: {stdout}\nExpected: {expected}\nActual: {got}\n]]>"
else: # status == "FAIL"
# If the test failed, add a failure element with details and a clickable link
failure_message = f"Test failed: Expected '{expected}' but got '{got}'"
failure = ET.SubElement(testcase, "failure", message=failure_message, type="AssertionError")
failure.text = f"<![CDATA[\nAssertionError: {failure_message}\n]]>"
system_out = ET.SubElement(testcase, "system-out")
system_out.text = f"<![CDATA[\n<a href=\"{url}\">Test Report</a>\n\nAssertion: {stdout}\nExpected: {expected}\nActual: {got}\n]]>"

return testcase

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

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

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

return testclass, testname, stdout, full_identifier, got, expected, status, url
return testpackage, testname, stdout, full_identifier, got, expected, status, url

def generate_junit_xml(input_file):
testsuites = ET.Element("testsuites")
testsuite = ET.Element("testsuite", name="Metta Tests")
testsuites.append(testsuite)
packages_dict = defaultdict(list) # Dictionary to group test cases by their testpackage

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

# Create a testsuite for each testpackage group
for testpackage, testcases in packages_dict.items():
testsuite = ET.Element("testsuite", name=testpackage)
for testcase in testcases:
testsuite.append(testcase)
testsuites.append(testsuite)

# Generate the XML tree and return it as a string
tree = ET.ElementTree(testsuites)
return ET.tostring(testsuites, encoding="utf-8", xml_declaration=True).decode("utf-8")

if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: python generate_junit.py <input_file>")
print("Usage: python scripts/into_junit.py <input_file>")
sys.exit(1)

input_file = sys.argv[1]
Expand Down
Loading