Skip to content

Commit

Permalink
feat(unity): add flag to preserve Python test cases and PYTHON_FUNC a…
Browse files Browse the repository at this point in the history
…ttribute

new
  • Loading branch information
alekseiapa committed Nov 29, 2024
1 parent 8b81166 commit 58cfd66
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 3 deletions.
90 changes: 90 additions & 0 deletions pytest-embedded-idf/tests/test_idf.py
Original file line number Diff line number Diff line change
Expand Up @@ -897,3 +897,93 @@ def test_erase_all_with_port_cache_case2(dut):
)

result.assert_outcomes(passed=2)


def test_no_preserve_python_tests(testdir):
testdir.makepyfile(r"""
def test_python_case(dut):
dut.run_all_single_board_cases(name=["normal_case1", "multiple_stages_test"])
""")

testdir.runpytest(
'-s',
'--embedded-services', 'esp,idf',
'--app-path', os.path.join(testdir.tmpdir, 'unit_test_app_esp32'),
'--log-cli-level', 'DEBUG',
'--junitxml', 'report.xml',
)

junit_report = ET.parse('report.xml').getroot()[0]

assert junit_report.attrib['tests'] == '2'
for testcase in junit_report.findall('testcase'):
assert testcase.attrib['is_unity_case'] == '1'

def test_preserve_python_tests(testdir):
testdir.makepyfile(r"""
def test_python_case(dut):
dut.run_all_single_board_cases(name=["normal_case1", "multiple_stages_test"])
""")

testdir.runpytest(
'-s',
'--embedded-services', 'esp,idf',
'--app-path', os.path.join(testdir.tmpdir, 'unit_test_app_esp32'),
'--log-cli-level', 'DEBUG',
'--junitxml', 'report.xml',
'--unity-test-report-mode', 'merge',
)

junit_report = ET.parse('report.xml').getroot()[0]

assert junit_report.attrib['tests'] == '2'
assert junit_report[0].attrib['is_unity_case'] == '0'
for testcase in junit_report[1:]:
assert testcase.attrib['is_unity_case'] == '1'


def test_preserve_python_tests_with_failures(testdir):
testdir.makepyfile(r"""
def test_python_case(dut):
dut.run_all_single_board_cases(name=["normal_case1", "normal_case2"])
""")

testdir.runpytest(
'-s',
'--embedded-services', 'esp,idf',
'--app-path', os.path.join(testdir.tmpdir, 'unit_test_app_esp32'),
'--log-cli-level', 'DEBUG',
'--junitxml', 'report.xml',
'--unity-test-report-mode', 'merge',
)

junit_report = ET.parse('report.xml').getroot()[0]

assert junit_report.attrib['failures'] == '1'
assert junit_report[0].attrib['is_unity_case'] == '0' # Python test case is preserved
assert junit_report[1].attrib['is_unity_case'] == '1' # C test case
assert junit_report[1].find('failure') is None # normal_case1 passed
assert junit_report[2].attrib['is_unity_case'] == '1'
assert junit_report[2].find('failure') is not None # normal_case2 failed


def test_python_func_attribute(testdir):
testdir.makepyfile(r"""
def test_python_case(dut):
dut.run_all_single_board_cases(name=["normal_case1", "multiple_stages_test"])
""")

testdir.runpytest(
'-s',
'--embedded-services', 'esp,idf',
'--app-path', os.path.join(testdir.tmpdir, 'unit_test_app_esp32'),
'--log-cli-level', 'DEBUG',
'--junitxml', 'report.xml',
'--unity-test-report-mode', 'merge',
)

junit_report = ET.parse('report.xml').getroot()[0]

assert junit_report[0].attrib['is_unity_case'] == '0' # Python test case
for testcase in junit_report[1:]:
assert testcase.attrib['is_unity_case'] == '1' # Other test cases
14 changes: 13 additions & 1 deletion pytest-embedded/pytest_embedded/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,16 @@ def pytest_addoption(parser):
help='y/yes/true for True and n/no/false for False. '
'Set to True to prettify XML junit report. (Default: False)',
)
parser.addoption(
'--unity-test-report-mode',
choices=['merge', 'replace'],
default='replace',
help=(
'Specify the behavior for handling Unity test cases in the main JUnit report. '
"'merge' includes them alongside the parent Python test case. "
"'replace' substitutes the parent Python test case with Unity test cases (default)."
),
)

# supports parametrization
base_group.addoption('--root-logdir', help='set session-based root log dir. (Default: system temp folder)')
Expand Down Expand Up @@ -1183,7 +1193,9 @@ def unity_tester(dut: t.Union['IdfDut', t.Tuple['IdfDut']]) -> t.Optional['CaseT


def pytest_configure(config: Config) -> None:
config.stash[_junit_merger_key] = JunitMerger(config.option.xmlpath)
config.stash[_junit_merger_key] = JunitMerger(
config.option.xmlpath, config.getoption('unity_test_report_mode', default='replace')
)
config.stash[_junit_report_path_key] = config.option.xmlpath

config.stash[_pytest_embedded_key] = PytestEmbedded(
Expand Down
13 changes: 11 additions & 2 deletions pytest-embedded/pytest_embedded/unity.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ class TestFormat(enum.Enum):
FIXTURE = 1


class UnityTestReportMode(enum.Enum):
REPLACE = 'replace'


class TestCase:
def __init__(self, name: str, result: str, **kwargs):
self.name = name
Expand Down Expand Up @@ -206,8 +210,9 @@ class JunitMerger:
SUB_JUNIT_FILENAME = 'dut.xml'
# multi-dut junit reports should be dut-[INDEX].xml

def __init__(self, main_junit: Optional[str]) -> None:
def __init__(self, main_junit: Optional[str], unity_test_report_mode: Optional[str] = 'replace') -> None:
self.junit_path = main_junit
self.unity_test_report_mode = unity_test_report_mode or UnityTestReportMode.REPLACE.value

self._junit = None

Expand Down Expand Up @@ -291,9 +296,13 @@ def merge(self, junit_files: List[str]):
raise ValueError(f'Could\'t find test case {test_case_name}, dumped into "debug.xml" for debugging')

junit_case_is_fail = junit_case.find('failure') is not None
junit_parent.remove(junit_case)

junit_case.attrib['is_unity_case'] = '0'
if self.unity_test_report_mode == 'replace':
junit_parent.remove(junit_case)

for case in merging_cases:
case.attrib['is_unity_case'] = '1'
junit_parent.append(case)

junit_parent.attrib['errors'] = self._int_add(
Expand Down

0 comments on commit 58cfd66

Please sign in to comment.