Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Testbench Core Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require --dev orchestra/testbench-core
    

    Ensure version compatibility with your Laravel version (e.g., orchestra/testbench-core:^11.0 for Laravel 11).

  2. Basic Test Class:

    use Orchestra\Testbench\TestCase;
    
    class ExampleTest extends TestCase
    {
        public function test_basic()
        {
            $this->assertTrue(true);
        }
    }
    
  3. Configure testbench.php (optional):

    return [
        'seeders' => true, // Auto-run seeders
        'providers' => [
            // Custom service providers
        ],
        'aliases' => [
            // Custom aliases
        ],
    ];
    
  4. Run Tests:

    php artisan test
    

First Use Case: Testing a Package

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());
    }
}

Implementation Patterns

Core Workflows

1. Service Provider Testing

  • Load Providers:
    protected function getPackageProviders($app)
    {
        return [
            'App\\Providers\\AuthServiceProvider',
            'MyPackage\\Providers\\MyPackageServiceProvider',
        ];
    }
    
  • Mock Bindings:
    $this->app->bind('MyService', function () {
        return Mockery::mock('MyService');
    });
    

2. Configuration Testing

  • Override Config:
    protected function getEnvironmentSetUp($app)
    {
        $app['config']->set('my-package.key', 'value');
    }
    
  • Use Attributes (Laravel 9+):
    use Orchestra\Testbench\Attributes\WithConfig;
    
    #[WithConfig(['my-package' => ['key' => 'value']])]
    class MyTest extends TestCase { ... }
    

3. Database Testing

  • Migrations & Seeders:
    public function setUp(): void
    {
        parent::setUp();
        $this->loadMigrationsFrom(__DIR__.'/../../database/migrations');
        $this->artisan('db:seed', ['--class' => 'MyTestSeeder']);
    }
    
  • Fixtures:
    use Orchestra\Testbench\Concerns\WithFixtures;
    
    class MyTest extends TestCase
    {
        use WithFixtures;
    
        protected $fixtures = [
            'users' => ['admin'],
        ];
    }
    

4. Artisan Command Testing

  • Execute Commands:
    $this->artisan('my:command', ['option' => 'value'])
         ->assertExitCode(0)
         ->expectsOutput('Expected output');
    

5. HTTP Testing (with BrowserKit/Dusk)

  • BrowserKit Example:
    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');
        }
    }
    

6. Parallel Testing

  • Enable Parallelism (PHPUnit 9+):
    php artisan test --parallel
    
  • Use WithFixtures for Parallel Compatibility:
    use Orchestra\Testbench\Concerns\WithFixtures;
    
    class MyTest extends TestCase
    {
        use WithFixtures;
    
        // Fixtures will be loaded per-test in parallel mode
    }
    

Integration Tips

Testing Packages in Isolation

  • Use getPackageAliases() to register package aliases:
    protected function getPackageAliases($app)
    {
        return [
            'MyPackage' => 'MyPackage\\Facades\\MyPackage',
        ];
    }
    

Mocking External Services

  • 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);
    

Testing Events

  • Assert Events Fired:
    Event::fake();
    MyEvent::dispatch();
    Event::assertDispatched(MyEvent::class);
    

Testing Middleware

  • Override Middleware:
    protected function getMiddleware($middleware)
    {
        return [
            'web' => ['App\\Http\\Middleware\\TrustProxies'],
        ];
    }
    

Gotchas and Tips

Pitfalls

1. Configuration Loading Order

  • Issue: #[WithConfig] may not merge configs if loaded too early.
  • Fix: Use defer: false:
    #[WithConfig(['key' => 'value'], defer: false)]
    

2. Parallel Testing Quirks

  • Issue: WithFixtures may fail in parallel mode if not configured.
  • Fix: Ensure testbench.yaml has:
    parallel: true
    

3. Service Provider Booting

  • Issue: #[UsesVendor] fails if the app isn’t booted.
  • Fix: Ensure getPackageProviders() returns the correct providers.

4. Database State Persistence

  • Issue: Tests may share database state between runs.
  • Fix: Use refreshDatabase() or migrateFresh():
    public function setUp(): void
    {
        parent::setUp();
        $this->refreshDatabase();
    }
    

5. Artisan Command Output

  • Issue: assertsOutput() may fail with special characters.
  • Fix: Use regex or trim output:
    $this->artisan('command')
         ->assertExitCode(0)
         ->expectsOutput('/Expected.*pattern/');
    

6. PHPUnit 13+ Deprecations

  • Issue: method_exists() checks may fail.
  • Fix: Update to use hasMethod() or can() where applicable.

Debugging Tips

1. Inspect the Application

  • Dump the container:
    $this->app->bindings();
    
  • Check config:
    $this->app['config']->get('key');
    

2. Enable Debugging

  • Set APP_DEBUG=true in .env.testing:
    APP_DEBUG=true
    APP_ENV=testing
    

3. Log Test Output

  • Use dd() or dump() sparingly; prefer var_dump() for quick checks.

4. Isolate Tests

  • Use #[Depends] to chain tests:
    #[Depends(MyTest::class)]
    class RelatedTest extends TestCase { ... }
    

Extension Points

1. Custom Testbench Extensions

  • Create a Custom Trait:
    trait WithCustomFixtures
    {
        protected function loadCustomFixtures()
        {
            // Custom fixture logic
        }
    }
    

2. Override Default Behavior

  • Extend TestCase:
    class CustomTestCase extends TestCase
    {
        protected function getEnvironmentSetUp($app)
        {
            parent::getEnvironmentSetUp($app);
            // Custom setup
        }
    }
    

3. Use testbench.yaml for Global Config

seeders: true
providers:
    - App\Providers\AuthServiceProvider
migrations:
    - database/migrations
    - packages/my-package/database/migrations

4. Leverage Orchestra\Testbench\package_version_compare()

  • Compare package versions in tests:
    if (package_version_compare('my-package', '^1.0') >= 0) {
        // Run version-specific tests
    }
    

5. Flush Global State

  • Reset Str, Validator, or JsonResource states:
    $this->flushStrStates();
    $this->flushValidatorStates();
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codraw/framework-extra-bundle
codraw/messenger
codraw/security
codraw/mailer
codraw/contracts
codraw/profiling
codraw/dependency-injection
codraw/tester
codraw/core
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony