Skip to content
Pest Flow
Esc
↑↓navigate↵open⌘Jpreview
On this page

DSL and API reference

Function signatures, declaration rules, Pest context, and errors for Pest Flow.

Pest Flow’s public DSL is six namespaced PHP functions. Import the functions you use into a Pest test file:

use function Pest\Flow\feature;
use function Pest\Flow\rule;
use function Pest\Flow\scenario;
use function Pest\Flow\given;
use function Pest\Flow\when;
use function Pest\Flow\then;

Composer loads the function definitions from the package automatically. The use function statements make their names available in this file.

Functions

All callbacks must be PHP Closure instances. feature(), rule(), and scenario() return fluent declaration calls with a tags(...$tags) method. The step helpers return void.

Function Signature Pest behavior
feature() feature(string $name, Closure $definition): TaggedGroupCall Declares a top-level describe group; ->tags(...) tags the feature and its descendant scenarios for filtering.
rule() rule(string $name, Closure $definition): TaggedGroupCall Declares a describe group inside the active feature; ->tags(...) tags the rule and its descendant scenarios for filtering.
scenario() scenario(string $name, Closure $definition): TaggedScenarioCall Registers a normal Pest test using $name as its description; ->tags(...) tags that scenario.
given() given(string $description, Closure $definition): void Records and executes a Given step.
when() when(string $description, Closure $definition): void Records and executes a When step.
then() then(string $description, Closure $definition): void Records and executes a Then step.

Declaration rules

feature()
└── rule()
    └── scenario()
        ├── given()
        ├── when()
        └── then()
  • Features cannot be nested inside features.
  • A rule must be declared inside a feature; rules cannot be nested.
  • A scenario inside a feature must be inside a rule. A scenario declared outside all features is allowed as a standalone Pest test.
  • Every step helper must be called while a scenario is executing.
  • Steps run in the order the helper calls appear. The Given/When/Then types are labels; Pest Flow does not enforce a count or sequence.

Callback timing and $this

feature() and rule() build Pest describe groups while the test file is loaded. Their callbacks are for declarations such as nested rules, scenarios, and Pest hooks; they are not themselves scenario test callbacks.

scenario() registers a Pest test. When that test executes, Pest Flow calls the scenario callback once to collect the step declarations. It then executes each step callback in declaration order. The scenario and step callbacks use the same Pest test object as $this:

scenario('adds two numbers', function (): void {
    given('two numbers', function (): void {
        $this->left = 2;
        $this->right = 3;
    });

    when('they are added', function (): void {
        $this->result = $this->left + $this->right;
    });

    then('the sum is five', function (): void {
        expect($this->result)->toBe(5);
    });
});

Use non-static closures when the callback needs $this. Keep the scenario callback focused on declaring steps: statements outside step closures run during collection, before any step closure executes. If a step closure throws or an expectation fails, Pest Flow records the exception, marks later declared steps as skipped, and rethrows the original exception to Pest. Pest still reports the scenario as failed.

Placement errors

Invalid declarations throw LogicException with a message explaining the required placement:

Call Error
Nest feature() inside another feature Features cannot be nested.
Call rule() without an active feature rule() must be declared inside feature().
Nest rule() inside another rule Rules cannot be nested.
Call scenario() directly inside a feature scenario() inside a feature() must be declared inside rule().
Call given() outside a scenario Given steps must be declared inside scenario().
Call when() outside a scenario When steps must be declared inside scenario().
Call then() outside a scenario Then steps must be declared inside scenario().

Pest Flow captures exceptions from step code in the execution metadata, then rethrows the same exception so Pest handles the test result normally. A Pest skip exception marks the current and remaining steps as skipped.

Registry API

Use Pest\Flow\FlowRegistry to inspect registered features, rules, scenarios, and executed steps. See the registry reference for method returns, node fields, identifier rules, and when data becomes available. Follow the registry walkthrough for an end-to-end example.

Was this page helpful?