Skip to content
Test Types & Methods

What Is Functional Testing for Hardware

Functional testing validates that hardware behaves correctly as a complete system. Learn the difference from ICT, how to build functional tests in Python.

JJulien Buteau
beginner8 min readMarch 14, 2026

What Is Functional Testing for Hardware with TofuPilot

Functional testing validates that a hardware product behaves correctly as a complete system. Unlike in-circuit testing (ICT), which checks individual components and solder joints, functional testing treats the board or product as a black box and verifies its inputs and outputs. This guide covers what functional testing involves, how it compares to other test methods, and how to build functional tests in Python with TofuPilot.

Functional Testing vs Other Methods

MethodWhat It TestsHowFinds
ICT (In-Circuit Test)Individual componentsBed-of-nails fixture, poweredOpens, shorts, wrong values
Flying probeIndividual componentsMoving probes, unpowered/poweredSame as ICT, no fixture needed
Functional test (FCT)System behaviorPowered, exercised through interfacesIntegration bugs, firmware issues, performance
Boundary scan (JTAG)Digital IC connectionsThrough JTAG chainDigital connectivity

ICT tells you the right parts are soldered correctly. Functional testing tells you the product actually works.

What Functional Tests Cover

A functional test exercises the product through its real interfaces: power input, communication ports, sensors, actuators, and user controls.

CategoryExample Checks
PowerStartup current, voltage regulation, power sequencing
CommunicationUART, SPI, I2C, CAN, Ethernet respond correctly
AnalogADC readings match known inputs within tolerance
Digital I/OGPIO states match expected logic levels
ActuatorsMotors, relays, LEDs respond to commands
FirmwareVersion check, self-test pass, boot time
RF (if applicable)Transmit power, receive sensitivity, frequency accuracy

Prerequisites

  • Python 3.10+
  • OpenHTF installed (pip install openhtf)
  • TofuPilot Python SDK installed (pip install tofupilot)

Step 1: Define Functional Test Phases

Each functional check becomes an OpenHTF phase. Group related checks together but keep phases focused enough that a failure points to a specific subsystem.

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


@htf.measures(
    htf.Measurement("boot_time_ms")
    .in_range(maximum=2000)
    .with_units(units.MILLISECOND),
    htf.Measurement("firmware_version").equals("1.3.0"),
)
def phase_power_and_boot(test):
    """Power up the DUT and verify boot sequence."""
    test.measurements.boot_time_ms = 1240
    test.measurements.firmware_version = "1.3.0"


@htf.measures(
    htf.Measurement("uart_loopback").equals("PASS"),
    htf.Measurement("i2c_sensor_id").equals("0x68"),
)
def phase_communication(test):
    """Verify communication interfaces respond correctly."""
    test.measurements.uart_loopback = "PASS"
    test.measurements.i2c_sensor_id = "0x68"


@htf.measures(
    htf.Measurement("adc_channel_0_V")
    .in_range(minimum=2.45, maximum=2.55)
    .with_units(units.VOLT),
    htf.Measurement("adc_channel_1_V")
    .in_range(minimum=1.60, maximum=1.70)
    .with_units(units.VOLT),
)
def phase_analog_inputs(test):
    """Apply known voltages and verify ADC readings."""
    test.measurements.adc_channel_0_V = 2.50
    test.measurements.adc_channel_1_V = 1.65

Step 2: Run and Log Results

Connect the test to TofuPilot. Every unit's functional test result uploads automatically with full measurement detail.

functional_test.py
from tofupilot.openhtf import TofuPilot

test = htf.Test(
    phase_power_and_boot,
    phase_communication,
    phase_analog_inputs,
)

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

Step 3: Track Results in TofuPilot

TofuPilot tracks functional test results automatically. Open the Analytics tab to see:

  • First pass yield for each functional test procedure
  • Failure Pareto showing which phases fail most often (power? communication? analog?)
  • Measurement distributions with limit overlays to spot tightening trends
  • Station comparison if you run the same test on multiple stations

This data helps you decide where to invest. If 80% of functional test failures come from one phase, that's where to focus your design or process improvement.

When to Use Functional Testing

ScenarioUse FCT?
PCBA with firmwareYes, after SMT and programming
Simple passive boardNo, ICT or flying probe is sufficient
Assembled product with sensors/actuatorsYes, as EOL test
Safety-critical productYes, with documented test procedure
High-volume, low-complexityMaybe, depends on field failure cost

Functional testing adds cycle time, but it catches the integration failures that ICT cannot. For products with firmware, communication interfaces, or analog circuits, it's the test stage that matters most.

More Guides

Put this guide into practice