Unit Under Test (UUT)
Identify hardware units under test with serial numbers, custom metadata, and sub-unit assemblies for full traceability in TofuPilot.
You can identify each unit under test with serial numbers, part numbers, revision numbers, and batch numbers.
TofuPilot Framework stores unit information in test reports for traceability.
Identify Unit
To ensure UUT is identified during a run, TofuPilot adds an automatic Identify Unit phase. This phase uses default_values when provided and waits for user input of at least serial number and part number.
To skip the interactive phase entirely and use default values automatically, see Auto-Identify.
Auto-Identify
You can skip the Identify Unit phase by setting auto_identify: true. TofuPilot uses default_value fields directly — the run starts immediately without operator input.
unit:
auto_identify: true
serial_number:
default_value: "SN00012345"
part_number:
default_value: "PCB-MAIN-V2"Requires serial_number.default_value and part_number.default_value to be set. Optional fields (revision_number, batch_number, sub_units) use their defaults if provided. See use case in Examples.
With auto_identify: true, the Run Again button is disabled — use Run instead.
Serial Number
You can set a unique identifier for each individual unit.
unit:
serial_number:
default_value: "SN00012345"def identify_unit(unit):
unit.serial_number = "SN00012345"TofuPilot Framework requires a serial number for every test run.
Part Number
You can set the unit type or model number.
unit:
part_number:
default_value: "PCB-MAIN-V2"def set_part(unit):
unit.part_number = "PCB-MAIN-V2"TofuPilot Framework requires a part number for every test run.
Revision Number
You can optionally set the revision of the unit.
unit:
revision_number:
default_value: "Rev C"def set_revision(unit):
unit.revision_number = "Rev C"TofuPilot Framework stores revision numbers in reports and syncs them to your Dashboard.
Batch Number
You can optionally set the production batch or lot number.
unit:
batch_number:
default_value: "BATCH-2024-001"def set_batch(unit):
unit.batch_number = "BATCH-2024-001"TofuPilot Framework stores batch numbers in reports and syncs them to your Dashboard.
Sub-units
You can track component serial numbers linked to the main unit under test.
unit:
sub_units:
- label: "Battery"
serial_number:
placeholder: "Scan battery"
pattern: "^BAT-.*"
- label: "Motor"
serial_number:
placeholder: "Scan motor"def test_phase(unit):
# Dict access (case-insensitive)
battery_sn = unit.sub_units["battery"]
motor_sn = unit.sub_units["motor"]
# Attribute access (lowercase)
battery_sn = unit.sub_units.battery
motor_sn = unit.sub_units.motor
# Iterate all sub-units (keys are lowercase)
for key, serial in unit.sub_units.items():
print(f"{key}: {serial}") # "battery: BAT-...", "motor: MOT-..."TofuPilot Framework collects sub-unit serial numbers during the Identify Unit phase and makes them available in Python as a dictionary.
Each sub-unit requires a label and optionally a serial_number configuration. The serial_number field supports the same validation options as the main unit fields — see Validation for all available options.
The sub-units must already exist as Units in TofuPilot when creating the Run. Ensure each sub-unit has been tested and registered before referencing it in the assembly. If a sub-unit doesn't exist, the report will be saved locally but won't sync to your Dashboard.
Validation
You can configure validation rules for unit fields.
unit:
serial_number:
min_length: 8
max_length: 20
pattern: "^SN\\d{8}$"
part_number:
max_length: 50
pattern: "^PCB-[A-Z]+-V\\d+$"
revision_number:
pattern: "^Rev [A-Z]$"
batch_number:
pattern: "^BATCH-\\d{4}-\\d{3}$"TofuPilot Framework trims whitespace, validates length constraints, and checks regex patterns before test execution.
You can use these validation options for each unit field:
| Option | Type | Description |
|---|---|---|
default_value | string | Pre-filled value in operator input form |
placeholder | string | Placeholder text shown in input field |
min_length | integer | Minimum character length (after trimming) |
max_length | integer | Maximum character length (after trimming) |
pattern | string | Regex pattern for validation |
Python
You can set unit information from any phase function by adding unit as a parameter.
def identify_unit(unit, device):
# Read serial number from device registry
serial = device.read_register(0x1000)
unit.serial_number = serial
# Derive part number from serial prefix
if serial.startswith("IX"):
unit.part_number = "IXRouter-V3"
elif serial.startswith("SN"):
unit.part_number = "PCB-MAIN-V2"TofuPilot Framework passes the unit object to your phase function via dependency injection when you add it as a parameter.
Examples
Unit with Validation
A procedure with default values, placeholders, and regex patterns on unit fields — the operator fills in the Identify Unit form before testing starts.
name: Battery Functional Test
version: 1.0.0
unit:
serial_number:
placeholder: "Enter serial number"
pattern: "^SN\\d{8}$"
part_number:
default_value: "PCB-MAIN-V2"
revision_number:
default_value: "Rev C"
batch_number:
placeholder: "Enter batch number"
min_length: 5
max_length: 20
main:
- key: check_voltage
name: Check Voltage
python: phases.check_voltage
measurements:
- key: voltage
name: Battery Voltage
type: numeric
unit: V
limits:
low: 3.2
high: 4.2def check_voltage(m, multimeter):
m.voltage = multimeter.measure_dc_voltage()Auto-Identified with Barcode Scanner
A procedure that uses auto_identify with a Python phase that reads the serial number from a connected barcode scanner — typical for automated test stations where units are scanned programmatically.
name: Battery Functional Test
version: 1.0.0
plugs:
- key: barcode_scanner
name: Barcode Scanner
python: plugs.barcode_scanner:BarcodeScanner
unit:
auto_identify: true
serial_number:
default_value: "PENDING"
part_number:
default_value: "PCB-MAIN-V2"
main:
- key: scan_unit
name: Scan Unit
python: phases.scan_unit
- key: check_voltage
name: Check Voltage
python: phases.check_voltage
measurements:
- key: voltage
name: Battery Voltage
type: numeric
unit: V
limits:
low: 3.2
high: 4.2import serial
class BarcodeScanner:
def __init__(self):
self.connection = serial.Serial("/dev/ttyUSB0", baudrate=9600)
def scan(self):
return self.connection.readline().decode().strip()def scan_unit(unit, barcode_scanner):
unit.serial_number = barcode_scanner.scan()def check_voltage(m, multimeter):
m.voltage = multimeter.measure_dc_voltage()How is this guide?