Skip to content
Merged
Show file tree
Hide file tree
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
10 changes: 9 additions & 1 deletion mlx/unity2junit/unity2junit.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ def parse_unity_output(self):
}
if result.strip() == "FAIL":
self.failures += 1
if reason:
test_case["reason"] = reason.lstrip(':').strip()
elif result.strip() == "SKIP":
self.skipped += 1
self.test_cases.append(test_case)
Expand All @@ -89,13 +91,19 @@ def generate_junit_xml(self):
skipped="0"
)

ET.SubElement(
testcase_element = ET.SubElement(
testsuite, "testcase",
name=case["name"],
classname=case["classname"],
time="0.0"
)

if case["result"] == "FAIL":
message = case.get("reason", "No reason")
ET.SubElement(testcase_element, "failure", message=message)
elif case["result"] == "SKIP":
ET.SubElement(testcase_element, "skipped")

tree = ET.ElementTree(testsuites)
ET.indent(tree, space=" ", level=0)
tree.write(self.output_file, encoding="utf-8", xml_declaration=True)
Expand Down
21 changes: 21 additions & 0 deletions tests/test_in/utest_Failed_Runner.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version='1.0' encoding='utf-8'?>
<testsuites>
<testsuite name="INIT" errors="0" tests="5" failures="1" skipped="0" timestamp="2025-09-25T13:40:24.403458+00:00" />
<testsuite name="INIT.SWUTEST_INIT-TEST_INIT_SUCCESS" timestamp="2025-09-25T13:40:24.403458+00:00" time="0.0" errors="0" tests="1" failures="0" skipped="0">
<testcase name="SWUTEST_INIT-TEST_INIT_SUCCESS" classname="INIT.SWUTEST_INIT-TEST_INIT_SUCCESS" time="0.0" />
</testsuite>
<testsuite name="INIT.SWUTEST_INIT-TEST_INIT_WRONG_EEPROM_VERSION" timestamp="2025-09-25T13:40:24.403458+00:00" time="0.0" errors="0" tests="1" failures="0" skipped="0">
<testcase name="SWUTEST_INIT-TEST_INIT_WRONG_EEPROM_VERSION" classname="INIT.SWUTEST_INIT-TEST_INIT_WRONG_EEPROM_VERSION" time="0.0" />
</testsuite>
<testsuite name="INIT.SWUTEST_INIT-TEST_INIT_I2C_READ_FAILS" timestamp="2025-09-25T13:40:24.403458+00:00" time="0.0" errors="0" tests="1" failures="1" skipped="0">
<testcase name="SWUTEST_INIT-TEST_INIT_I2C_READ_FAILS" classname="INIT.SWUTEST_INIT-TEST_INIT_I2C_READ_FAILS" time="0.0">
<failure message="Function Blah_SecondFunction. Called more times than expected." />
</testcase>
</testsuite>
<testsuite name="INIT.SWUTEST_INIT-TEST_INIT_I2C_READ_FAILS2" timestamp="2025-09-25T13:40:24.403458+00:00" time="0.0" errors="0" tests="1" failures="0" skipped="0">
<testcase name="SWUTEST_INIT-TEST_INIT_I2C_READ_FAILS2" classname="INIT.SWUTEST_INIT-TEST_INIT_I2C_READ_FAILS2" time="0.0" />
</testsuite>
<testsuite name="INIT.SWUTEST_INIT-TEST_INIT_I2C_READ_FAILS3" timestamp="2025-09-25T13:40:24.403458+00:00" time="0.0" errors="0" tests="1" failures="0" skipped="0">
<testcase name="SWUTEST_INIT-TEST_INIT_I2C_READ_FAILS3" classname="INIT.SWUTEST_INIT-TEST_INIT_I2C_READ_FAILS3" time="0.0" />
</testsuite>
</testsuites>
25 changes: 25 additions & 0 deletions tests/unity_parsing_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,19 @@ def test_parsing_unity_log_and_building_testcases_failed(self):
'SWUTEST_INIT-TEST_INIT_I2C_READ_FAILS2',
'SWUTEST_INIT-TEST_INIT_I2C_READ_FAILS3']
expected_test_cases_Failed_Runner['result'] = ['PASS', 'PASS', 'FAIL', 'PASS', 'PASS']
expected_test_cases_Failed_Runner['reason'] = [None, None,
'Function Blah_SecondFunction. Called more times than '
'expected.', None, None]

for tc in test_cases:
# Find some smart way to check the test case class, name and line number
self.assertEqual(tc['classname'], expected_test_cases_Failed_Runner['classname'].pop(0))
self.assertEqual(tc['line'], expected_test_cases_Failed_Runner['line'].pop(0))
self.assertEqual(tc['name'], expected_test_cases_Failed_Runner['name'].pop(0))
self.assertEqual(tc['result'], expected_test_cases_Failed_Runner['result'].pop(0))
expected_reason = expected_test_cases_Failed_Runner['reason'].pop(0)
if expected_reason:
self.assertEqual(tc.get('reason'), expected_reason)

self.assertEqual(tc['file'], 'unit_test/utest_Init.c')

Expand All @@ -123,6 +129,25 @@ def test_parsing_unity_log_and_building_testcases_failed(self):
self.assertEqual(converter.failures, 1)
self.assertEqual(converter.skipped, 0)

def test_failed_runner_output(self):
'''Verify that utest_Failed_Runner.log is converted to utest_Failed_Runner.xml on a fixed timestamp of
2025-09-25T13:40:24.403458+00:00 and that the failure message is correctly included.'''
fixed_timestamp_str = "2025-09-25T13:40:24.403458"
fixed_datetime = datetime.fromisoformat(fixed_timestamp_str).replace(tzinfo=timezone.utc)
expected_xml = ''

with open(TEST_IN_DIR / 'utest_Failed_Runner.xml', 'r', encoding='utf-8') as f:
expected_xml = f.readlines()

with tempfile.NamedTemporaryFile(mode='w+', delete=True, encoding='utf-8') as tmp_output_file:
with patch('mlx.unity2junit.unity2junit.datetime') as mock_dt:
mock_dt.now.return_value = fixed_datetime
converter = Unity2Junit(TEST_IN_DIR / 'utest_Failed_Runner.log', tmp_output_file.name)
converter.convert()
tmp_output_file.seek(0)
generated_xml = tmp_output_file.readlines()
self.assertListEqual(generated_xml, expected_xml)

def test_init_runner_output(self):
'''Verify that utest_Init_Runner.log is converted to utest_Init_Runner.xml on a fixed timestamp of
2025-09-25T13:40:24.403458+00:00'''
Expand Down