orchestra/testbench-core
Orchestra Testbench Core is the foundation for testing Laravel packages. It boots a lightweight Laravel app inside your package so you can run artisan commands, migrations, routing, and more, with compatibility across Laravel 6–12.
Installation:
composer require --dev orchestra/testbench-core
Ensure version compatibility with your Laravel version (e.g., orchestra/testbench-core:^11.0 for Laravel 11).
Basic Test Class:
use Orchestra\Testbench\TestCase;
class ExampleTest extends TestCase
{
public function test_basic()
{
$this->assertTrue(true);
}
}
Configure testbench.php (optional):
return [
'seeders' => true, // Auto-run seeders
'providers' => [
// Custom service providers
],
'aliases' => [
// Custom aliases
],
];
Run Tests:
php artisan test
use Orchestra\Testbench\TestCase;
class MyPackageTest extends TestCase
{
protected function getPackageProviders($app)
{
return ['MyPackage\\Providers\\MyPackageServiceProvider'];
}
public function test_package_works()
{
$this->assertTrue(MyPackage::isInstalled());
}
}
protected function getPackageProviders($app)
{
return [
'App\\Providers\\AuthServiceProvider',
'MyPackage\\Providers\\MyPackageServiceProvider',
];
}
$this->app->bind('MyService', function () {
return Mockery::mock('MyService');
});
protected function getEnvironmentSetUp($app)
{
$app['config']->set('my-package.key', 'value');
}
use Orchestra\Testbench\Attributes\WithConfig;
#[WithConfig(['my-package' => ['key' => 'value']])]
class MyTest extends TestCase { ... }
public function setUp(): void
{
parent::setUp();
$this->loadMigrationsFrom(__DIR__.'/../../database/migrations');
$this->artisan('db:seed', ['--class' => 'MyTestSeeder']);
}
use Orchestra\Testbench\Concerns\WithFixtures;
class MyTest extends TestCase
{
use WithFixtures;
protected $fixtures = [
'users' => ['admin'],
];
}
$this->artisan('my:command', ['option' => 'value'])
->assertExitCode(0)
->expectsOutput('Expected output');
use Orchestra\Testbench\BrowserKit\TestCase;
class MyBrowserTest extends TestCase
{
public function test_login()
{
$this->visit('/login')
->type('email@example.com', 'email')
->type('password', 'password')
->press('Login')
->see('Dashboard');
}
}
php artisan test --parallel
WithFixtures for Parallel Compatibility:
use Orchestra\Testbench\Concerns\WithFixtures;
class MyTest extends TestCase
{
use WithFixtures;
// Fixtures will be loaded per-test in parallel mode
}
getPackageAliases() to register package aliases:
protected function getPackageAliases($app)
{
return [
'MyPackage' => 'MyPackage\\Facades\\MyPackage',
];
}
HTTP Clients:
$this->mock(Http::class, function ($mock) {
$mock->shouldReceive('get')
->once()
->andReturn(response()->json(['key' => 'value']));
});
Queues:
Queue::fake();
MyJob::dispatch();
Queue::assertPushed(MyJob::class);
Event::fake();
MyEvent::dispatch();
Event::assertDispatched(MyEvent::class);
protected function getMiddleware($middleware)
{
return [
'web' => ['App\\Http\\Middleware\\TrustProxies'],
];
}
#[WithConfig] may not merge configs if loaded too early.defer: false:
#[WithConfig(['key' => 'value'], defer: false)]
WithFixtures may fail in parallel mode if not configured.testbench.yaml has:
parallel: true
#[UsesVendor] fails if the app isn’t booted.getPackageProviders() returns the correct providers.refreshDatabase() or migrateFresh():
public function setUp(): void
{
parent::setUp();
$this->refreshDatabase();
}
assertsOutput() may fail with special characters.$this->artisan('command')
->assertExitCode(0)
->expectsOutput('/Expected.*pattern/');
method_exists() checks may fail.hasMethod() or can() where applicable.$this->app->bindings();
$this->app['config']->get('key');
APP_DEBUG=true in .env.testing:
APP_DEBUG=true
APP_ENV=testing
dd() or dump() sparingly; prefer var_dump() for quick checks.#[Depends] to chain tests:
#[Depends(MyTest::class)]
class RelatedTest extends TestCase { ... }
trait WithCustomFixtures
{
protected function loadCustomFixtures()
{
// Custom fixture logic
}
}
TestCase:
class CustomTestCase extends TestCase
{
protected function getEnvironmentSetUp($app)
{
parent::getEnvironmentSetUp($app);
// Custom setup
}
}
testbench.yaml for Global Configseeders: true
providers:
- App\Providers\AuthServiceProvider
migrations:
- database/migrations
- packages/my-package/database/migrations
Orchestra\Testbench\package_version_compare()if (package_version_compare('my-package', '^1.0') >= 0) {
// Run version-specific tests
}
Str, Validator, or JsonResource states:
$this->flushStrStates();
$this->flushValidatorStates();
How can I help you explore Laravel packages today?