TofuPilotTofuPilot

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 Test

TofuPilot 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_test

If 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:

OutcomeIf
ErrorUnhandled exception thrown
SkipCalled phase.skip() or phase skipped by framework
TimeoutPhase exceeded timeout limit
StopCalled phase.stop(), Error outcome from another phase or run stopped by user in UI
FailCalled phase.fail(), phase.retry() exceeding retry limit, or measurements invalid
PassAll measurements valid

Outcome Control

You can control phase outcomes by calling methods on the phase parameter in your python function :

MethodDescription
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 skipped

Outcome 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:

  1. Test power that succeeds
  2. Test capacity that fails

We'll create the procedure file and the Python modules:

procedure.yaml
test_power.py
test_capacity.py

We'll define the phases and reference the modules:

def test_power(phase, battery):
    if not battery.check_voltage():
        phase.fail()
    # Implicit pass
def test_capacity(phase, battery):
    if not battery.verify_capacity():
        phase.fail()
    # Implicit pass
main:
  - name: Test Power
    python: phases.test_power

  - name: Test Capacity
    python: phases.test_capacity

TofuPilot 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

ActionDescription
continueContinue to next phase
retryRetry this phase (see Retry)
skipSkip to next phase
stopStop entire run

Default

OutcomeNext Action
Passcontinue to next phase
Failstop entire run (see Callbacks)
Skipcontinue to next phase
Errorstop entire run
Timeoutstop entire run
Stopstop 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: stop
def temperature_check(phase, thermometer):
  temp = thermometer.get_temp()
  if temp > 100: 
    phase.fail()

How is this guide?