orchestra/pest-plugin-testbench
Pest Plugin for Testbench adds PestPHP support for Laravel package development using Orchestra Testbench. Run your package tests with Pest in a Testbench-powered environment, with simple setup and CI-friendly defaults.
Installation:
composer require --dev orchestra/pest-plugin-testbench
Ensure orchestral/testbench is also installed (required dependency).
Pest Configuration:
Add the plugin to your pest.php:
use Orchestra\Testbench\PestPlugin;
expects()->add(PestPlugin::class);
First Use Case:
Test a Laravel service provider in tests/Feature/ExampleTest.php:
use Orchestra\Testbench\TestCase;
it('loads a service provider', function () {
$this->app->register(\App\Providers\ExampleServiceProvider::class);
expect($this->app->bound('example'))->toBeTrue();
})->uses(TestCase::class);
Service Provider Testing:
it('binds a service', function () {
$this->app->singleton('example', fn () => 'bound');
expect($this->app->make('example'))->toBe('bound');
})->uses(TestCase::class);
Mocking Facades:
it('mocks a facade', function () {
$this->mock(\Illuminate\Auth\Facades\Auth::class, function ($mock) {
$mock->shouldReceive('check')->andReturn(true);
});
expect(auth()->check())->toBeTrue();
})->uses(TestCase::class);
Database Testing:
it('uses a fresh database', function () {
$this->artisan('migrate:fresh');
$user = User::factory()->create();
expect(User::count())->toBe(1);
})->uses(TestCase::class)->withDatabase();
Combine with Pest Plugins:
Use alongside pest-plugin-laravel for seamless Laravel-specific assertions:
use Pest\Laravel\AssertableDatabase;
it('creates a user', function () {
$response = $this->post('/register', ['name' => 'Test']);
$response->assertCreated();
$this->assertDatabaseHas('users', ['name' => 'Test']);
})->uses(TestCase::class);
Custom Testbench Setup:
Override getEnvironmentSetUp() in a custom TestCase class:
class CustomTestCase extends TestCase {
protected function getEnvironmentSetUp($app) {
$app['config']->set('app.debug', false);
}
}
Missing uses() Directive:
Forgetting to specify ->uses(TestCase::class) will skip Testbench setup.
Fix: Add it to every test or extend a base test class.
Database Conflicts:
Running withDatabase() without migrate:fresh may leave stale data.
Fix: Always pair with migrate:fresh or migrate:reset.
Facade Mocking Scope:
Mocks reset between tests unless explicitly configured.
Fix: Use ->withoutResolvingFacades() for persistent mocks:
$this->mock(Auth::class, fn ($mock) => $mock->shouldReturn('admin'))
->withoutResolvingFacades();
Environment Issues:
If Laravel config isn’t loading, verify APP_ENV=testing is set in .env.testing.
Tip: Use php artisan config:clear in CI environments.
Service Provider Loading: Ensure providers are registered before assertions:
beforeEach(function () {
$this->app->register(\App\Providers\AuthServiceProvider::class);
});
Custom Assertions:
Extend TestCase to add domain-specific helpers:
class FeatureTestCase extends TestCase {
protected function assertUserHasRole($user, $role) {
expect($user->roles()->where('name', $role)->exists())->toBeTrue();
}
}
Testbench Hooks:
Override getPackageProviders() or getPackageAliases() for package testing:
protected function getPackageProviders($app) {
return [\Laravel\Sanctum\SanctumServiceProvider::class];
}
Pest Plugins:
Combine with pest-plugin-actions for fluent HTTP testing:
it('tests an API endpoint', function () {
$this->post('/login', ['email' => 'test@example.com'])
->assertOk()
->assertJson(['token' => true]);
})->uses(TestCase::class);
How can I help you explore Laravel packages today?