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 Laravel Package

graham-campbell/testbench

Laravel TestBench adds testing helpers for Laravel packages and apps, built on PHPUnit, Mockery, and Orchestral Testbench. Supports Laravel 8–13 and PHP 7.4–8.5, providing a solid base for fast, reliable package tests.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require --dev graham-campbell/testbench:^6.3
    

    No additional configuration is required.

  2. First Test Case: Extend GrahamCampbell\TestBench\AbstractPackageTestCase (for packages) or GrahamCampbell\TestBench\AbstractAppTestCase (for applications) in your test class:

    use GrahamCampbell\TestBench\AbstractPackageTestCase;
    
    class ExampleTest extends AbstractPackageTestCase
    {
        protected function getPackageProviders($app)
        {
            return ['Vendor\\Package\\ServiceProvider'];
        }
    }
    
  3. Run Tests:

    phpunit
    

Key Starting Points

  • AbstractPackageTestCase: For testing Laravel packages (bootstraps a fresh Laravel container).
  • AbstractAppTestCase: For testing Laravel applications (uses your existing config/app.php).
  • getPackageProviders(): Define required service providers for package tests.
  • getBasePath(): Override to specify custom paths (e.g., for monorepos).

Implementation Patterns

Core Workflows

1. Package Testing

  • Bootstrap: Automatically loads Laravel with your package’s service providers.
  • Configuration: Override getPackageProviders() to declare dependencies:
    protected function getPackageProviders($app)
    {
        return [
            'Vendor\\Auth\\AuthServiceProvider',
            'Vendor\\Database\\DatabaseServiceProvider',
        ];
    }
    
  • Mocking: Use Mockery (included) to stub services:
    $this->mock(\Vendor\Contracts\Service::class, function ($mock) {
        $mock->shouldReceive('doSomething')->andReturn(true);
    });
    

2. Application Testing

  • Environment: Uses your .env.testing (or .env) by default.
  • Customization: Override getEnvironmentSetUp() to modify the app:
    protected function getEnvironmentSetUp($app)
    {
        $app['config']->set('app.debug', false);
    }
    

3. HTTP Testing

  • Leverage Laravel’s HTTP testing helpers (e.g., get(), post()) directly:
    $response = $this->get('/api/users');
    $response->assertStatus(200);
    

4. Database Testing

  • Use Laravel’s database testing traits (e.g., RefreshDatabase):
    use Illuminate\Foundation\Testing\RefreshDatabase;
    
    class UserTest extends AbstractAppTestCase
    {
        use RefreshDatabase;
    }
    

Integration Tips

  • Service Providers: Test bindings and boot methods:
    $this->assertTrue($this->app->bound('service'));
    $this->assertEquals('expected', $this->app->make('service')->doSomething());
    
  • Middleware: Verify middleware is registered:
    $this->assertEquals(1, count($this->app['router']->getMiddleware()));
    
  • Commands: Test Artisan commands:
    $this->artisan('command:name')
         ->expectsQuestion('confirm', 'yes')
         ->assertExitCode(0);
    

Gotchas and Tips

Pitfalls

  1. Static Methods in v6+:

    • getBasePath() and getRequiredServiceProviders() are now static. Avoid passing $app as an argument (deprecated in v6.0+).
    • Fix: Update overrides to match the new signature:
      protected static function getBasePath(): string
      {
          return __DIR__ . '/../vendor/vendor-package';
      }
      
  2. PHPUnit Version Conflicts:

    • TestBench supports PHPUnit 9–11. Ensure your phpunit.xml aligns:
      <phpunit bootstrap="vendor/autoload.php">
          <php>
              <ini name="error_reporting" value="-1" />
          </php>
      </phpunit>
      
    • Gotcha: PHPUnit 12 is not officially supported due to minor-release volatility.
  3. Mockery Assertions:

    • Mockery’s shouldReceive() must match the exact method signature. Use ->any() for dynamic calls:
      $mock->shouldReceive('handleRequest')->withAnyArgs()->andReturn(true);
      
  4. Database Transactions:

    • RefreshDatabase trait rolls back transactions after each test. For shared state, use setUp()/tearDown():
      public function setUp(): void
      {
          parent::setUp();
          DB::table('users')->insert([...]);
      }
      

Debugging Tips

  • Dump the Container:
    $this->app->dump();
    
  • Log Service Providers: Add to getPackageProviders() to debug loading:
    $this->app->make('log')->info('Providers:', $this->getPackageProviders($this->app));
    
  • Isolate Tests: Use createApplication() in AbstractAppTestCase to avoid global state pollution:
    public function createApplication()
    {
        $app = require __DIR__.'/../../bootstrap/app.php';
        $app->make(Kernel::class)->bootstrap();
        return $app;
    }
    

Extension Points

  1. Custom Fixtures: Override getFixturePath() to load custom database seeds:

    protected function getFixturePath(): string
    {
        return __DIR__ . '/fixtures';
    }
    
  2. Test Traits: Reuse logic across tests with traits:

    trait AssertsJson
    {
        protected function assertInJson(array $data, $response)
        {
            $this->assertTrue($response->json()->has($data));
        }
    }
    
  3. Parallel Testing: Use PHPUnit’s --parallel flag with TestBench. Ensure getBasePath() is static to avoid conflicts.

Configuration Quirks

  • Environment Variables: TestBench ignores .env by default. Use getEnvironmentSetUp() to inject vars:
    protected function getEnvironmentSetUp($app)
    {
        putenv('APP_ENV=testing');
        $app['config']->set('database.default', 'sqlite_testing');
    }
    
  • Encryption Key: TestBench auto-generates a dummy key. For real encryption tests, set one in getEnvironmentSetUp():
    $app['config']->set('app.key', 'base64:...');
    
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.
calmfox/watch-sylius
damienfern/grpc-symfony-bundle
atoolo/index-bundle
atoolo/genai-bundle
coprotoai/laravel-ticket
davidjln/llm-carbon-bundle
cryonighter/valid-request-bundle
coolms/taxonomy-bundle
coolms/field-bundle
articulate-orm/symfony
aaix/laravel-tall-architect
ephoto/akeneo-connector
emmanuelballery/eb-plantumlbundle
emielburgman/symfony-visitor-beacon
emielburgman/symfony-visit-storage
emielburgman/symfony-security-headers
emielburgman/symfony-log-viewer
emarref/xdebug-bundle
emarref/pubnub-bundle
elriseio/finance-money-bundle