orchestra/testbench
Orchestra Testbench is the de facto helper for testing Laravel packages. It boots a lightweight Laravel app for PHPUnit/Pest, so you can run integration and feature tests against your package with minimal setup and fast feedback.
## Getting Started
### Minimal Setup
1. **Installation**:
```bash
composer require --dev orchestra/testbench
Add to your composer.json under require-dev:
"orchestra/testbench": "^11.0"
Basic Test Class:
Extend Orchestra\Testbench\TestCase in your test file:
use Orchestra\Testbench\TestCase;
class ExampleTest extends TestCase
{
public function test_basic()
{
$this->assertTrue(true);
}
}
First Use Case:
Load your package and its providers in getPackageProviders():
protected function getPackageProviders($app)
{
return [
\YourVendor\YourPackage\YourPackageServiceProvider::class,
];
}
Run Tests:
phpunit
testbench.yaml configuration (for customizing test environments)Concerns\WithFixtures for database seedingprotected function getPackageProviders($app)
{
return [
\YourVendor\YourPackage\Providers\AuthServiceProvider::class,
\YourVendor\YourPackage\Providers\RouteServiceProvider::class,
];
}
getPackageAliases() for facade aliases if needed.$this->loadMigrationsFrom([
__DIR__.'/../database/migrations',
__DIR__.'/../../vendor/your-package/src/database/migrations',
]);
testbench.yaml):
seeders: true
Or programmatically:
$this->artisan('db:seed', ['--class' => 'YourSeeder']);
$mock = Mockery::mock('alias:YourContract');
$mock->shouldReceive('method')->once();
$this->app->instance('YourContract', $mock);
$this->app->bind('YourInterface', function () {
return new YourImplementation();
});
$response = $this->get('/your-package/endpoint');
$response->assertStatus(200);
$this->app->middleware('your.package.middleware');
testbench.yaml:
skeleton: custom/path/to/skeleton
environment: testing
seeders: true
$this->withEnvironmentSetup([
'APP_DEBUG' => true,
'YOUR_PACKAGE_OPTION' => 'value',
]);
WithFixturesuse Orchestra\Testbench\Concerns\WithFixtures;
class UserTest extends TestCase
{
use WithFixtures;
protected function getFixturesPath()
{
return __DIR__.'/fixtures';
}
}
WithFixtures is compatible with --parallel flag in PHPUnit:
phpunit --parallel
terminate() or bail() for early exits in parallel tests:
if ($this->shouldSkip()) {
Orchestra\Testbench\bail('Skipping test...');
}
$this->artisan('your-package:command')
->expectsQuestion('confirm', 'yes')
->assertExitCode(0);
Event::fake([
\YourVendor\YourPackage\Events\YourEvent::class,
]);
Event::assertDispatched(function ($event) {
return $event instanceof YourEvent;
});
$view = $this->view('your-package::view.name');
$view->assertSee('Expected Text');
$this->app['config']->set('your-package.key', 'value');
$this->assertEquals('value', config('your-package.key'));
$this->app->make('auth')->shouldUseName('YourPolicy');
$this->assertTrue($this->app['auth']->authorize('user', 'access'));
Queue::fake();
YourJob::dispatch();
Queue::assertPushed(YourJob::class);
Notification::fake();
Notification::assertSentTo(
User::first(),
YourNotification::class
);
Str, or Validator states may leak between tests.$this->app->flush();
\Illuminate\Support\Str::flush();
\Illuminate\Database\Eloquent\Model::flush();
WithFixtures or manually rollback:
$this->beginDatabaseTransaction();
// Test code
$this->rollBackDatabaseTransaction();
WithFixtures may fail in parallel mode due to shared state.terminate() to skip tests:
if (!file_exists($this->getFixturesPath())) {
Orchestra\Testbench\terminate('Fixtures not found');
}
.env files may not load.testbench.yaml or override in setUp():
$this->withEnvironmentSetup([
'DB_CONNECTION' => 'sqlite_memory',
]);
package_version_compare() to enforce constraints:
if (!Orchestra\Testbench\package_version_compare('11.*', '^11.0')) {
$this->markTestSkipped('Unsupported Laravel version');
}
Mockery::close();
Orchestra\Testbench\Workbench\Actions\AddAssetSymlinkFolders or disable in testbench.yaml:
symlinks: false
dd($this->app->make('config')->all());
$this->withEnvironmentSetup([
'APP_DEBUG' => true,
]);
$this->artisan('your-command', [
'--verbose' => true,
]);
$this->app->register(\YourVendor\YourPackage\Providers\YourProvider::class);
$this->app->make('log')->error('Deprecation: ...');
testbench.yaml:
skeleton: /path/to/custom/skeleton
orchestra/sidekick to generate skeletons dynamically.How can I help you explore Laravel packages today?