# Phases URL: /phases Discover how to define and execute test phases using OpenHTF, including phase creation, phase results, and phase options with detailed examples. Organize your test flow by breaking it down into multiple phases. A hardware test typically consists of several steps that perform measurements and validation. OpenHTF refers to these steps as phases and allows for precise management of their execution based on the results obtained. Phases are Python functions that take the `test` object as an argument and must be added to the `Test` object to be executed. The phase outcome is set either manually with a `PhaseResult` or automatically through a measurement validator, covered on the Measurements page. You can choose the next phase's execution by setting the `PhaseResult` from the following options. Set the phase outcome to `PASS` and execute the next phase. Set the phase outcome to `FAIL` and stop executing the test. Repeat the phase, ignoring current measurement outcomes. If exceeded the `repeat_limit`, it triggers a `PhaseResult.STOP`. Set the phase outcome to `FAIL` and execute the next phase. Set the phase outcome to `SKIP`, ignore current measurement outcomes, and execute the next phase. Fail the enclosing subtest and continue with the next one. Outside a subtest this is an `ERROR`. A phase that returns `None` (no explicit return) is treated as `CONTINUE`. You can use the `@openhtf.PhaseOptions` decorator to modify phase execution behavior. Timeout for the phase, in seconds. Maximum number of repeats. Set to `None` for infinite repeats, as long as `PhaseResult.REPEAT` is returned. For more options, check the advanced use cases. You can leverage advanced OpenHTF options to handle more complex phase execution cases. You can replace the default phase name or change the case formatting: Override for the name of the phase. `PhaseNameCase.KEEP` (default) leaves the function name as-is; `PhaseNameCase.CAMEL` converts `measure_voltage` to `MeasureVoltage`. You can repeat or stop phases under specific conditions with these following `PhaseOptions`: Define a maximum number of repeats. None indicates that a phase will be repeated infinitely as long as `PhaseResult.REPEAT` is returned. Force the phase to repeat up to `repeat_limit` times. Repeat phase on timeout. Repeat the phase (up to `repeat_limit`) when any of its measurements fails validation, instead of failing the phase. Stop the test if any measurements fail. You can run the phase under the Python Debugger. When setting this option, increase the phase `timeout_s` as well because the timeout will still apply when under the debugger. You can use a callback to decide whether a phase executes at all. The typical use is gating a subset of phases on an environment variable or a configuration flag, so the same test file serves several station setups (a full end-of-line run on one bench, a quick subset on another) without maintaining separate copies of the test. Two things to keep in mind: The callback takes **no arguments**, so it cannot see the test state or earlier measurements; it can only read module globals, environment variables, or configuration values. To skip based on something measured during the run, return `PhaseResult.SKIP` from inside the phase instead. A phase skipped by `run_if` is **not logged**: it leaves no phase record in the test output, as if it were never part of the test. `PhaseResult.SKIP` on the other hand records the phase with a skip outcome. You can use this option when a phase needs to manage internal test details, such as wrapping or controlling other phases. The complete `TestState` object is passed instead of default `TestApi`. You can group phases into `setup`, `main`, and `teardown`. If a failure occurs during the `setup` or `main` phases, the system will automatically ensure that the `teardown` phase is always executed. The Phase Groups page covers nesting and the shorthand decorators.