Skip to content
Scaling & Monitoring

Hardware Test Infrastructure with TofuPilot

Learn how to build scalable hardware test infrastructure using TofuPilot as the data backbone for test stations, instruments, and automation.

JJulien Buteau
advanced12 min readMarch 14, 2026

Hardware Test Infrastructure with TofuPilot

Test infrastructure is everything between the engineer's test script and the data that drives quality decisions. Instruments, fixtures, stations, software frameworks, data pipelines. TofuPilot sits at the center as the data backbone, connecting your test stations to dashboards, analytics, and traceability.

What Hardware Test Infrastructure Looks Like

A production test setup has multiple layers:

┌────────────────────────────────────────────┐ │ TofuPilot (Cloud) │ │ Dashboards · Analytics · Traceability │ ├────────────────────────────────────────────┤ │ Test Framework Layer │ │ OpenHTF · pytest · Custom Python │ ├────────────────────────────────────────────┤ │ Instrument Layer │ │ DMMs · Oscilloscopes · Power Supplies │ │ DAQs · Spectrum Analyzers · Load Banks │ ├────────────────────────────────────────────┤ │ Fixture Layer │ │ Pogo pin fixtures · Cable harnesses │ │ Pneumatic actuators · Thermal chambers │ ├────────────────────────────────────────────┤ │ DUT (Device Under Test) │ └────────────────────────────────────────────┘

Each layer has its own concerns. TofuPilot handles the top layer: collecting, storing, and analyzing the data that flows up from the test stack.

Station Architecture

A well-designed test station separates concerns:

ComponentResponsibilityTools
Test logicWhat to test and in what orderOpenHTF, pytest, custom Python
Instrument controlCommunicating with test equipmentPyVISA, python-ivi, vendor drivers
Fixture controlEngaging/disengaging the DUTGPIO, serial, pneumatic controllers
Data captureRecording measurementsTofuPilot client
Operator interfaceScan serial, display resultsOpenHTF UI, custom GUI

Minimal Station Setup

minimal_station.py
from tofupilot import TofuPilotClient
import pyvisa

# Instrument layer
rm = pyvisa.ResourceManager()
dmm = rm.open_resource("TCPIP::192.168.1.10::INSTR")
psu = rm.open_resource("TCPIP::192.168.1.11::INSTR")

# Test logic
def run_functional_test(serial_number):
    psu.write("OUTP ON")
    vcc = float(dmm.query("MEAS:VOLT:DC?"))
    current = float(dmm.query("MEAS:CURR:DC?"))
    psu.write("OUTP OFF")

    passed = 3.25 <= vcc <= 3.35 and 30 <= current <= 60

    # Data capture
    client = TofuPilotClient()
    client.create_run(
        procedure_id="BOARD-FUNCTIONAL",
        unit_under_test={"serial_number": serial_number},
        run_passed=passed,
        steps=[{
            "name": "Power Rails",
            "step_type": "measurement",
            "status": 3.25 <= vcc <= 3.35,
            "measurements": [
                {"name": "vcc_3v3", "value": vcc, "unit": "V", "limit_low": 3.25, "limit_high": 3.35},
                {"name": "idle_current_ma", "value": current * 1000, "unit": "mA", "limit_low": 30, "limit_high": 60},
            ],
        }],
    )
    return passed

# Operator interface
while True:
    serial = input("Scan serial (or 'q' to quit): ")
    if serial.lower() == "q":
        break
    result = run_functional_test(serial)
    print(f"{'PASS' if result else 'FAIL'}")

Scaling from One Station to Many

Identical Stations

When you add stations for the same test, keep the test code identical across all stations. Use the same procedure ID. TofuPilot distinguishes stations automatically.

station_config.py
import socket

# Station identification
STATION_ID = socket.gethostname()  # Each station PC has a unique hostname

# Same test code, same procedure, different station
client.create_run(
    procedure_id="BOARD-FUNCTIONAL",
    unit_under_test={"serial_number": serial},
    run_passed=passed,
    steps=steps,
)
# TofuPilot tracks which station ran each test

Different Test Stages

Production flows typically have multiple test stages. Each stage gets its own procedure.

Assembly Line: Station 1-4: ICT (In-Circuit Test) → procedure: "ICT-V2" Station 5-6: Functional Test → procedure: "FUNC-TEST-V3" Station 7: Burn-In → procedure: "BURN-IN-24H" Station 8-10: Final Test → procedure: "FINAL-TEST-V2"

TofuPilot links all test stages for a given serial number, creating a complete manufacturing test history.

Instrument Management

Common Instrument Types

InstrumentWhat it measuresInterface
DMM (Digital Multimeter)Voltage, current, resistanceGPIB, LAN, USB
OscilloscopeWaveforms, timingLAN, USB
Power Supply(Provides power, measures output)GPIB, LAN, USB
DAQ (Data Acquisition)Multi-channel analog/digitalUSB, PCIe
Spectrum AnalyzerFrequency contentGPIB, LAN
Load Bank(Simulates load conditions)Serial, LAN
Environmental ChamberTemperature, humiditySerial, LAN

Instrument Connection Patterns

instrument_pool.py
import pyvisa

class InstrumentPool:
    """Manage instrument connections for a test station."""

    def __init__(self):
        self.rm = pyvisa.ResourceManager()
        self._instruments = {}

    def get(self, name, address):
        if name not in self._instruments:
            self._instruments[name] = self.rm.open_resource(address)
        return self._instruments[name]

    def close_all(self):
        for inst in self._instruments.values():
            inst.close()

# Usage
pool = InstrumentPool()
dmm = pool.get("dmm", "TCPIP::192.168.1.10::INSTR")
psu = pool.get("psu", "TCPIP::192.168.1.11::INSTR")

Infrastructure Monitoring

Your test infrastructure is itself something that needs monitoring. TofuPilot's dashboards reveal infrastructure health:

MetricWhat it indicates
FPY per stationStation hardware health
Cycle time per stationInstrument/fixture performance
Measurement variance per stationFixture contact quality
Uptime per stationReliability of test PC/software

When one station's FPY drops while others stay stable, the problem is the station, not the product. Investigate the fixture, instruments, and cabling.

Infrastructure Best Practices

PracticeWhy
Version your test codeKnow exactly what test ran on each unit
Use the same procedure ID across identical stationsEnables cross-station comparison
Store instrument calibration datesKnow when calibration might affect results
Keep fixtures as simple as possibleFewer moving parts = fewer failure modes
Monitor cycle timeIt's a free health indicator
Separate test logic from instrument driversSwap instruments without rewriting tests
Use IP-based instrument connectionsMore reliable than USB for production

What TofuPilot Handles vs. What You Handle

TofuPilot handlesYou handle
Data storage and indexingTest code and logic
Dashboards and analyticsInstrument drivers
Traceability and searchFixture design and maintenance
Yield calculationsStation hardware setup
Measurement trendingNetwork connectivity
Cross-station comparisonOperator training

TofuPilot is the data layer. You bring the test layer. Together they form a complete test infrastructure.

More Guides

Put this guide into practice