A pytest plugin to test Arduino projects using pytest-embedded and arduino-cli
Project description
pytest-embedded-arduino-cli
A pytest plugin to test Arduino projects using pytest-embedded and arduino-cli.
Overview
pytest-embedded-arduino-cli is a small plugin that keeps pytest-embedded's generic DUT / serial / expect flow and replaces Arduino-specific build and upload with arduino-cli.
This package does not depend on pytest-embedded-arduino. It is intended to stay generic enough to work well for Arduino projects beyond ESP32-specific assumptions.
Design
- Build with
arduino-cli compile - Upload with
arduino-cli upload - Use
pytest-embeddedas the runtime foundation - Avoid
EspSerialand ESP-specific flashing services - Resolve sketch settings from
sketch.yamland--profile - Treat the test file directory as the sketch directory
Setup
uv init
uv add pytest-embedded-arduino-cli
uv sync
Runtime dependencies include:
pytestpytest-embeddedpytest-embedded-serialPyYAML
Requirements
arduino-cliavailable inPATH- Installed Arduino board core(s)
- A serial port accessible from the host when running hardware tests
Project Layout
The expected layout is one sketch directory per test app.
tests/
my_app/
sketch.yaml
my_app.ino
test_my_app.py
When pytest runs a specific .py file, this plugin treats that file's directory as the sketch directory. Build settings are resolved from the nearest sketch.yaml.
Usage
Build, upload, and run tests:
uv run pytest tests/my_app --port /dev/ttyACM0
Select an Arduino CLI profile from sketch.yaml:
uv run pytest tests/my_app --profile esp32s3 --port /dev/ttyACM0
Build only:
uv run pytest tests/my_app --run-mode=build
Upload and test against an already-built image:
uv run pytest tests/my_app --run-mode=test --port /dev/ttyACM0
--run-mode=test skips compile, reuses the existing build output, uploads it, and then runs the test.
Run this package's own tests:
uv run pytest
Main Options
--run-mode=all|build|test--profile
Use pytest-embedded standard options for runtime control, such as:
--port--flash-port--baud--embedded-services
pytest-embedded-serial is installed as a normal dependency so hardware tests can use the serial service without extra package installation.
If --embedded-services is not specified, this plugin enables serial by default.
For profile-specific serial ports, the plugin resolves ports in this order:
--flash-port--portTEST_SERIAL_PORT_<PROFILE>TEST_SERIAL_PORT
Example:
export TEST_SERIAL_PORT_ESP32S3=/dev/ttyUSB1
uv run pytest tests/my_app --profile esp32s3
If --profile is omitted, the plugin uses the resolved profile from sketch.yaml, including default_profile.
For compile-time defines, place a build_config.toml in the sketch directory:
[defines]
TEST_WIFI_SSID = "WIFI_SSID"
TEST_WIFI_PASSWORD = "WIFI_PASSWORD"
Here, the left side is the environment variable name and the right side is the C/C++ define name.
For example, TEST_WIFI_SSID becomes -DWIFI_SSID="..." at compile time.
Set values before running pytest:
export TEST_WIFI_SSID=my-ssid
export TEST_WIFI_PASSWORD=my-password
uv run pytest tests/my_app
If an environment variable is missing, the plugin still passes the define with an empty string value. This allows the test or sketch code to decide how to handle missing settings.
For command visibility, follow pytest's standard verbosity:
-vshows thearduino-cli compile/arduino-cli uploadcommand line-vvalso shows execution context such ascwd,sketch_dir,build_path,profile, andport
Example
def test_hello(dut):
dut.expect_exact("hello from arduino")
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("hello from arduino");
}
void loop() {}
Additional sample:
examples/wifi- Connects to Wi-Fi on ESP32/ESP32-S3
- Includes
unoas a skip example for a non-Wi-Fi profile - Expects
TEST_WIFI_SSIDandTEST_WIFI_PASSWORD - Verifies that the board prints
WIFI_OK <ip-address>
Warnings
You may see PytestExperimentalApiWarning: record_xml_attribute is an experimental feature.
This warning comes from pytest-embedded, not from this plugin. It is usually safe to ignore.
If you want to suppress it in your project, add a warning filter in pytest.ini, pyproject.toml, or a local config such as examples/pytest.ini.
What This Plugin Does Not Try To Be
- A drop-in replacement for
pytest-embedded-arduino - An ESP-specific flashing layer
- A board auto-discovery tool
Future Extensions
- Board-family-specific upload strategies
- Smarter artifact discovery
- Serial reset / monitor helpers
- Multi-device support
- Optional
fqbnor sketch path overrides
Release
This repository uses GitHub Actions for releases.
Before triggering a release:
- Update the
## Unreleasedsection inCHANGELOG.md - Make sure
uv run pytest testspasses locally if needed
Release flow:
- Open GitHub Actions
- Run the
Releaseworkflow manually - Enter the release version such as
0.1.0 - Choose whether to publish to PyPI
The workflow will:
- Update versions in
pyproject.tomlandsrc/pytest_embedded_arduino_cli/__init__.py - Move
CHANGELOG.mdunreleased entries into## <version> - Run tests and build the package
- Commit the release changes and create tag
v<version> - Create a GitHub Release
- Publish to PyPI when enabled
PyPI publishing is configured for Trusted Publishing via GitHub Actions.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pytest_embedded_arduino_cli-1.0.0.tar.gz.
File metadata
- Download URL: pytest_embedded_arduino_cli-1.0.0.tar.gz
- Upload date:
- Size: 21.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7c4048dfc6131f9ee8d5cbcb0e0b7e6076658c36a9634ab247c58dc0b0e6f695
|
|
| MD5 |
21e7f00bb3c635264db85016cdb01d23
|
|
| BLAKE2b-256 |
e39c9b52a8db026ddea488502cea935aae7a0f150aad7cebf180eb1f42eb68db
|
Provenance
The following attestation bundles were made for pytest_embedded_arduino_cli-1.0.0.tar.gz:
Publisher:
release.yml on tanakamasayuki/pytest-embedded-arduino-cli
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pytest_embedded_arduino_cli-1.0.0.tar.gz -
Subject digest:
7c4048dfc6131f9ee8d5cbcb0e0b7e6076658c36a9634ab247c58dc0b0e6f695 - Sigstore transparency entry: 1347962886
- Sigstore integration time:
-
Permalink:
tanakamasayuki/pytest-embedded-arduino-cli@0b73898867e08eb376d42e0683a9763df0a65c6e -
Branch / Tag:
refs/heads/main - Owner: https://github.com/tanakamasayuki
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0b73898867e08eb376d42e0683a9763df0a65c6e -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file pytest_embedded_arduino_cli-1.0.0-py3-none-any.whl.
File metadata
- Download URL: pytest_embedded_arduino_cli-1.0.0-py3-none-any.whl
- Upload date:
- Size: 10.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
096bedfbe110019aec136d6c6d408b3e0790ddaef1211951012963b65a97d06f
|
|
| MD5 |
749e142f2064c23ecdfcabf5410d5b2d
|
|
| BLAKE2b-256 |
49ab4c496886ecd48b7d878628ad398e5b6eb22072e27a1aa34b690494311849
|
Provenance
The following attestation bundles were made for pytest_embedded_arduino_cli-1.0.0-py3-none-any.whl:
Publisher:
release.yml on tanakamasayuki/pytest-embedded-arduino-cli
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pytest_embedded_arduino_cli-1.0.0-py3-none-any.whl -
Subject digest:
096bedfbe110019aec136d6c6d408b3e0790ddaef1211951012963b65a97d06f - Sigstore transparency entry: 1347962891
- Sigstore integration time:
-
Permalink:
tanakamasayuki/pytest-embedded-arduino-cli@0b73898867e08eb376d42e0683a9763df0a65c6e -
Branch / Tag:
refs/heads/main - Owner: https://github.com/tanakamasayuki
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0b73898867e08eb376d42e0683a9763df0a65c6e -
Trigger Event:
workflow_dispatch
-
Statement type: