Skip to content
Getting Started

How to Write a Hardware Test Plan

A hardware test plan defines what to test, when, and how. Learn how to structure a test plan and implement it in Python with TofuPilot.

JJulien Buteau
intermediate9 min readMarch 14, 2026

How to Write a Hardware Test Plan with TofuPilot

A hardware test plan defines what gets tested, at which stage, with what equipment, and against which criteria. Without one, test coverage depends on whoever wrote the last script. This guide walks through structuring a test plan from EVT through production and implementing it in Python with TofuPilot.

What a Test Plan Covers

SectionContent
Product overviewWhat the product does, key specifications
Test stagesWhich tests run at EVT, DVT, PVT, production
Test proceduresStep-by-step instructions per test
Equipment listInstruments, fixtures, software
Pass/fail criteriaMeasurement limits per test
Data requirementsWhat gets recorded, where, retention period
RolesWho writes tests, who runs them, who reviews results

The test plan is a living document. It starts rough in EVT and gets refined through each build stage.

Step 1: Map Requirements to Test Stages

Start with the product requirements and decide when each one gets verified.

RequirementEVTDVTPVTProduction
Output voltage within 5%XXXX
Survives 1m dropX
Operates -20C to 60CXX
Firmware boots in under 2sXXXX
Leakage current below 500uAXX
FPY above 95%XX

Not every requirement needs testing at every stage. EVT focuses on basic functionality. DVT covers environmental and stress. PVT validates the manufacturing process. Production tests run on every unit.

Step 2: Define Test Procedures

Each test procedure becomes an OpenHTF test script. Define the measurements and limits directly in code so the test plan and the implementation stay in sync.

production_test.py
import openhtf as htf
from openhtf.util import units


@htf.measures(
    htf.Measurement("output_voltage_V")
    .in_range(minimum=4.75, maximum=5.25)
    .with_units(units.VOLT),
    htf.Measurement("boot_time_ms")
    .in_range(maximum=2000)
    .with_units(units.MILLISECOND),
    htf.Measurement("leakage_current_uA")
    .in_range(maximum=500)
    .with_units(units.MICROAMPERE),
)
def phase_production_checks(test):
    """Production test: voltage, boot time, safety."""
    test.measurements.output_voltage_V = 5.02
    test.measurements.boot_time_ms = 1350
    test.measurements.leakage_current_uA = 85.0

Step 3: Specify Equipment and Fixtures

Document every instrument in the test plan. This prevents "it works on my bench" problems.

InstrumentModelPurposeCalibration
DMMKeysight 34461AVoltage and currentAnnual
Power supplyRigol DP832DUT powerAnnual
FixtureCustom PCB jig v2.1Pogo pin contactPer shift check
PCAny, Python 3.10+Test executionN/A

Step 4: Set Initial Limits

Start with limits from the datasheet or design spec. Tighten them after DVT data shows the actual distribution.

limit_evolution.py
import openhtf as htf
from openhtf.util import units

# EVT: wide limits, learning the design
evT_voltage = htf.Measurement("voltage_V").in_range(
    minimum=4.5, maximum=5.5
).with_units(units.VOLT)

# DVT: tightened based on EVT data
dvt_voltage = htf.Measurement("voltage_V").in_range(
    minimum=4.7, maximum=5.3,
    marginal_minimum=4.75, marginal_maximum=5.25,
).with_units(units.VOLT)

# Production: final limits with margins
prod_voltage = htf.Measurement("voltage_V").in_range(
    minimum=4.75, maximum=5.25,
    marginal_minimum=4.8, marginal_maximum=5.2,
).with_units(units.VOLT)

Step 5: Connect to TofuPilot

Log every test run to TofuPilot from the start. EVT data informs DVT limits. DVT data informs production limits. This only works if the data is captured consistently.

production_test.py
from tofupilot.openhtf import TofuPilot

test = htf.Test(phase_production_checks)

with TofuPilot(test):
    test.execute(test_start=lambda: input("Scan serial: "))

TofuPilot tracks results across all test stages. Open the Analytics tab to see measurement distributions, yield trends, and failure patterns. This data feeds back into the test plan as you refine limits and add or remove test steps.

Common Mistakes

MistakeFix
Testing everything at every stageMap requirements to specific stages
Limits from the datasheet onlyRefine from actual production data
Test plan in a Word doc, code elsewhereDefine limits in code, keep them in sync
No calibration trackingLog instrument info with each run
Skipping EVT data collectionStart logging from the first prototype

A test plan is not a one-time document. Review it after every build stage and update limits, procedures, and equipment based on what the data shows.

More Guides

Put this guide into practice