Skip to content

Installation

Requirements

  • PHP 8.1 or higher
  • Pest PHP 2.x or 3.x
  • Composer

Installing Pest BDD

Install Pest BDD via Composer as a development dependency:

bash
composer require testflowlabs/pest-plugin-bdd --dev

That's it! The plugin automatically integrates with Pest.

Laravel Integration

Pest BDD is designed to work seamlessly with Laravel. Step attributes can be placed on any Laravel class - Models, Services, Actions, Controllers, Jobs, and more.

Supported Laravel Class Types

Class TypeStep TypeFeatures
FactoriesGivenLazy creation, state chaining
ModelsGiven/WhenStatic methods, Model::find() fallback
ActionsWhenConstructor DI, invokable support
ServicesWhenFull dependency injection
ControllersWhen/ThenRequest injection
AssertionsThenTest-specific assertions

Service Container Support

Pest BDD uses Laravel's Service Container (app()) to resolve step classes:

php
class OrderService
{
    // Dependencies are automatically injected
    public function __construct(
        private PaymentGateway $gateway,
        private InventoryService $inventory,
    ) {}

    #[When('order is processed')]
    public function process(Order $order): void
    {
        $this->gateway->charge($order);
        $this->inventory->reserve($order->items);
    }
}

Static Method Support

Static methods on Models work as step definitions:

php
class User extends Model
{
    #[Given('an admin user {name} exists')]
    public static function createAdmin(string $name): self
    {
        return self::create(['name' => $name, 'role' => 'admin']);
    }
}

Model Query Fallback

When a step parameter is a Model type and the value is numeric, Pest BDD automatically queries the database:

php
#[When('order {id} is shipped')]
public function ship(Order $order): void  // Order::find($id) if not in context
{
    $order->update(['status' => 'shipped']);
}

Learn More

See the Laravel Integration section for complete documentation on Factory integration, Service Container, and static methods.

Attributes Package

Pest BDD encourages placing step definitions in production code. To avoid requiring a test framework as a production dependency, step attributes are provided separately:

bash
composer require testflowlabs/pest-test-attributes
PackageTypePurpose
pest-plugin-bddDev dependencyTest runner, Gherkin parser, step discovery
pest-test-attributesProduction dependencyOnly the attribute classes (~4 files)

Example: Action with Step Attribute

php
// app/Actions/User/CreateUser.php
namespace App\Actions\User;

use TestFlowLabs\PestTestAttributes\When;

class CreateUser
{
    public function __construct(private UserRepository $users) {}

    #[When('I create a user with email {email}')]
    public function __invoke(string $email): User
    {
        return $this->users->create(['email' => $email]);
    }
}

This Action class works both in production (attribute ignored) and in BDD tests (attribute maps the step).

Optimizing Auto-Discovery

For complete step discovery, generate an optimized classmap:

bash
composer dump-autoload --optimize

This ensures Pest BDD can find all your step definition classes, especially in larger projects.

Why is this needed?

Pest BDD scans Composer's classmap to find classes with step attributes. By default, Composer only maps classes it has encountered. The --optimize flag generates a complete map of all classes in your project.

Project Structure

After installation, organize your BDD tests following the Given/When/Then pattern:

database/
└── factories/                    # Given steps - Factory class'ları
    ├── UserFactory.php
    └── OrderFactory.php

app/
└── Actions/                      # When steps - Production Actions
    └── User/
        └── CreateUser.php

tests/
├── Behaviors/                    # Feature files
│   ├── user-registration.feature
│   ├── shopping-cart.feature
│   └── checkout.feature
├── Assertions/                   # Then steps - Assertion class'ları
│   ├── User/
│   │   └── UserAssertions.php
│   └── Shared/
│       └── CommonAssertions.php
└── Unit/                         # Regular Pest tests
    └── ...

Step Location Summary

Step TypeTDDLocationDescription
GivenArrangedatabase/factories/Laravel Factory'ler
WhenActapp/Actions/Production Actions
ThenAsserttests/Assertions/Test assertions

Feature Files Location

Place your .feature files in tests/Behaviors/. Pest BDD automatically discovers all feature files in this directory and its subdirectories.

Step Definitions Location

Step definition classes can live anywhere in your project that Composer's autoloader can find:

  • database/factories/ - Given steps (Factory class'ları)
  • app/Actions/ - When steps (Production Actions)
  • tests/Assertions/ - Then steps (Assertion class'ları)

Laravel-Specific Setup

Autoload Configuration

For Pest BDD to discover step definitions in all locations, ensure your composer.json includes:

json
{
    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "Database\\Factories\\": "database/factories/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        }
    }
}

Then run:

bash
composer dump-autoload --optimize

Testbench for Package Development

If you're developing a Laravel package and using Orchestra Testbench:

php
// tests/TestCase.php
abstract class TestCase extends \Orchestra\Testbench\TestCase
{
    // Your test case configuration
}

Pest BDD works seamlessly with Testbench for package testing.

For detailed Laravel integration documentation:

Verifying Installation

Create a simple feature to verify everything works:

tests/Behaviors/hello.feature:

gherkin
Feature: Hello World
  Scenario: Greeting
    Given I say hello
    Then I should feel welcomed

tests/Assertions/HelloAssertions.php:

php
<?php

namespace Tests\Assertions;

use TestFlowLabs\PestTestAttributes\Given;
use TestFlowLabs\PestTestAttributes\Then;

class HelloAssertions
{
    #[Given('I say hello')]
    public function sayHello(): void
    {
        // Setup step
    }

    #[Then('I should feel welcomed')]
    public function shouldFeelWelcomed(): void
    {
        expect(true)->toBeTrue();
    }
}

Run the BDD tests:

bash
./vendor/bin/pest --bdd

You should see:

   PASS  Feature: Hello World
   ✓ Scenario: Greeting

  Tests:    1 passed
  Duration: 0.02s

Troubleshooting

Steps Not Found

If Pest BDD can't find your step definitions:

  1. Run composer dump-autoload --optimize
  2. Ensure your step classes are in a PSR-4 autoloaded directory
  3. Verify the namespace matches your autoload configuration

Feature Files Not Found

If feature files aren't discovered:

  1. Ensure files have the .feature extension
  2. Place files in tests/Behaviors/ directory
  3. Check file permissions

Released under the MIT License.