ci: move linux test cli args alongside the test scripts

This commit is contained in:
Fu Hanxi
2026-03-26 10:40:40 +01:00
parent ddc7e0cdf7
commit 036bb8ec77
5 changed files with 98 additions and 29 deletions
+1 -1
View File
@@ -396,7 +396,7 @@ test_pytest_linux:
- run_cmd idf-ci gitlab download-known-failure-cases-file ${KNOWN_FAILURE_CASES_FILE_NAME}
- run_cmd pytest
--target linux
--embedded-services idf
-m \"not macos\"
--junitxml=XUNIT_RESULT.xml
--ignore-result-files ${KNOWN_FAILURE_CASES_FILE_NAME}
@@ -127,15 +127,13 @@ def test_console_help_reverse_registration(dut: Dut) -> None:
@idf_parametrize('config', ['sorted'], indirect=['config'])
@idf_parametrize('target', ['linux'], indirect=['target'])
@idf_parametrize('test_on,markers', [('host', (pytest.mark.host_test,))])
def test_console_sorted_help_sorted_registration(dut: Dut, test_on: str) -> None:
def test_console_sorted_help_sorted_registration(dut: Dut) -> None:
do_test_help_generic(dut, 'sorted')
@idf_parametrize('config', ['sorted'], indirect=['config'])
@idf_parametrize('target', ['linux'], indirect=['target'])
@idf_parametrize('test_on,markers', [('host', (pytest.mark.host_test,))])
def test_console_sorted_help_reverse_registration(dut: Dut, test_on: str) -> None:
def test_console_sorted_help_reverse_registration(dut: Dut) -> None:
do_test_help_generic(dut, 'reverse')
@@ -120,25 +120,51 @@ Next is the environment marker. The ``@pytest.mark.generic`` marker indicates th
Finally, we have the test function. With a ``dut`` fixture. In single-dut test cases, the ``dut`` fixture is an instance of ``IdfDut`` class, for multi-dut test cases, it is a tuple of ``IdfDut`` instances. For more details regarding the ``IdfDut`` class, please refer to `pytest-embedded IdfDut API reference <https://docs.espressif.com/projects/pytest-embedded/en/latest/api.html#pytest_embedded_idf.dut.IdfDut>`__.
Running Tests in QEMU
^^^^^^^^^^^^^^^^^^^^^
Running Tests on Linux
^^^^^^^^^^^^^^^^^^^^^^
To execute a pytest case in QEMU, add the ``@pytest.mark.qemu`` marker to the test function.
To execute a pytest case on the Linux host, set ``target`` to ``linux``.
.. code-block:: python
@pytest.mark.qemu
@idf_parametrize('target', ['esp32', 'esp32c3'], indirect=['target'])
def test_hello_world_qemu(dut) -> None:
@idf_parametrize('target', ['linux'], indirect=['target'])
def test_hello_world_linux(dut) -> None:
dut.expect('Hello world!')
This is the simplest way to run the same test flow in QEMU instead of on physical hardware.
This is the simplest way to run the same test flow on the Linux host instead of on physical hardware.
For a simple QEMU-only test, adding ``pytest.mark.qemu`` is enough and the ``idf,qemu`` embedded services will be selected automatically.
For a simple Linux-only test, setting ``target`` to ``linux`` is enough and the ``idf`` embedded services will be selected automatically. The ``pytest.mark.host_test`` marker is not required.
For a mixed environment matrix, specify ``embedded_services`` manually for each case. See the later section :ref:`same-app-with-different-running-environments` for a more complex example.
For a mixed environment matrix, specify ``embedded_services`` manually for each case. See :ref:`Same App With Different Running Environments <pytest-same-app-different-running-environments>` for a more complex example.
For QEMU installation and setup, refer to :doc:`../api-guides/tools/qemu`.
.. only:: TARGET_SUPPORT_QEMU
Running Tests in QEMU
^^^^^^^^^^^^^^^^^^^^^
To execute a pytest case in QEMU, add the ``@pytest.mark.qemu`` marker to the test function.
.. code-block:: python
@pytest.mark.qemu
@idf_parametrize('target', ['esp32', 'esp32c3'], indirect=['target'])
def test_hello_world_qemu(dut) -> None:
dut.expect('Hello world!')
This is the simplest way to run the same test flow in QEMU instead of on physical hardware.
For a simple QEMU-only test, adding ``pytest.mark.qemu`` is enough and the ``idf,qemu`` embedded services will be selected automatically.
For a mixed environment matrix, specify ``embedded_services`` manually for each case. See the later section in this guide for a more complex example.
For QEMU installation and setup, refer to page :doc:`/api-guides/tools/qemu`.
Deprecation of ``pytest.mark.host_test``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
``pytest.mark.host_test`` is no longer needed and should not be added to new test cases.
For Linux target test cases and QEMU test cases, the required behavior is handled dynamically by the test framework. In particular, the embedded services are selected automatically for simple Linux-only and QEMU-only cases.
Same App With Different sdkconfig Files
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -223,6 +249,8 @@ Now this test function would be replicated to 2 test cases (represented as test
* ``esp32.foo.test_foo_bar``
* ``esp32s2.bar.test_foo_bar``
.. _pytest-same-app-different-running-environments:
Same App With Different Running Environments
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -120,25 +120,51 @@ ESP-IDF 在主机端使用 pytest 框架(以及一些 pytest 插件)来自
关于测试函数,使用了一个 ``dut`` fixture。在单一 DUT 测试用例中,``dut`` fixture 是 ``IdfDut`` 类的一个实例,对于多个 DUT 测试用例,它是 ``IdfDut`` 实例的一个元组。有关 ``IdfDut`` 类的更多详细信息,请参阅 `pytest-embedded IdfDut API 参考 <https://docs.espressif.com/projects/pytest-embedded/en/latest/api.html#pytest_embedded_idf.dut.IdfDut>`__
QEMU 中运行测试
^^^^^^^^^^^^^^^^^^^^^
Linux 上运行测试
^^^^^^^^^^^^^^^^^^^^
要在 QEMU 中执行 pytest 测试用例,请将 ``@pytest.mark.qemu`` 添加到测试函数上。
要在 Linux 主机上执行 pytest 测试用例,请将 ``target`` 设置为 ``linux``
.. code-block:: python
@pytest.mark.qemu
@idf_parametrize('target', ['esp32', 'esp32c3'], indirect=['target'])
def test_hello_world_qemu(dut) -> None:
@idf_parametrize('target', ['linux'], indirect=['target'])
def test_hello_world_linux(dut) -> None:
dut.expect('Hello world!')
这是在 QEMU 中运行与物理硬件相同测试流程的最简单方式。
这是在 Linux 主机上运行与物理硬件相同测试流程的最简单方式。
对于简单的纯 QEMU 测试,只需添加 ``pytest.mark.qemu``,系统会自动选择 ``idf,qemu`` 对应的 embedded services。
对于简单的纯 Linux 测试,只需``target`` 设置为 ``linux``,系统会自动选择 ``idf`` 对应的 embedded services。``pytest.mark.host_test`` marker 不再需要。
对于混合运行环境矩阵,则需要为每个用例手动指定 ``embedded_services``。更复杂的示例请参阅本指南后面的 :ref:`same-app-with-different-running-environments` 小节。
对于混合运行环境矩阵,则需要为每个用例手动指定 ``embedded_services``。更复杂的示例请参阅 :ref:`在不同运行环境中运行相同的应用程序 <pytest-same-app-different-running-environments>` 小节。
有关 QEMU 的安装和配置,请参阅 :doc:`../api-guides/tools/qemu`
.. only:: TARGET_SUPPORT_QEMU
在 QEMU 中运行测试
^^^^^^^^^^^^^^^^^^^^^
要在 QEMU 中执行 pytest 测试用例,请将 ``@pytest.mark.qemu`` 添加到测试函数上。
.. code-block:: python
@pytest.mark.qemu
@idf_parametrize('target', ['esp32', 'esp32c3'], indirect=['target'])
def test_hello_world_qemu(dut) -> None:
dut.expect('Hello world!')
这是在 QEMU 中运行与物理硬件相同测试流程的最简单方式。
对于简单的纯 QEMU 测试,只需添加 ``pytest.mark.qemu``,系统会自动选择 ``idf,qemu`` 对应的 embedded services。
对于混合运行环境矩阵,则需要为每个用例手动指定 ``embedded_services``。更复杂的示例请参阅本指南后面的对应小节。
有关 QEMU 的安装和配置,请参阅页面 :doc:`../api-guides/tools/qemu`
``pytest.mark.host_test`` 的弃用说明
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
``pytest.mark.host_test`` 已不再需要,也不应再添加到新的测试用例中。
对于 Linux target 测试用例和 QEMU 测试用例,相关行为会由测试框架动态处理。尤其是在简单的纯 Linux 或纯 QEMU 场景下,embedded services 会被自动选择。
使用不同的 sdkconfig 文件运行相同的应用程序
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -223,6 +249,8 @@ ESP-IDF 在主机端使用 pytest 框架(以及一些 pytest 插件)来自
* ``esp32.foo.test_foo_bar``
* ``esp32s2.bar.test_foo_bar``
.. _pytest-same-app-different-running-environments:
在不同运行环境中运行相同的应用程序
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+19 -4
View File
@@ -136,18 +136,33 @@ class IdfLocalPlugin:
return False
@staticmethod
def _is_linux_target_run(config: Config) -> bool:
target = config.getoption('target')
if not target:
return False
if isinstance(target, str):
targets = [_t.strip() for _t in target.split(',')]
else:
targets = [str(_t).strip() for _t in target]
return 'linux' in targets
@pytest.hookimpl(trylast=True)
def pytest_generate_tests(self, metafunc: Metafunc) -> None:
if 'embedded_services' not in metafunc.fixturenames:
return
if metafunc.definition.get_closest_marker('qemu') is None:
return
if self._has_parametrized_arg(metafunc, 'embedded_services'):
return
metafunc.parametrize('embedded_services', ['idf,qemu'], indirect=True)
if metafunc.definition.get_closest_marker('qemu') is not None:
metafunc.parametrize('embedded_services', ['idf,qemu'], indirect=True)
return
if self._is_linux_target_run(metafunc.config):
metafunc.parametrize('embedded_services', ['idf'], indirect=True)
@pytest.hookimpl(wrapper=True)
def pytest_collection_modifyitems(self, config: Config, items: list[Function]) -> t.Generator[None, None, None]: