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
11 changes: 8 additions & 3 deletions mlx/unity2junit/unity2junit.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@

class Unity2Junit:
"""Converts a Unity test output log to a JUnit XML report."""
def __init__(self, log_file, output_file):
def __init__(self, log_file, output_file, tc_prefix=None):
self.log_file = log_file
self.output_file = output_file
self.test_cases = []
self.default_suite_name = "EMPTY"
self.total_tests = 0
self.failures = 0
self.skipped = 0
self.test_case_prefix = tc_prefix

def parse_unity_output(self):
"""Parses the Unity log file and populates test case data."""
Expand All @@ -36,8 +37,11 @@ def parse_unity_output(self):
filename = os.path.basename(file_path).replace("utest_", "").split('.')[0].upper()
self.default_suite_name = filename # Set the default testsuite name

if self.test_case_prefix is None:
self.test_case_prefix = f"SWUTEST_{filename}-"

# Modify the test name: replace the underscore between SWUTEST_ and the next part with a hyphen
formatted_test_name = f"SWUTEST_{filename}-{test_name.upper()}"
formatted_test_name = f"{self.test_case_prefix}{test_name.upper()}"

test_case = {
"name": formatted_test_name,
Expand Down Expand Up @@ -97,9 +101,10 @@ def main():
parser.add_argument("log_file", help="Path to the Unity test output log file.")
parser.add_argument("output_file", help="Path to the output JUnit XML file.")
parser.add_argument("--version", "-v", action="version", version=f"%(prog)s {__version__}")
parser.add_argument("--tc-prefix", help="Prefix to add to each test case name.", default=None)
args = parser.parse_args()

converter = Unity2Junit(args.log_file, args.output_file)
converter = Unity2Junit(args.log_file, args.output_file, tc_prefix=args.tc_prefix)
converter.convert()


Expand Down
121 changes: 121 additions & 0 deletions tests/unity_parsing_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,127 @@ def test_init_runner_output(self):
generated_xml = tmp_output_file.readlines()
self.assertListEqual(generated_xml, expected_xml)

def test_force_test_case_prefix(self):
''' Verify that when a prefix is forced, it is used as the testsuite name.'''
with tempfile.NamedTemporaryFile(mode='w', delete=True) as tmp_output_file:
converter = Unity2Junit(TEST_IN_DIR / 'utest_Init_Runner.log', tmp_output_file.name,
tc_prefix="FORCED_PREFIX-")
converter.parse_unity_output()
test_cases = converter.test_cases

expected_test_cases_Init_Runner = {}
expected_test_cases_Init_Runner['classname'] = [
'INIT.FORCED_PREFIX-TEST_INIT_SUCCESS', 'INIT.FORCED_PREFIX-TEST_INIT_WRONG_EEPROM_VERSION',
'INIT.FORCED_PREFIX-TEST_INIT_I2C_READ_FAILS', 'INIT.FORCED_PREFIX-TEST_INIT_I2C_READ_FAILS2',
'INIT.FORCED_PREFIX-TEST_INIT_I2C_READ_FAILS3']
expected_test_cases_Init_Runner['line'] = ['49', '124', '135', '145', '163']
expected_test_cases_Init_Runner['name'] = ['FORCED_PREFIX-TEST_INIT_SUCCESS',
'FORCED_PREFIX-TEST_INIT_WRONG_EEPROM_VERSION',
'FORCED_PREFIX-TEST_INIT_I2C_READ_FAILS',
'FORCED_PREFIX-TEST_INIT_I2C_READ_FAILS2',
'FORCED_PREFIX-TEST_INIT_I2C_READ_FAILS3']

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_Init_Runner['classname'].pop(0))
self.assertEqual(tc['line'], expected_test_cases_Init_Runner['line'].pop(0))
self.assertEqual(tc['name'], expected_test_cases_Init_Runner['name'].pop(0))
self.assertEqual(tc['result'], 'PASS')

self.assertEqual(tc['file'], 'unit_test/utest_Init.c')
self.assertEqual(tc['suite'], 'INIT') # The suite in test cases remains the same

def test_force_test_case_prefix_noname(self):
''' Verify that when a prefix is forced, it is used as the testsuite name even when utest.c is used.'''
with tempfile.NamedTemporaryFile(mode='w', delete=True) as tmp_output_file:
converter = Unity2Junit(TEST_IN_DIR / 'utest_Noname_Runner.log', tmp_output_file.name,
tc_prefix="FORCED_PREFIX-")
converter.parse_unity_output()
test_cases = converter.test_cases

expected_test_cases_Noname_Runner = {}
expected_test_cases_Noname_Runner['classname'] = [
'UTEST.FORCED_PREFIX-TEST_INIT_SUCCESS', 'UTEST.FORCED_PREFIX-TEST_INIT_WRONG_EEPROM_VERSION',
'UTEST.FORCED_PREFIX-TEST_INIT_I2C_READ_FAILS', 'UTEST.FORCED_PREFIX-TEST_INIT_I2C_READ_FAILS2',
'UTEST.FORCED_PREFIX-TEST_INIT_I2C_READ_FAILS3']
expected_test_cases_Noname_Runner['line'] = ['49', '124', '135', '145', '163']
expected_test_cases_Noname_Runner['name'] = ['FORCED_PREFIX-TEST_INIT_SUCCESS',
'FORCED_PREFIX-TEST_INIT_WRONG_EEPROM_VERSION',
'FORCED_PREFIX-TEST_INIT_I2C_READ_FAILS',
'FORCED_PREFIX-TEST_INIT_I2C_READ_FAILS2',
'FORCED_PREFIX-TEST_INIT_I2C_READ_FAILS3']

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_Noname_Runner['classname'].pop(0))
self.assertEqual(tc['line'], expected_test_cases_Noname_Runner['line'].pop(0))
self.assertEqual(tc['name'], expected_test_cases_Noname_Runner['name'].pop(0))
self.assertEqual(tc['result'], 'PASS')

self.assertEqual(tc['file'], 'unit_test/utest.c')
self.assertEqual(tc['suite'], 'UTEST') # The suite in test cases remains the same

def test_force_test_case_prefix_empty(self):
''' Verify that when an empty prefix is forced, the default prefix is used as the testsuite name.'''
with tempfile.NamedTemporaryFile(mode='w', delete=True) as tmp_output_file:
converter = Unity2Junit(TEST_IN_DIR / 'utest_Init_Runner.log', tmp_output_file.name,
tc_prefix="")
converter.parse_unity_output()
test_cases = converter.test_cases

expected_test_cases_Init_Runner = {}
expected_test_cases_Init_Runner['classname'] = [
'INIT.TEST_INIT_SUCCESS', 'INIT.TEST_INIT_WRONG_EEPROM_VERSION',
'INIT.TEST_INIT_I2C_READ_FAILS', 'INIT.TEST_INIT_I2C_READ_FAILS2',
'INIT.TEST_INIT_I2C_READ_FAILS3']
expected_test_cases_Init_Runner['line'] = ['49', '124', '135', '145', '163']
expected_test_cases_Init_Runner['name'] = ['TEST_INIT_SUCCESS',
'TEST_INIT_WRONG_EEPROM_VERSION',
'TEST_INIT_I2C_READ_FAILS',
'TEST_INIT_I2C_READ_FAILS2',
'TEST_INIT_I2C_READ_FAILS3']

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_Init_Runner['classname'].pop(0))
self.assertEqual(tc['line'], expected_test_cases_Init_Runner['line'].pop(0))
self.assertEqual(tc['name'], expected_test_cases_Init_Runner['name'].pop(0))
self.assertEqual(tc['result'], 'PASS')

self.assertEqual(tc['file'], 'unit_test/utest_Init.c')
self.assertEqual(tc['suite'], 'INIT') # The suite in test cases remains the same

def test_force_test_case_prefix_empty_noname(self):
''' Verify that when an empty prefix is forced, the default prefix is used as the testsuite name even when
utest.c is used.'''
with tempfile.NamedTemporaryFile(mode='w', delete=True) as tmp_output_file:
converter = Unity2Junit(TEST_IN_DIR / 'utest_Noname_Runner.log', tmp_output_file.name,
tc_prefix="")
converter.parse_unity_output()
test_cases = converter.test_cases

expected_test_cases_Noname_Runner = {}
expected_test_cases_Noname_Runner['classname'] = [
'UTEST.TEST_INIT_SUCCESS', 'UTEST.TEST_INIT_WRONG_EEPROM_VERSION',
'UTEST.TEST_INIT_I2C_READ_FAILS', 'UTEST.TEST_INIT_I2C_READ_FAILS2',
'UTEST.TEST_INIT_I2C_READ_FAILS3']
expected_test_cases_Noname_Runner['line'] = ['49', '124', '135', '145', '163']
expected_test_cases_Noname_Runner['name'] = ['TEST_INIT_SUCCESS',
'TEST_INIT_WRONG_EEPROM_VERSION',
'TEST_INIT_I2C_READ_FAILS',
'TEST_INIT_I2C_READ_FAILS2',
'TEST_INIT_I2C_READ_FAILS3']

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_Noname_Runner['classname'].pop(0))
self.assertEqual(tc['line'], expected_test_cases_Noname_Runner['line'].pop(0))
self.assertEqual(tc['name'], expected_test_cases_Noname_Runner['name'].pop(0))
self.assertEqual(tc['result'], 'PASS')

self.assertEqual(tc['file'], 'unit_test/utest.c')
self.assertEqual(tc['suite'], 'UTEST') # The suite in test cases remains the same


if __name__ == '__main__':
unittest.main()