orchestra/workbench
Orchestra Workbench helps you preview and interact with your Laravel package during development by providing a local “workbench” app environment. Ideal for building, testing, and iterating on packages with a real Laravel instance.
Installation:
composer require --dev orchestra/workbench
php artisan workbench:install
workbench directory with stubs for routes, migrations, and config.First Use Case:
php artisan workbench:serve
http://localhost:8000 to preview your package’s routes, views, and configuration in isolation.Key Files to Review:
workbench/testbench.yaml: Configuration for Workbench (e.g., Laravel version, package namespace).workbench/routes/web.stub: Stub for package routes.workbench/database/migrations/: Migrations for testing database interactions.workbench/app/Models/User.php: Default user model (customizable via TESTBENCH_USER_MODEL).Quick Test:
routes/web.php:
Route::get('/test', function () {
return 'Package works!';
});
php artisan workbench:serve and visit http://localhost:8000/test.php artisan workbench:serve
php artisan workbench:devtool
routes/web.stub, app/Models/User.php) based on your package’s configuration.php artisan workbench:test
workbench/testbench.yaml to:
packages:
- vendor/package-name
Orchestra\Workbench\Actions\WriteEnvironmentVariables to dynamically set .env values:
use Orchestra\Workbench\Actions\WriteEnvironmentVariables;
WriteEnvironmentVariables::run([
'APP_ENV' => 'testing',
'DB_CONNECTION' => 'sqlite',
]);
routes/web.stub) using:
use Orchestra\Workbench\StubRegistrar;
StubRegistrar::replaceInFile(
'workbench/routes/web.stub',
'{{ PACKAGE_NAMESPACE }}',
'Your\Package'
);
.github/workflows/test.yml:
- name: Test Package with Workbench
run: php artisan workbench:test
workbench:test as a gatekeeper to ensure package compatibility before merging.Publish Assets: If your package publishes assets (e.g., views, configs), ensure they’re included in the Workbench stubs:
// In your package's ServiceProvider
if ($this->app->environment('workbench')) {
$this->loadViewsFrom(__DIR__.'/../resources/views', 'package');
}
Middleware Testing:
Register middleware in workbench/app/Http/Kernel.php to test package middleware:
protected $middleware = [
\Your\Package\Middleware\YourMiddleware::class,
];
Custom Factories:
Override the default UserFactory in workbench/database/factories/UserFactory.php:
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
use Orchestra\Workbench\App\Models\User;
class UserFactory extends Factory
{
protected $model = User::class;
public function definition()
{
return [
'name' => 'Test User',
'email' => 'test@example.com',
];
}
}
Database Testing: Use Workbench’s SQLite setup for fast, isolated tests:
public function test_package_feature()
{
$user = User::factory()->create();
$response = $this->actingAs($user)->get('/test');
$response->assertStatus(200);
}
php artisan workbench:serve --command=your:command
$this->artisan('your:command')
->expectsQuestion('Confirm?', 'yes')
->assertExitCode(0);
User Model Hardcoding:
Workbench\App\Models\User. If your package uses a custom user model, set the TESTBENCH_USER_MODEL env variable:
TESTBENCH_USER_MODEL=App\Models\CustomUser php artisan workbench:serve
TESTBENCH_USER_MODEL.Stub File Conflicts:
routes/web.stub) can cause conflicts when regenerating with workbench:devtool.StubRegistrar::replaceInFile() for dynamic updates instead of manual edits.Route Registration Timing:
workbench/routes/web.stub may not load if the package’s service provider isn’t registered early.register() method runs in Workbench by checking the environment:
if ($this->app->environment('workbench')) {
$this->app->register(\Your\Package\ServiceProvider::class);
}
Database Migrations:
php artisan migrate in Workbench may fail if migrations depend on package-specific tables not included in stubs.workbench/database/migrations/ or use SQLite for testing.Vite Assets:
npm run dev or npm run build separately, or configure Workbench’s Vite setup in workbench/vite.config.js.Check Workbench Logs:
workbench/.env:
APP_DEBUG=true
storage/logs/laravel.log.Inspect Stub Generation:
php artisan workbench:devtool --verbose to see which stubs are being generated/updated.Testbench Configuration:
workbench/testbench.yaml for typos or incorrect package paths. Example:
packages:
- vendor/your-package
Environment Variables:
.env or via command line:
TESTBENCH_PACKAGE_NAMESPACE=Your\Package php artisan workbench:serve
Middleware Debugging:
workbench/app/Http/Kernel.php to isolate issues:
protected $middleware = [];
Custom Actions:
Orchestra\Workbench\Actions\YourAction). Example:
namespace Orchestra\Workbench\Actions;
class YourAction
{
public static function run()
{
// Custom logic (e.g., seed test data)
\Your\Package\Models\TestModel::factory()->create();
}
}
workbench/app/Console/Kernel.php:
protected function commands()
{
$this->load(__DIR__.'/Commands');
YourAction::run();
}
Dynamic Stub Replacement:
StubRegistrar to inject package-specific values into stubs:
use Orchestra\Workbench\StubRegistrar;
StubRegistrar::replaceInFile(
'workbench/routes/web.stub',
'{{ PACKAGE_PREFIX }}',
'your-package'
);
Custom Testbench Commands:
workbench/app/Console/Kernel.php:
protected $commands = [
\Your\Package\Console\YourCommand::class,
];
Integration with Orchestra/Sidekick:
orchestra/sidekick for advanced package development (How can I help you explore Laravel packages today?