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.
- Homepage: https://autohilt.com
- Contact: hello@autohilt.com
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)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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
|