Decorators
Learn how to use OpenHTF decorators to enhance your test phases with measurements, hardware plugins, and execution configuration.
Last updated · Verified with OpenHTF 1.6.1
Learn how to use OpenHTF decorators to enhance your test phases.
Decorators stack on a phase function. PhaseOptions configures execution, measures declares the measurements the phase records, and plug injects the hardware plug the phase receives as an argument.
- @htf.PhaseOptions(timeout_s=30)execution: 30 s timeout
- @htf.measures(Measurement("voltage"))
- @htf.plug(dmm=MultimeterPlug)
- def phase_voltage(test, dmm)
Python decorators modify function behavior without changing their code. In OpenHTF, decorators add functionality to test phases like declaring measurements, injecting hardware plugins, and configuring execution. They're applied using the @ symbol before function definitions:
@decorator_function
def my_function():
passKey decorators
OpenHTF ships these decorators:
1. Declaring measurements
The @htf.measures decorator is used to declare what measurements a phase will capture and validate:
@htf.measures(
htf.Measurement("temperature")
.in_range(0, 100)
.with_units(units.DEGREE_CELSIUS)
.with_precision(1)
)
def measure_temperature(test):
test.measurements.temperature = 25.52. Hardware plugin injection
The @htf.plug decorator injects hardware or software plugins into your test phases:
@htf.plug(multimeter=MultimeterPlug)
def test_voltage(test, multimeter):
voltage = multimeter.measure_voltage()
test.measurements.voltage = voltage3. Phase configuration
The @htf.PhaseOptions decorator configures how a phase should execute:
@htf.PhaseOptions(timeout_s=10, repeat_limit=3)
def retry_phase(test):
# Phase will timeout after 10 seconds and can retry up to 3 times
return htf.PhaseResult.CONTINUECombining
You can stack decorators on one phase:
@htf.measures(
htf.Measurement("firmware_version").equals("1.2.4"),
htf.Measurement("connection_status").equals(True)
)
@htf.plug(device=DeviceConnection)
@htf.PhaseOptions(timeout_s=30)
def verify_device_connection(test, device):
test.measurements.connection_status = device.is_connected()
test.measurements.firmware_version = device.get_firmware_version()Enhanced example
Let's enhance our first test to demonstrate decorator usage:
import openhtf as htf
@htf.measures(
htf.Measurement("greeting_message").with_validator(
lambda msg: "Hello" in msg
)
)
@htf.PhaseOptions(timeout_s=5)
def hello_world_with_measurement(test):
message = "Hello world!"
print(message)
test.measurements.greeting_message = message
def main():
test = htf.Test(hello_world_with_measurement)
test.execute(lambda: "SN1234")
if __name__ == '__main__':
main()This version adds:
- Measurement validation using
@htf.measures - Phase timeout using
@htf.PhaseOptions - Custom validation with lambda functions
Dynamic configuration
Python decorators are callables, which means you can apply them at runtime instead of with the @ syntax: htf.measures(m)(phase) returns the decorated phase. This is how you build phases whose limits come from a config file, a product database or operator input.
import openhtf as htf
def phase_resistance_test(test):
test.measurements.resistance = 10.5
def main():
limits = {"min": 5, "max": 17} # e.g. loaded from YAML per part number
measurement = htf.Measurement("resistance").in_range(limits["min"], limits["max"])
configured_phase = htf.PhaseOptions(timeout_s=10)(
htf.measures(measurement)(phase_resistance_test)
)
test = htf.Test(configured_phase)
test.execute(lambda: "SN1234")
if __name__ == "__main__":
main()The same works for @htf.plug. A worked measurement example is under Callable decorators.
Other decorators
Beyond the three above, OpenHTF exposes:
@htf.diagnose(*diagnosers)Attach phase diagnosers that classify the phase's results.
@htf.monitors(name, func, units=, poll_interval_ms=)Sample a value in a background thread while the phase runs — see Monitors.
@CONF.save_and_restore(**overrides)Temporarily override configuration values for one phase.
@CONF.inject_positional_argsFill a plug's __init__ arguments from configuration keys of the same name.
phase.with_args(**kwargs) / phase.with_plugs(**plugs)Not decorators but the same idea: return a copy of a phase with template arguments or plug placeholders filled in. Used in the with_plugs example.
Related
Multi-station
Run OpenHTF on several test stations and see them from one place — the built-in dashboard_server, multicast station discovery, station_server history, configuration per station, and where the built-in tooling stops.
Overview
Runnable OpenHTF example scripts, one per feature — hello world, measurements, plugs, phase groups, branches, checkpoints, repeat, stop on first failure, custom JSON output, Operator UI — each explained line by line.