Output Callbacks
Enable automatic test report generation in JSON or other formats.
Overview
Tracking tests is crucial for traceability and analysis, especially in production environments. OpenHTF uses output callbacks to automatically generate reports, with a default JSON format that can be customized as needed.
When integrating with TofuPilot, test results synch directly to TofuPilot without local storage, ensuring real-time remote access and reducing the risk of data loss. If needed, you can still configure additional callbacks to export results locally.
JSON
You can enable automatic test result export in the default JSON format.
main.py
from openhtf import Test, PhaseResult
from openhtf.output.callbacks import json_factory
def get_sn(test):
test.test_record.dut_id = 'PCB001'
return PhaseResult.CONTINUE
def main():
test = Test(get_sn)
# Exports results to JSON with pretty-printing
test.add_output_callbacks(json_factory.OutputToJSON("test_result.json", indent=2))
test.execute()
if __name__ == "__main__":
main()
A test_result.json
file is created after execution and saved in the execution directory. The file path can be changed if needed. The general structure of an OpenHTF JSON log is as follows:
dut_id
start_time_millis
end_time_millis
outcome # PASS/FAIL
metadata
└── test_name
└── config
└── ...
phases # Array of test phases executed
└── name
└── outcome # PASS/FAIL
└── result # Phase-specific result details (e.g., CONTINUE)
└── measurements
log_records # Array of log messages
└── message
└── timestamp_millis
station_id
code_info # Details about the test script (name, source code)
TofuPilot integration
The TofuPilot automatically uploads OpenHTF test reports using an output callback.
To integrate TofuPilot, install the open-source client:
pip install tofupilot
Add it to your test like this:
main.py
from openhtf import Test, PhaseResult
from tofupilot.openhtf import TofuPilot
def get_sn(test):
test.test_record.dut_id = 'PCB001'
return PhaseResult.CONTINUE
def main():
test = Test(get_sn)
with TofuPilot(test): # just works™️
test.execute()
if __name__ == '__main__':
main()
Test runs are securely uploaded using your or the test station's API key. They appear right away on the "Runs" page in your workspace. Any import warnings or errors are listed on the "Import Error" page.
The callback generates a default JSON OpenHTF log and attached it to the test run, capturing the full output, including custom fields. You don't need an output callback anymore, except if you want to keep storing local results.
You can learn more on TofuPilot in the documentation.
Learn more in the TofuPilot DocsAdvanced use cases
You can use output callbacks extended features for advanced use cases.
Custom output format
You can implement a custom output format by creating a function to handle the test record and adding it as an output callback if the built-in format doesn’t meet your needs.
main.py
import openhtf as htf
def custom_output_callback(test_record):
with open("./custom_output.txt", "w") as f:
f.write("Custom Output\n")
f.write(f"DUT ID: {test_record.dut_id}\n")
f.write(f"Outcome: {test_record.outcome}\n")
for phase in test_record.phases:
f.write(f"Phase: {phase.name}\n")
def get_sn(test):
test.test_record.dut_id = "PCB001"
return htf.PhaseResult.CONTINUE
def main():
test = htf.Test(get_sn)
test.add_output_callbacks(custom_output_callback)
test.execute()
if __name__ == "__main__":
main()
The output file will then be:
custom_output.txt
Custom Output
DUT ID: PCB001
Outcome: Outcome.PASS
Phase: get_sn