Phases
Break down your test into distinct steps that run Python, executables, and operator UI.
A phase represents a single step within your test procedure.
Runtime
Each phase can run Python scripts, execute a command, and/or display operator UI prompts. Find usage and example for Python, shell commands and operator UI.
Name
You can create a new phase by adding it to the main list.
main:
- name: Power On TestTofuPilot will automatically trim whitespace and enforce a 100 character limit.
Description
You can add an optional description to explain what the phase does.
main:
- name: Power On Test
description: "Verify 5V power rail is within specification"TofuPilot will enforce a 1,000 character limit on descriptions.
Key
You can define a key for referencing this phase in your Python phases or YAML procedure.
main:
- name: Power On Test
description: "Verify 5V power rail is within specification"
key: power_on_testIf not specified, TofuPilot auto-generates a key from the phase name. Keys must be valid Python identifiers: start with a letter or underscore, followed by letters, numbers, or underscores.
Outcome
Your phase can end with one of these outcomes:
| Outcome | If |
|---|---|
| Error | Unhandled exception thrown |
| Skip | Called phase.skip() or phase skipped by framework |
| Timeout | Phase exceeded timeout limit |
| Stop | Called phase.stop(), Error outcome from another phase or run stopped by user in UI |
| Fail | Called phase.fail(), phase.retry() exceeding retry limit, or measurements invalid |
| Pass | All measurements valid |
Outcome Control
You can control phase outcomes by calling methods on the phase parameter in your python function :
| Method | Description |
|---|---|
phase.fail() | Mark phase as fail and exit immediately |
phase.skip() | Skip this phase |
phase.retry() | Retry this phase (see Retry) |
phase.stop() | Stop the entire test run |
For example, you can skip a phase when a precondition is not met:
def advanced_calibration(phase, device):
if not device.supports_advanced_mode():
phase.skip()
# Phase continues if not skippedOutcome Resolution
TofuPilot evaluates outcomes in priority order (first match wins):
After the outcome is determined, TofuPilot moves to the Next Action.
Example
Let's create a battery test with 2 phases:
- Test power that succeeds
- Test capacity that fails
We'll create the procedure file and the Python modules:
We'll define the phases and reference the modules:
def test_power(phase, battery):
if not battery.check_voltage():
phase.fail()
# Implicit passdef test_capacity(phase, battery):
if not battery.verify_capacity():
phase.fail()
# Implicit passmain:
- name: Test Power
python: phases.test_power
- name: Test Capacity
python: phases.test_capacityTofuPilot executes both phases in parallel:
Next Action
After determining the phase outcome, TofuPilot decides the next action. You can customize the default behavior at procedure level or at phase level.
Actions
| Action | Description |
|---|---|
continue | Continue to next phase |
retry | Retry this phase (see Retry) |
skip | Skip to next phase |
stop | Stop entire run |
Default
| Outcome | Next Action |
|---|---|
| Pass | continue to next phase |
| Fail | stop entire run (see Callbacks) |
| Skip | continue to next phase |
| Error | stop entire run |
| Timeout | stop entire run |
| Stop | stop entire run |
Next Action
You can customize next action determination at phase level by using then field. Use this field to map next actions on outcomes.
For example, you can stop the procedure if a critical phase fails :
main:
- name: Temperature Check
description: "Verify UUT is not over-heating"
python: temperature_check
then:
fail: stopdef temperature_check(phase, thermometer):
temp = thermometer.get_temp()
if temp > 100:
phase.fail()How is this guide?