Files
esphome/tests/components
J. Nick Koston bf718a28b9 [noise] Assert the spare key reaches the wire, drop the ESP8266 warning threshold
The gtest now checks that the responder's message carries the slot's
public key and that the next handshake uses a different one, so a
silently refused spare cannot pass. The api refill sites are guarded by
the feature define they use. The ESP8266 blocking threshold change is
left to a separate core change for operations that cannot be shortened.
2026-09-07 16:35:54 +02:00
..
2026-04-06 21:59:05 -10:00
2026-09-01 07:13:36 +10:00
2026-01-29 22:48:16 -05:00
2025-09-26 08:53:21 +12:00
2025-11-23 21:25:24 -06:00

How to write C++ ESPHome unit tests

  1. Locate the folder with your component or create a new one with the same name as the component.
  2. Write the tests. You can add as many .cpp and .h files as you need to organize your tests.

IMPORTANT: wrap all your testing code in a unique namespace to avoid linker collisions when compiling testing binaries that combine many components. By convention, this unique namespace is esphome::component::testing (where "component" is the component under test), for example: esphome::uart::testing.

Platform components

For components that expose to a platform component, create a folder under your component test folder with the platform component name, e.g. binary_sensor and include the relevant .cpp and .h test files there.

Override component code generation for testing

During C++ test builds, to_code is suppressed for every component by default — most components do not need to generate configuration code for a unit test binary.

Manifest overrides

If your component needs to customise code generation behavior for testing — for example to re-enable to_code, supply a lightweight stub, add a test-only dependency, or change any other manifest attribute — create an __init__.py in your component's test directory and define override_manifest:

Top-level component (tests/components/<component>/__init__.py):

from tests.testing_helpers import ComponentManifestOverride


def override_manifest(manifest: ComponentManifestOverride) -> None:
    # Re-enable the component's own to_code (needed when the component must
    # emit C++ setup code that the test binary depends on at link time).
    manifest.enable_codegen()

Or supply a lightweight stub instead of the real to_code:

from tests.testing_helpers import ComponentManifestOverride


def override_manifest(manifest: ComponentManifestOverride) -> None:
    async def to_code_testing(config):
        # Only emit what the C++ tests actually need
        pass

    manifest.to_code = to_code_testing
    manifest.dependencies = manifest.dependencies + ["some_test_only_dep"]

Platform component (tests/components/<component>/<domain>/__init__.py, e.g. tests/components/my_sensor/sensor/__init__.py):

from tests.testing_helpers import ComponentManifestOverride


def override_manifest(manifest: ComponentManifestOverride) -> None:
    manifest.enable_codegen()

override_manifest receives a ComponentManifestOverride that wraps the real manifest. Attribute assignments store an override; reads fall back to the real manifest when no override is present.

Key methods:

Method Effect
manifest.enable_codegen() Remove the to_code suppression, re-enabling code generation
manifest.restore() Clear all overrides, reverting every attribute to the original

The function is called after to_code has already been set to None, so calling enable_codegen() is a deliberate opt-in.

Running component unit tests

(from the repository root)

./script/cpp_unit_test.py component1 component2 ...

The above will compile and run the provided components and their tests.

To run all tests, you can invoke cpp_unit_test.py with the special --all flag:

./script/cpp_unit_test.py --all

To run a specific test suite, you can provide a Google Test filter:

GTEST_FILTER='UART*' ./script/cpp_unit_test.py uart modbus

The process will return 0 for success or nonzero for failure. In case of failure, the errors will be printed out to the console.