Files
esp-matter/examples/unit_test_app/README.md
T
Shubham Patil fe57fa6cf1 ci: add QEMU target to uni-test-app to be able to run in ci
- Add pytest_unit_test_app.py with per-group test functions (each gets
  a fresh QEMU boot to handle the single esp_matter::start() constraint)
- Add build_unit_test_app_qemu and pytest_unit_test_app_qemu CI jobs
- Disable WiFi and use QEMU virtual Ethernet in sdkconfig.defaults
- Register host_test and qemu pytest markers
- Document local QEMU test setup in README
2026-03-25 17:49:40 +05:30

3.5 KiB

ESP Matter Unit Test App

This application runs unit tests for the ESP Matter component using the Unity test framework.

Unity Test Framework

This test app uses the Unity Test Framework suggested by ESP-IDF.

Further reads:

Running the Tests

  1. Build the application:
cd examples/unit_test_app
idf.py build
  1. Flash to device:
idf.py -p <PORT> flash monitor
  1. Run tests: Once flashed, the test menu will appear in the serial monitor. You can:
  • Press Enter to see the list of available tests
  • Enter a test number to run a specific test
  • Enter * to run all tests

Running Tests with QEMU (no hardware needed)

You can run the unit tests locally under QEMU emulation without physical hardware. This is the same method used in CI.

Prerequisites

  • Install QEMU for RISC-V (esp32c3):
python3 -m pip install pytest-embedded-qemu
  • Ensure the QEMU binary (qemu-system-riscv32) is available. Install it via ESP-IDF tools:
$IDF_PATH/tools/idf_tools.py install qemu-riscv32
source $IDF_PATH/export.sh  # re-source to pick up the new tool in PATH

Build and Run

cd examples/unit_test_app
idf.py -DSDKCONFIG_DEFAULTS="sdkconfig.defaults;sdkconfig.defaults.qemu" set-target esp32c3 build

# Run all QEMU test groups (each gets a fresh QEMU reboot)
pytest pytest_unit_test_app.py \
    --target esp32c3 \
    -m qemu \
    --embedded-services idf,qemu \
    --qemu-extra-args="-global driver=timer.esp32c3.timg,property=wdt_disable,value=true"

# Run a single test group
pytest pytest_unit_test_app.py \
    --target esp32c3 \
    -m qemu \
    --embedded-services idf,qemu \
    --qemu-extra-args="-global driver=timer.esp32c3.timg,property=wdt_disable,value=true" \
    -k test_get_val

Why multiple test functions?

Each test file has its own setup_*() function that calls esp_matter::start(), and there is no teardown/stop. Since only one setup can succeed per boot, tests are grouped so each group runs after a fresh QEMU reboot. Each pytest function (eg: test_get_val, test_get_val_type, test_update_report) gets its own QEMU instance.

Extending the Tests

Adding tests to existing component

  1. Create a new .cpp file in components/<component_name>/test/
  2. Add the filename to the source list in components/<component_name>/test/CMakeLists.txt:
list(APPEND srcs_list "your_new_test_file.cpp")
  1. Write the test cases in the new test file.

Adding new component tests

Please refer to components/esp_matter/test directory for comprehensive structure and example.

  • After adding the new component tests, you need to add the component to the TEST_COMPONENTS list in CMakeLists.txt
  • Append the component name to the TEST_COMPONENTS list. For example, if you add a new component called "new_component", you need to add it to the TEST_COMPONENTS list in CMakeLists.txt:
set(TEST_COMPONENTS "esp_matter new_component" CACHE STRING "List of components to test")

For running them in the CI,

  • Add the test group to the pytest_unit_test_app.py file with the appropriate marker and test function name.
@pytest.mark.host_test
@pytest.mark.qemu
@pytest.mark.esp32c3
def test_my_unit_tests(dut: QemuDut) -> None:
    run_group(dut, 'my_test_group')