Skip to main content

autohilt

The test engine for autoHILT — automated hardware-in-loop testing for embedded systems.

autoHILT turns a drawing of your test station into pytest fixtures: draw the station (MCUs on their board, debugger, relays, power) on the autoHILT canvas, publish it, and this package brings those components to life as fixtures named after your own drawing — my_mcu, cli, dut_power — in plain, unmodified pytest.

python3 -m venv .venv && source .venv/bin/activate
pip install autohilt
autohilt init            # the first-run wizard: repo, login, config, starter test
pytest --ah-dev          # iterate — results are never recorded

Every test computer carries a built-in greeter endpoint, so the whole loop works before any hardware arrives:

def test_hello(greeter):
    assert greeter.ping().startswith("hello from my-rig")

Plain pytest is a production run — recorded against your workspace — so it insists on a tree it can trace (committed, pushed, credentialed) and names every missing precondition instead of quietly downgrading the run.

Commands

command what it does
autohilt init first-run wizard: set up or connect a test repo, sync, write the starter test and starting libraries
autohilt sync resolve the pinned config, cache its parts list, write autohilt.lock — and say when the drawing has outgrown your tree
autohilt check full local-state report; every ✗ names its fix
autohilt doctor what is true about THIS machine — runs with no repo, no credential and no reachable server; exits non-zero when something is actually broken
autohilt link hold this machine's connection to the server: scheduled runs arrive down it, health is reported on the server's interval, and the station reads online while it runs (--install-service to keep it up across reboots)
autohilt scaffold write starting libraries: per-board product libraries in your company package, per-kind wrapper modules in libraries/autohilt/ (report-only where files exist)
autohilt discover identify what is plugged into THIS machine and auto-write its device map (autohilt.local.toml): matches the bus against the drawing, walks you through anything ambiguous, never writes to a device
autohilt docs print the in-wheel module reference — always the version you are running; --path for agents reading the files directly
autohilt migrate after a rename on the canvas, rewrite your tests to match
autohilt login store a personal API token for a server (browser approval on a terminal)
autohilt enroll give this machine its own station credential (--code for rack machines nobody logs in on)
autohilt unenroll hand this machine's credential back
autohilt git-credential git credential helper autohilt init wires repo-locally — not a command you run

autohilt --version prints the engine version.

The fixture model, in brief

Fixtures are minted in memory from your locked parts list at pytest startup — nothing generated is ever code at rest, and a fixture is named exactly what you named the component on the canvas. Many-instance kinds get one kind-named factory (relay.get("mains"), relay.get(model=RelayModel.NUMATO) — enums, never strings). Boards are composition units: a PCBA fixture carries the transports the drawing wires across its boundary (board.cli, board.power["mains_feed"], board.debug). Roles appear when unambiguous: dut, cli, dut_power.

The lifecycle, in brief

Initialization is collection-driven: only what the selected tests need is brought up, made test-ready, and baselined — power channels driven to the resting state your drawing declares (default_on), then recorded. Every write through the engine is tracked per channel; after every test the restore is targeted — only what the test drifted is driven back — with your own restore() hook running every time. A failed or hung restore poisons the resource and the next test gets a clean refusal, never a silent re-init. At session teardown, on_final_release() runs (system first, then each component) before drivers close. Everything the engine calls is time-bounded (10 s default). The normative contract lives in autohilt docs lifecycle.

Your test tree

tests/  drafts/  fixtures/  credentials/  pytest.ini  requirements.txt
libraries/
  autohilt/        kind wrappers — generic extensions of the engine's classes
  <your company>/  product layer — boards, system.py, subsystems
  third_party/     vendor and community wrappers you pull in

Each fixture comes with a library: the scaffold starts a wrapper class per drawn instance (extending RelayBase, DebuggerBase, PcbaBase, …), you grow it, and the fixture yields your class — with the engine's restore, poison, timeout, and release rules applying to your code identically. The files are yours after the scaffold writes them: never regenerated, never edited; when the drawing grows, missing pieces are created and existing files get paste-ready additions printed instead. autohilt docs tree has the full map.

Module reference

Ships inside the wheel — autohilt docs <topic>: lifecycle, tree, factories, virtual, pcba, relay, usb_serial, debugger, usb_hub, custom, transports, changelog. Each kind topic states its API, restore behavior, timeouts, extension points, what is guaranteed versus not, and its exact failure messages. Agents working in your repo can read the same files straight from autohilt docs --path.

Requirements & platforms

Python 3.9+, pytest 7 or 8. Linux, macOS, Windows, and Raspberry Pi (arm64) are all first-class: the engine and its built-in driver layer (over pyserial) are pure Python, Windows COM ports are handled, and the test suite runs on all three OS families in CI. Hardware drivers bind to each machine's own ports through a gitignored autohilt.local.toml device map — the drawing stays shared; the paths stay local.

The full walkthrough — account to recorded run in about ten minutes, no hardware required — is at autohilt.com; signed-in users find the guides under Documentation in the app.

Release files for autohilt 0.8.0

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

Built distribution (wheel)

Table of built distributions (wheels) for autohilt 0.8.0
File Interpreter ABI Platform
autohilt-0.8.0-py3-none-any.whl Python 3 none any Details

Release files / autohilt-0.8.0-py3-none-any.whl

Download URL autohilt-0.8.0-py3-none-any.whl
Size 277.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
49734700e7258f877541f64597b568b6bb2f8fd31a67110432dedbadc29031f9
BLAKE2b-256 checksum
How to use checksums
ddf8ad62ad610ae55c6ec90fbfdbbcf18004a625166ec08438d857eafdbcae0f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.8

Release history Release notifications | RSS feed

This release

0.8.0 This release

1 release file

0.7.1

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.0.1

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