Merge branch 'docs/idf_parametrize' into 'master'

docs(pytest): improve documentation with idf_parametrize use cases

See merge request espressif/esp-idf!43824
This commit is contained in:
Igor Udot
2026-01-12 12:02:07 +08:00
@@ -91,17 +91,28 @@ Getting Started
.. code-block:: python
@pytest.mark.parametrize('target', [
'esp32',
'esp32s2',
], indirect=True)
@idf_parametrize('target', ['esp32', 'esp32s2'], indirect=['target'])
@pytest.mark.generic
def test_hello_world(dut) -> None:
dut.expect('Hello world!')
This is a simple test script that could run with the ESP-IDF getting-started example :example:`get-started/hello_world`.
In this test script, the ``@pytest.mark.parametrize`` decorator is used to parameterize the test case. The ``target`` parameter is a special parameter that indicates the target board type. The ``indirect=True`` argument indicates that this parameter is pre-calculated before other fixtures.
`idf_parametrize` is a wrapper around `pytest.mark.parametrize` that simplifies and extends string-based parameterization for tests. Using `idf_parametrize` makes testing parameters more flexible and easier to maintain.
In this test script, the ``idf_parametrize`` decorator is used to parameterize the test case. The ``target`` parameter is a special parameter that indicates the target board type. The ``indirect=['target']`` argument indicates that this parameter is pre-calculated before other fixtures.
In this example, the target is set to `esp32` and `esp32s2`, so the test will be run on both the ESP32 and the ESP32-S2.
.. note::
If the test case can be run on all targets officially supported by ESP-IDF (call ``idf.py --list-targets`` for more details), you can use the special parameter ``supported_targets`` to apply all of them in one line. We also support ``preview_targets`` and ``all`` as special values (call ``idf.py --list-targets --preview`` for the full list of targets, including preview targets). For example: ``@idf_parametrize('target', ['supported_targets'], indirect=['target'])``
.. note::
If the target should be specified by ``soc_caps``, it is possible to filter them using ``soc_filtered_targets``. For example: ``@idf_parametrize('target', soc_filtered_targets('SOC_ULP_SUPPORTED != 1'), indirect=['target'])``
Next is the environment marker. The ``@pytest.mark.generic`` marker indicates that this test case should run on the generic board type.
@@ -133,11 +144,11 @@ If the test case needs to run all supported targets with these two sdkconfig fil
.. code-block:: python
@pytest.mark.parametrize('target', [
'esp32', # <-- run with esp32 target
'esp32s2', # <-- run with esp32s2 target
], indirect=True)
@pytest.mark.parametrize('config', [ # <-- parameterize the sdkconfig file
@idf_parametrize('target', [
'esp32', # <-- run with esp32 target
'esp32s2' # <-- run with esp32s2 target
], indirect=['target'])
@pytest.mark.parametrize('config', [ # <-- use this marker to specify the sdkconfig file; if you don't use it, it uses ``default`` (built from ``sdkconfig.ci`` or ``sdkconfig.ci.default``); if you use it, it uses the specified ``sdkconfig.ci.<config>`` (e.g. ``sdkconfig.ci.foo``, ``sdkconfig.ci.bar``)
'foo', # <-- run with sdkconfig.ci.foo
'bar', # <-- run with sdkconfig.ci.bar
], indirect=True) # <-- `indirect=True` is required, indicates this param is pre-calculated before other fixtures
@@ -176,14 +187,18 @@ The test case ID is used to identify the test case in the JUnit report.
Same App With Different sdkconfig Files, Different Targets
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
For some test cases, you may need to run the same app with different sdkconfig files. These sdkconfig files supports different targets. We may use ``pytest.param`` to achieve this. Let's use the same folder structure as above.
For some test cases, you may need to run the same app with different sdkconfig files. These sdkconfig files supports different targets. We may use ``idf_parametrize`` to achieve this. Let's use the same folder structure as above.
.. code-block:: python
@pytest.mark.parametrize('config, target', [
pytest.param('foo', 'esp32'),
pytest.param('bar', 'esp32s2'),
], indirect=True)
@idf_parametrize(
'target, config',
[
('esp32', 'foo'),
('esp32s2', 'bar')
],
indirect=['target', 'config']
)
Now this test function would be replicated to 2 test cases (represented as test case IDs):