Skip to main content

Hardware test platform for the AI-assisted era

Project description

Litmus

PyPI Python License CI

Python hardware test platform for electronics validation and production.

Litmus is a hardware test platform for test engineers. The main path is plain pytest — you write ordinary pytest functions and Litmus handles the parts that aren't your test: instrument setup, limit checking, results storage, operator UI. Already running OpenHTF, LabVIEW, TestStand, or custom scripts? A results API records runs from any source, so you can adopt Litmus without rewriting your suite. Tests run against mock instruments out of the box — start without hardware, move to a real bench later.

Get started in under a minute

pip install litmus-test
litmus init my_project --starter && cd my_project
pytest

The starter's test passes against mock instruments. The tutorial walks you from this starter project to a production-ready suite, one concept at a time.

Or explore it without installing: Open in GitHub Codespaces — a browser sandbox with mock instruments, the UI, analytics, and AI. Real instrument control needs a local install.

What --starter generated

# stations/starter_station.yaml — mock instruments for getting started
id: starter_station
name: Starter Station
instruments:
  psu:
    type: psu
    resource: "TCPIP::192.168.1.100::INSTR"
    mock: true
    mock_config:
      set_voltage: null
      enable_output: null
      measure_voltage: 5.0
  dmm:
    type: dmm
    resource: "TCPIP::192.168.1.101::INSTR"
    mock: true
    mock_config:
      measure_dc_voltage: 3.3
# tests/test_example.py
def test_output_voltage(context, psu, dmm, verify):
    """Verify output voltage is within spec."""
    vin = context.get_param("vin", 5.0)
    psu.set_voltage(vin)
    psu.enable_output()
    verify("output_voltage", float(dmm.measure_dc_voltage()))

psu and dmm come from your station config. context and verify come from the Litmus plugin for pytest. No conftest.py needed.

Learning path

After the starter project runs, the recommended progression:

  1. Tutorial — Twelve short chapters from a first test through continuous production monitoring. Read in order; each builds on the last.
  2. Examples — A seven-step learning chain (01-vanilla07-profiles), each a diff off the last, plus standalone data-tier examples. Clone, run, modify.
  3. Concepts — Reference for the vocabulary: station, fixture, part, sequence, capability, vector.

When you're ready to leave mocks behind, Real Instruments covers the transition.

litmus discover                 # scan for real instruments
litmus station init             # assign roles interactively
litmus new-test output_voltage  # scaffold a new test
pytest --mock-instruments       # develop without hardware
pytest --station=my_bench       # run against real instruments
litmus runs                     # see results

Design principles

  1. Built for hardware test, end to end — Every measurement carries its limits, signal path, and the instrument that took it (with serial, cal date, firmware) — a field failure traces back to the exact bench state. Yield, Cpk, Pareto, retest, and time-loss analytics ship built in. Industry exporters (STDF, HDF5, TDMS, MDF4) bridge your reporting pipeline.
  2. Everything is a file you can version — Limits, stations, parts, fixtures, sequences, results — all files. Edit them in your text editor, diff them in git, review changes like code. A project moves between machines as a folder.
  3. Open and extensible, no lock-in — Pytest tests (plus its plugin ecosystem), PyVISA for any VISA-compatible instrument, YAML config, Parquet results that any data tool can read. All open source. If you change your mind about Litmus, your tests, configs, and results travel with you.
  4. AI-ready, never AI-dependent — Built on technology AI assistants know deeply (pytest, YAML, Python, markdown). MCP tools expose every Litmus operation; JSON Schemas act as guardrails for any config the AI writes. The platform itself never calls out to an AI model.
  5. Starts simple, grows with you — After install, pytest passes on any machine — no server, no account, no hardware needed to begin. Add what you need as you need it: measurement logging, station config, part specs, capability matching — in whatever order fits your project.

Project layout

parts/*.yaml           → Part characteristics and tolerances
catalog/*.yaml            → Instrument capabilities and accuracy
stations/*.yaml           → Which instruments are at this bench
fixtures/*.yaml           → How UUT pins connect to instruments
sequences/*.yaml          → What to test and in what order
tests/*.py                → Test code
data/*.parquet            → Measurements (run output, gitignored)

Your specs, stations, limits, and tests are all files — versioned in git. You get diffs on limit changes, code review on test sequences, and a history of every config change. (Run results land in data/, which stays out of git.)

verify() vs plain assert

Plain assert for pass/fail checks:

def test_power_on(psu):
    psu.enable_output()
    assert psu.get_status() == "ON"

verify() when you need recorded measurements:

def test_rail_3v3(context, psu, dmm, verify):
    psu.set_voltage(context.get_param("vin"))
    psu.enable_output()
    verify("rail_3v3", float(dmm.measure_dc_voltage()))
    # → limit-checked against the YAML next to the test or your part spec
    # → logged to your results file with the instrument that took it

Sweeps, limits, mocks, and retries are all controlled from a YAML file alongside the test — no extra wrapper code in your test function.

Capability matching

"We're bringing up a new board — do we have the instruments to test it?"

litmus_match(requirements=[
    {"function": "dc_voltage", "direction": "input", "range_max": 50, "unit": "V"},
    {"function": "dc_current", "direction": "output", "range_max": 3, "unit": "A"},
])
# → Keysight 34461A covers dc_voltage input
# → Keysight E36312A covers dc_current output

Litmus exposes this as an MCP tool, so an AI assistant can answer it directly from your catalog.

AI integration

Connect Claude Code or any AI assistant to your test system. Optional, not required.

litmus setup claude-code    # Add to Claude Code
litmus mcp serve            # Any MCP-compatible AI tool

An AI assistant can read a datasheet, extract specs, recommend instruments, generate configs, and scaffold tests for you to review.

CLI

litmus init <name> [--starter]  # New project (--starter for full example)
litmus discover [--visa]        # Scan for instruments
litmus station init             # Interactive station setup
litmus new-test <name>          # Scaffold a test file
litmus serve [--reload]         # Operator UI
litmus runs / show <id>         # Results
litmus instrument list / show   # Instrument inventory
litmus mcp serve                # MCP server
litmus setup <tool>             # AI tool integration

Docs

License

Apache 2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

litmus_test-0.3.1.tar.gz (3.5 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

litmus_test-0.3.1-py3-none-any.whl (3.0 MB view details)

Uploaded Python 3

File details

Details for the file litmus_test-0.3.1.tar.gz.

File metadata

  • Download URL: litmus_test-0.3.1.tar.gz
  • Upload date:
  • Size: 3.5 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for litmus_test-0.3.1.tar.gz
Algorithm Hash digest
SHA256 6aa5e69aefc7d7e399e07261cc0627ef0f58e38d91355f96d0f55521364a064e
MD5 e0d389afae48f0a7efc7e6a3a8909324
BLAKE2b-256 5368249b991e9d3b7a4d94cad27dfb558e0aead23f82c5e83a9038366b903a8d

See more details on using hashes here.

Provenance

The following attestation bundles were made for litmus_test-0.3.1.tar.gz:

Publisher: release.yml on pragmatest-dev/litmus

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file litmus_test-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: litmus_test-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 3.0 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for litmus_test-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 9401acf7ce66d135678997ccede67e6b0dcbc3d1044eb785e4609b662ded2c7d
MD5 6c1267f141c949251f3c8f6ea33d2363
BLAKE2b-256 2c483a181878251664412df548679db0a28b3fbc099d91eacab28d691e8e98f4

See more details on using hashes here.

Provenance

The following attestation bundles were made for litmus_test-0.3.1-py3-none-any.whl:

Publisher: release.yml on pragmatest-dev/litmus

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page