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

Phpunit Laravel Package

contributte/phpunit

PHPUnit integration helpers by Contributte for PHP projects. Provides lightweight tooling and conventions to simplify writing, running, and organizing tests, with sensible defaults and compatibility aimed at smoother CI and developer experience.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require contributte/phpunit --dev
    

    Add to composer.json under require-dev:

    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        }
    }
    

    Run composer dump-autoload.

  2. Basic Configuration: Create a phpunit.xml (or extend an existing one) with:

    <phpunit bootstrap="vendor/autoload.php">
        <extensions>
            <extension class="Contributte\Phpunit\Extension\BootstrapExtension"/>
        </extensions>
    </phpunit>
    
  3. First Use Case: Run a basic test:

    ./vendor/bin/phpunit
    

    Verify the BootstrapExtension loads your Laravel environment (if configured).


Implementation Patterns

Laravel-Specific Workflows

  1. Environment Bootstrapping: Extend BootstrapExtension to load Laravel’s service container:

    // In a custom extension class
    public function bootstrap(PhpUnit\Runner\BeforeTestHook $hook) {
        $app = require __DIR__.'/../../bootstrap/app.php';
        $hook->addTestListener(new LaravelTestListener($app));
    }
    
  2. Test Isolation: Use Contributte\Phpunit\Traits\RefreshDatabase for Laravel migrations:

    use Contributte\Phpunit\Traits\RefreshDatabase;
    
    class UserTest extends TestCase {
        use RefreshDatabase;
        // Tests run with a fresh DB
    }
    
  3. Custom Assertions: Add assertions via Contributte\Phpunit\Extension\AssertionExtension:

    $this->assertDatabaseHas('users', ['email' => 'test@example.com']);
    
  4. Parallel Testing: Configure in phpunit.xml:

    <phpunit parallel="true" processes="4">
        <!-- ... -->
    </phpunit>
    

Integration Tips

  • Laravel Mix: Use phpunit in package.json scripts:
    "scripts": {
        "test": "php artisan test",
        "test:unit": "./vendor/bin/phpunit --testdox-html=tests/_output/coverage.html"
    }
    
  • CI/CD: Cache vendor/ and storage/logs/ for faster runs:
    # .github/workflows/test.yml
    jobs:
      test:
        steps:
          - uses: actions/cache@v3
            with:
              path: |
                vendor
                storage/logs
              key: ${{ runner.os }}-phpunit-${{ hashFiles('**/composer.lock') }}
    

Gotchas and Tips

Pitfalls

  1. Extension Conflicts:

    • If using laravel/phpunit, disable its extensions in phpunit.xml:
      <extensions>
          <extension class="Contributte\Phpunit\Extension\BootstrapExtension"/>
          <!-- Exclude Laravel's default extensions -->
      </extensions>
      
  2. Database Traits:

    • RefreshDatabase does not roll back transactions—it truncates tables. Use sparingly in CI.
    • For MySQL, add SOFT_DELETE columns to avoid foreign key errors:
      Schema::table('users', function (Blueprint $table) {
          $table->softDeletes();
      });
      
  3. Parallel Testing Quirks:

    • Avoid static state (e.g., config() caches) in tests. Use dependency injection.
    • MySQL’s innodb_file_per_table must be enabled for parallel DB tests.

Debugging Tips

  • Verbose Output:
    ./vendor/bin/phpunit -v
    
  • Log Extensions: Add to phpunit.xml:
    <extensions>
        <extension class="Contributte\Phpunit\Extension\DebugExtension"/>
    </extensions>
    
    This dumps extension calls to storage/logs/phpunit.log.

Extension Points

  1. Custom Test Listeners: Implement PhpUnit\Framework\TestListener:

    class LaravelTestListener implements TestListener {
        public function addError(Test $test, Throwable $t, float $time) {
            Log::error("Test failed: {$test->getName()}", ['exception' => $t]);
        }
    }
    
  2. Hooks: Override bootstrap() in your extension to inject Laravel’s AppServiceProvider:

    public function bootstrap(BeforeTestHook $hook) {
        $hook->addTestListener(new LaravelServiceProviderListener());
    }
    
  3. Mocking Facades: Use Contributte\Phpunit\Traits\MockFacades:

    use Contributte\Phpunit\Traits\MockFacades;
    
    class CacheTest extends TestCase {
        use MockFacades;
    
        public function testCache() {
            $this->mockFacade(Cache::class);
            Cache::shouldReceive('get')->andReturn('mocked');
        }
    }
    

Config Quirks

  • Timezone: Set in phpunit.xml to match Laravel’s config:
    <php>
        <env name="TZ" value="UTC"/>
    </php>
    
  • Memory Limits: Increase for large test suites:
    <php>
        <memoryLimit>1G</memoryLimit>
    </php>
    
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.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor