1
0
mirror of https://github.com/esphome/esphome.git synced 2025-06-15 14:56:59 +02:00
2025-05-26 21:31:32 -05:00

2.8 KiB

ESPHome Integration Tests

This directory contains end-to-end integration tests for ESPHome, focusing on testing the complete flow from YAML configuration to running devices with API connections.

Structure

  • conftest.py - Common fixtures and utilities
  • const.py - Constants used throughout the integration tests
  • types.py - Type definitions for fixtures and functions
  • fixtures/ - YAML configuration files for tests
  • test_*.py - Individual test files

How it works

Automatic YAML Loading

The yaml_config fixture automatically loads YAML configurations based on the test name:

  • It looks for a file named after the test function (e.g., test_host_mode_basicfixtures/host_mode_basic.yaml)
  • The fixture file must exist or the test will fail with a clear error message
  • The fixture automatically injects a dynamic port number into the API configuration

Key Fixtures

  • run_compiled - Combines write, compile, and run operations into a single context manager
  • api_client_connected - Creates an API client that automatically connects using ReconnectLogic
  • reserved_tcp_port - Reserves a TCP port by holding the socket open until ESPHome needs it
  • unused_tcp_port - Provides the reserved port number for each test

Writing Tests

The simplest way to write a test is to use the run_compiled and api_client_connected fixtures:

@pytest.mark.asyncio
async def test_my_feature(
    yaml_config: str,
    run_compiled: RunCompiledFunction,
    api_client_connected: APIClientConnectedFactory,
) -> None:
    # Write, compile and run the ESPHome device, then connect to API
    async with run_compiled(yaml_config), api_client_connected() as client:
        # Test your feature using the connected client
        device_info = await client.device_info()
        assert device_info is not None

Creating YAML Fixtures

Create a YAML file in the fixtures/ directory with the same name as your test function (without the test_ prefix):

# fixtures/my_feature.yaml
esphome:
  name: my-test-device
host:
api:  # Port will be automatically injected
logger:
# Add your components here

Running Tests

# Run all integration tests
script/integration_test

# Run a specific test
pytest -vv tests/integration/test_host_mode_basic.py

# Debug compilation errors or see ESPHome output
pytest -s tests/integration/test_host_mode_basic.py

Implementation Details

  • Tests automatically wait for the API port to be available before connecting
  • Process cleanup is handled automatically, with graceful shutdown using SIGINT
  • Each test gets its own temporary directory and unique port
  • Port allocation minimizes race conditions by holding the socket until just before ESPHome starts
  • Output from ESPHome processes is displayed for debugging