From b1223d6bba639bbde1335153bc9dbc7c41b9bb4f Mon Sep 17 00:00:00 2001 From: horw Date: Wed, 7 Feb 2024 11:30:17 +0800 Subject: [PATCH] feat: add unity_tester fix: use only custom dut --- pytest-embedded-idf/tests/test_idf.py | 48 +++++++++++++++++++ pytest-embedded-serial/tests/test_serial.py | 10 ++-- .../pytest_embedded/dut_factory.py | 15 ++++-- pytest-embedded/pytest_embedded/plugin.py | 12 +++-- 4 files changed, 76 insertions(+), 9 deletions(-) diff --git a/pytest-embedded-idf/tests/test_idf.py b/pytest-embedded-idf/tests/test_idf.py index f16d34ff..dcdce26e 100644 --- a/pytest-embedded-idf/tests/test_idf.py +++ b/pytest-embedded-idf/tests/test_idf.py @@ -5,6 +5,7 @@ import xml.etree.ElementTree as ET import pytest + from pytest_embedded_idf.dut import IdfDut toolchain_required = pytest.mark.skipif( @@ -35,6 +36,53 @@ def test_idf_serial_flash(dut): result.assert_outcomes(passed=1) +def test_custom_idf_device_dut(testdir): + p = os.path.join(testdir.tmpdir, 'hello_world_esp32') + unity_test_path = os.path.join(testdir.tmpdir, 'unit_test_app_esp32') + testdir.makepyfile(f""" + import pytest + + def test_idf_custom_dev(): + from pytest_embedded.dut_factory import DutFactory + dut = DutFactory.create(embedded_services='esp,idf', app_path=r'{p}') + dut.expect("Hello") + + def test_idf_mixed(dut): + from pytest_embedded.dut_factory import DutFactory + dutc = DutFactory.create(embedded_services='esp,idf', app_path=r'{p}') + dutc.expect("Hello") + dut.expect("Hello") + assert dutc.serial.port!=dut.serial.port + + def test_idf_unity_tester(): + from pytest_embedded.dut_factory import DutFactory + dut1 = DutFactory.create(embedded_services='esp,idf', app_path=r'{unity_test_path}') + dut2 = DutFactory.create(embedded_services='esp,idf', app_path=r'{unity_test_path}') + tester = DutFactory.unity_tester(dut1, dut2) + tester.run_all_cases() + + def test_idf_run_all_single_board_cases(): + from pytest_embedded.dut_factory import DutFactory + dut1 = DutFactory.create(embedded_services='esp,idf', app_path=r'{unity_test_path}') + dut1.run_all_single_board_cases() + """) + + result = testdir.runpytest( + '-s', + '--app-path', p, + '--embedded-services', 'esp,idf', + '--junitxml', 'report.xml', + ) + result.assert_outcomes(passed=4, errors=0) + + junit_report = ET.parse('report.xml').getroot()[0] + + assert junit_report.attrib['errors'] == '0' + assert junit_report.attrib['failures'] == '2' + assert junit_report.attrib['skipped'] == '0' + assert junit_report.attrib['tests'] == '7' + + def test_idf_serial_flash_with_erase_nvs(testdir): testdir.makepyfile(""" import pexpect diff --git a/pytest-embedded-serial/tests/test_serial.py b/pytest-embedded-serial/tests/test_serial.py index a13d76f4..43f57c58 100644 --- a/pytest-embedded-serial/tests/test_serial.py +++ b/pytest-embedded-serial/tests/test_serial.py @@ -3,11 +3,11 @@ import pytest -def test_custom_serial_device_dut_count_2(testdir): +def test_custom_serial_device(testdir): testdir.makepyfile(r""" import pytest - def test_serial_device_created_dut_count_2(dut): + def test_serial_mixed(dut): from pytest_embedded.dut_factory import DutFactory assert len(dut)==2 another_dut = DutFactory.create() @@ -19,6 +19,10 @@ def test_serial_device_created_dut_count_2(dut): ) ) assert len(st) == 3 + + def test_custom_dut(): + from pytest_embedded.dut_factory import DutFactory + another_dut = DutFactory.create(embedded_services='esp,serial') """) result = testdir.runpytest( @@ -26,7 +30,7 @@ def test_serial_device_created_dut_count_2(dut): '--embedded-services', 'esp,serial', '--count', 2, ) - result.assert_outcomes(passed=1, errors=0) + result.assert_outcomes(passed=2, errors=0) def test_custom_serial_device_dut_count_1(testdir): diff --git a/pytest-embedded/pytest_embedded/dut_factory.py b/pytest-embedded/pytest_embedded/dut_factory.py index 73ababc3..3a3a31cb 100644 --- a/pytest-embedded/pytest_embedded/dut_factory.py +++ b/pytest-embedded/pytest_embedded/dut_factory.py @@ -10,6 +10,9 @@ from collections import defaultdict from pathlib import Path +from pytest_embedded_idf import CaseTester +from pytest_embedded_idf.dut import IdfDut + if t.TYPE_CHECKING: from pytest_embedded_idf import LinuxSerial from pytest_embedded_jtag import Gdb, OpenOcd @@ -315,9 +318,10 @@ def _fixture_classes_and_options_fn( ) if 'idf' in _services: - from pytest_embedded_idf.unity_tester import IdfUnityDutMixin from pytest_embedded_wokwi.idf import IDFFirmwareResolver + from pytest_embedded_idf.unity_tester import IdfUnityDutMixin + kwargs['wokwi'].update({'firmware_resolver': IDFFirmwareResolver()}) mixins[fixture].append(IdfUnityDutMixin) @@ -558,12 +562,17 @@ def close(cls): del DutFactory.obj_stack cls.obj_stack = [] + @classmethod + def unity_tester(cls, *args: 'IdfDut'): + return CaseTester(args) + @classmethod def create( cls, *, + embedded_services='', app_path='', - build_dir='', + build_dir='build', port=None, port_location=None, port_mac=None, @@ -612,7 +621,7 @@ def create( pexpect_proc = pexpect_proc_fn(_pexpect_fr) _kwargs = { - '_services': buff_parametrized_fixtures['_services'], + '_services': embedded_services or buff_parametrized_fixtures['_services'], # parametrize fixtures 'app_path': app_path, 'build_dir': build_dir, diff --git a/pytest-embedded/pytest_embedded/plugin.py b/pytest-embedded/pytest_embedded/plugin.py index 4b68c861..ac6b0636 100644 --- a/pytest-embedded/pytest_embedded/plugin.py +++ b/pytest-embedded/pytest_embedded/plugin.py @@ -61,12 +61,13 @@ ) if t.TYPE_CHECKING: - from pytest_embedded_idf import CaseTester, IdfDut, LinuxSerial from pytest_embedded_jtag import Gdb, OpenOcd from pytest_embedded_qemu import Qemu from pytest_embedded_serial import Serial from pytest_embedded_wokwi import WokwiCLI + from pytest_embedded_idf import CaseTester, IdfDut, LinuxSerial + _T = t.TypeVar('_T') @@ -951,7 +952,7 @@ def _services(embedded_services: t.Optional[str]) -> t.List[str]: return ['base'] + services -@pytest.fixture +@pytest.fixture(autouse=True) @multi_dut_fixture def parametrize_fixtures( _services, @@ -993,6 +994,12 @@ def parametrize_fixtures( return locals() +@pytest.fixture(autouse=True) +def close_factory_duts(): + yield + DutFactory.close() + + @pytest.fixture @multi_dut_fixture def _fixture_classes_and_options( @@ -1266,5 +1273,4 @@ def pytest_sessionfinish(self, session: Session, exitstatus: int) -> None: # no if self.prettify_junit_report: _prettify_xml(_stash_junit_report_path) - DutFactory.close() exitstatus = int(modifier.failed) # True -> 1 False -> 0 # noqa