Skip to main content

chumicro-pytest-device

Pytest plugin that runs your tests in a CircuitPython or MicroPython runtime, on a real board or in a unix-port subprocess.

--target picks where a test runs. The default, device, intercepts collection under any functional_tests/ directory: it stages your library and test source onto the connected board via chumicro-deploy, executes the test in the device runtime, parses the result back, and passes or fails host-side pytest with the on-device outcome. device-unit puts a library's ordinary tests/ suite on the board instead, so the cross-runtime unit tests run against real firmware. unix-port runs that same suite in a MicroPython or CircuitPython unix-port subprocess, which gives you runtime-accurate results with no board plugged in. Device targets read devices.yml and follow the same workspace conventions as the rest of the ChuMicro tooling.


Part of the ChuMicro family: small, focused Python libraries for microcontrollers and laptops. Browse all workbench tools. This is a workbench tool: it runs on your laptop and drives the boards over serial.

Install

pip install chumicro-pytest-device

That brings both ChuMicro dependencies with it: chumicro-deploy (plus its pyserial / mpremote deps) and chumicro-workspace, along with msgpack and cryptography. The plugin auto-registers via the pytest11 entry point, so you don't need a pytest_plugins = [...] line in conftest.py. Native Windows isn't currently supported (the underlying chumicro-deploy raises WindowsNotSupportedError); WSL2 works.

Quick example

A functional test reads like a normal unit test. It just runs on the board:

# libraries/mylib/functional_tests/test_heartbeat.py
import time
from chumicro_timing import Heartbeat
from chumicro_timing.ticks import ticks_ms


def test_heartbeat_fires_on_real_clock() -> None:
    heartbeat = Heartbeat(period_ms=10)
    deadline = time.monotonic() + 1.0
    fires = 0
    while time.monotonic() < deadline:
        if heartbeat.poll(ticks_ms()):
            fires += 1
    assert fires > 50

The libraries/<name>/functional_tests/ layout is what triggers the routing, so put the file there and the plugin takes over from pytest. Run it on every device your devices.yml defaults name:

pytest libraries/mylib/functional_tests --runtime both

The plugin discovers the board, stages libraries/mylib/src/ plus the test, executes on-device, parses the on-device pytest result back, and reports PASS or FAIL through host-side pytest.

With no board attached, the same library's ordinary unit tests run in a unix-port interpreter instead:

pytest libraries/mylib/tests --target unix-port --runtime micropython

What's included

Plugin modules

Module Purpose
chumicro_pytest_device.plugin The pytest plugin entry-point module: collection interception, deploy orchestration, result reporting
chumicro_pytest_device.runtime_config set_runtime_config(), called from a functional_tests/conftest.py, hands the device a config payload staged at /runtime_config.msgpack. Board-side code reads it through the usual chumicro_config.load_runtime_config()
chumicro_pytest_device.features Per-board feature gating. A test file that declares __chumicro_features__ = ("esp32",) is dropped from the plan for any board that doesn't probe as carrying that feature
chumicro_pytest_device.fixtures Host-side fixtures for networking tests: lan (LAN address, free port, wait-until-listening), mosquitto (spawns a broker), tcp_echo / udp_echo / tls_echo (echo servers, TLS with a generated self-signed cert), and host_driver (an HTTP client that fires once the board prints its ready marker)
chumicro_pytest_device.testing Public fakes and builders for testing code that drives the plugin: FakeConfig, FakeSession, hot_path_device, prime_transport_cache, make_prepare_item, make_run_file_item, make_test_item
chumicro_pytest_device.result_parser Parses on-device test output back into TestResult objects
chumicro_pytest_device.pr_summary Renders a Markdown PR-summary block from captured run results; drop it into a CI step
chumicro_pytest_device.backends The execution backends behind --target: the board transport and the unix-port subprocess

Pytest options

Option Effect
--target {device,device-unit,unix-port} Where tests run. device (the default) runs functional_tests/ on a board, device-unit runs libraries/<name>/tests/ on a board, unix-port runs that same suite in a unix-port subprocess
--runtime {micropython,circuitpython,both} Override defaults.ide_runtime
--micropython-device <id> Override defaults.micropython
--circuitpython-device <id> Override defaults.circuitpython
--micropython-binary <path> unix-port only: the MicroPython binary to spawn, ahead of .tools/micropython.path and PATH
--circuitpython-binary <path> unix-port only: the CircuitPython binary to spawn, ahead of .tools/circuitpython.path and PATH
--unix-port-timeout <seconds> unix-port only: per-file wall-clock ceiling; a worker that overruns is killed and the file fails cleanly
--unix-port-heapsize <size> unix-port only: heap ceiling for workers (192K, say). Defaults to the per-runtime budgets in target-runtimes.toml; pass 0 or off for the port's native multi-MB heap
--deploy-mode {ram,flash} Override the per-device deploy mode
--per-file Device unit runs: soft-reset before each test file rather than once per library, so a big module starts on a fresh interpreter. Worth it on a 256 KB board
--pr-summary Append a Markdown summary block to stdout at end of session
--pr-summary-command <text> The command that re-runs the failed tests, included in the summary

Where this fits

Two ChuMicro dependencies, both installed for you. chumicro-deploy is the transport that stages tests on a board. chumicro-workspace supplies the device-orchestration primitives the collection layer dispatches to (transport build, bootstrap runner, library-source walking) and is also what writes the devices.yml this plugin reads. Auto-registers via pytest11.

Companions

Workbench tool Why you'd use it alongside
chumicro-deploy The transport layer the plugin uses for staging. Useful directly when you want to drive a board outside of pytest
chumicro-repl Tail a board's REPL after a deploy, which is where you go next when a functional test surprises you
chumicro-workspace The host CLI for project workspaces. Reads the same devices.yml schema

Contributing

Issues, bug reports, and pull requests are welcome, and so is "I ran it on this board and here's what happened", some of the most useful feedback a hardware project can get. Development happens in the ChuMicro repository, whose contributing guide covers setup and the test workflow.

Find this library

License

MIT

Metadata

Release files for chumicro-pytest-device 0.18.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for chumicro-pytest-device 0.18.0
File Size Uploaded
chumicro_pytest_device-0.18.0.tar.gz 63.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for chumicro-pytest-device 0.18.0
File Interpreter ABI Platform
chumicro_pytest_device-0.18.0-py3-none-any.whl Python 3 none any Details

Total release size: 137.3 kB

Release files / chumicro_pytest_device-0.18.0.tar.gz

Download URL chumicro_pytest_device-0.18.0.tar.gz
Size 63.3 kB
Tags Source
SHA-256 checksum
How to use checksums
41bebf1533d7e0f7176a8832831f3ddd5a24b2d7bb71801880791d61229ded97
BLAKE2b-256 checksum
How to use checksums
568082d8193bdf7c46f68daa86e8cb1d4c7143a9afa30f91010a95cea26e2692
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 17, 2026.

Transparency log

Release files / chumicro_pytest_device-0.18.0-py3-none-any.whl

Download URL chumicro_pytest_device-0.18.0-py3-none-any.whl
Size 74.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3f0437af6251c22b35c91b97dd3908a5ea384e5b4a3357149ff6852322e9748e
BLAKE2b-256 checksum
How to use checksums
3eab1e9f2ac5f54c9388bf0fa4a6fc88de0360986d8cb00265d9947523b9dc82
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 17, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.18.0 This release

2 release files

0.17.8

2 release files

0.17.7

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page