Skip to content

Running Tests

Pest BDD integrates seamlessly with the Pest test runner. This guide covers all the ways to run your BDD tests.

Basic Usage

Run All BDD Tests

bash
pest --bdd

This command:

  1. Scans Composer's classmap for step definition classes
  2. Discovers all .feature files in tests/Behaviors/
  3. Executes scenarios and reports results

Regular Pest vs BDD

By default, Pest and BDD tests are separate:

bash
# Run only unit/feature tests (excludes BDD)
pest

# Run only BDD tests
pest --bdd

This separation allows you to:

  • Run fast unit tests during development
  • Run full BDD suite for acceptance testing
  • Keep CI pipelines organized

Filtering Tests

By Feature or Scenario Name

Use --filter to run specific features or scenarios:

bash
# Run features containing "Calculator"
pest --bdd --filter="Calculator"

# Run scenarios containing "Addition"
pest --bdd --filter="Addition"

# Case-insensitive partial match
pest --bdd --filter="user login"

By Tags

Filter scenarios using tags:

bash
# Run only @smoke tagged scenarios
pest --bdd --tags="@smoke"

# Run @smoke but exclude @slow
pest --bdd --tags="@smoke and not @slow"

# Run @critical or @smoke
pest --bdd --tags="@critical or @smoke"

# Complex expressions
pest --bdd --tags="(@smoke or @regression) and not @wip"

Tag expressions support:

  • and - Both conditions must match
  • or - Either condition can match
  • not - Negation
  • Parentheses for grouping

Parallel Execution

Speed up your test suite with parallel execution:

bash
pest --bdd --parallel

This runs scenarios across multiple processes. Each scenario is independent, so parallel execution is safe.

Parallel with Process Count

bash
# Use 4 parallel processes
pest --bdd --parallel --processes=4

Output Options

Verbose Output

See detailed step execution:

bash
pest --bdd

Output:

   PASS  Feature: Calculator
   ✓ Scenario: Addition
     ✓ Given I have number 5
     ✓ When I add 3
     ✓ Then the result should be 8

  Tests:    1 passed
  Duration: 0.05s

Compact Output

For CI or large test suites:

bash
pest --bdd --compact

Stop on Failure

Stop execution on first failure:

bash
pest --bdd --stop-on-failure

Test Execution Flow

Understanding the execution flow helps with debugging:

1. Discovery Phase

composer dump-autoload --optimize

Scan classmap for #[Given], #[When], #[Then]

Find .feature files in tests/Behaviors/

2. Parsing Phase

.feature file

Behat/Gherkin parser

ParsedFeature, ParsedScenario, ParsedStep objects

3. Execution Phase

For each scenario:

Create fresh ScenarioContext

For each step:
    Match step text → step definition
    Extract parameters
    Resolve injected parameters
    Execute step method
    Store return value in context

Report results

Debugging

See Matched Steps

When a step fails to match, Pest BDD suggests possible definitions:

Step not found: "Given a user exits"

Did you mean?
  Given a user exists
  Given a user {name} exists

Or create a new step:
  #[Given('a user exits')]
  public function aUserExits(): void
  {
      // TODO: Implement
  }

Check Step Discovery

Verify your steps are being discovered:

bash
# Ensure classmap is up to date
composer dump-autoload --optimize

If steps still aren't found:

  1. Check the class is in a PSR-4 autoloaded directory
  2. Verify the namespace matches composer.json
  3. Ensure attributes are correctly imported

Debug Step Execution

Add temporary logging to understand execution:

php
#[Given('a user {name} exists')]
public function userExists(string $name): User
{
    dump("Creating user: $name");  // Temporary debug
    return User::factory()->create(['name' => $name]);
}

CI/CD Integration

GitHub Actions

yaml
name: BDD Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.2'

      - name: Install dependencies
        run: composer install --prefer-dist --no-progress

      - name: Optimize autoloader
        run: composer dump-autoload --optimize

      - name: Run BDD tests
        run: vendor/bin/pest --bdd

GitLab CI

yaml
bdd-tests:
  stage: test
  script:
    - composer install --prefer-dist --no-progress
    - composer dump-autoload --optimize
    - vendor/bin/pest --bdd
  only:
    - merge_requests
    - main

Running Both Unit and BDD

yaml
jobs:
  unit-tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: composer install
      - run: vendor/bin/pest

  bdd-tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: composer install
      - run: composer dump-autoload --optimize
      - run: vendor/bin/pest --bdd

Common Commands

bash
# Basic BDD run
pest --bdd

# With filter
pest --bdd --filter="Calculator"

# With tags
pest --bdd --tags="@smoke"

# Parallel execution
pest --bdd --parallel

# Stop on first failure
pest --bdd --stop-on-failure

# Combine options
pest --bdd --parallel --tags="@smoke" --stop-on-failure

Performance Tips

Optimize Autoloader

Always run before BDD tests:

bash
composer dump-autoload --optimize

Use Tags for Fast Feedback

Mark critical scenarios:

gherkin
@smoke @fast
Scenario: User can login
  ...

Run smoke tests during development:

bash
pest --bdd --tags="@smoke"

Parallel for Large Suites

For large test suites, parallel execution significantly reduces time:

bash
pest --bdd --parallel --processes=8

Released under the MIT License.