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

Tester Laravel Package

contributte/tester

Contributte Tester integrates Nette Tester into your project with a ready-to-use setup and tooling. Install via Composer and follow the included docs to run and manage automated tests on PHP 8.2+ with Nette 3.2+.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require --dev contributte/tester
    

    Ensure your phpunit.xml includes the package’s bootstrap:

    <phpunit>
        <autoload>
            <classmap suffix=".php"/>
        </autoload>
        <extensions>
            <extension class="Contributte\Tester\Extensions\TesterExtension"/>
        </extensions>
    </phpunit>
    
  2. First Test: Create a test file (e.g., tests/Unit/ExampleTest.php) and use the Tester facade:

    use Contributte\Tester\Tester;
    use Tester\Assert;
    
    class ExampleTest extends \PHPUnit\Framework\TestCase
    {
        public function testBasicAssertion()
        {
            $tester = new Tester();
            Assert::true(true, 'This should pass');
        }
    }
    
  3. Run Tests:

    ./vendor/bin/phpunit
    

Key Entry Points

  • Tester Class: Core testing utility with assertions, mocking, and helpers.
  • Tester\Helpers: Laravel-specific assertions (e.g., assertRouteIs(), assertSession()).
  • Tester\Environment: Manage test environments, temp directories, and cleanup.
  • Tester\ContainerBuilder: Build and mock Laravel’s service container dynamically.

Implementation Patterns

Common Workflows

1. HTTP/API Testing

Leverage Tester\Helpers for Laravel HTTP assertions:

use Contributte\Tester\Tester;
use Tester\Helpers;

class ApiTest extends \PHPUnit\Framework\TestCase
{
    public function testGetUser()
    {
        $tester = new Tester();
        $response = $tester->get('/api/user/1');

        Helpers::assertRouteIs('users.show', $response);
        Helpers::assertJson($response, [
            'id' => 1,
            'name' => 'John Doe'
        ]);
    }
}

2. Service Container Mocking

Use ContainerBuilder to mock Laravel services:

use Contributte\Tester\Tester;
use Contributte\Tester\ContainerBuilder;

class UserServiceTest extends \PHPUnit\Framework\TestCase
{
    public function testCreateUser()
    {
        $tester = new Tester();
        $container = ContainerBuilder::buildWith([
            'services' => [
                'App\Services\UserService' => fn() => new class {
                    public function create(string $name): string {
                        return "User: $name";
                    }
                }
            ]
        ]);

        $userService = $container->get('App\Services\UserService');
        $result = $userService->create('Alice');
        $tester->assertSame('User: Alice', $result);
    }
}

3. Environment Isolation

Use Tester\Environment to manage test directories and cleanup:

use Contributte\Tester\Tester;
use Contributte\Tester\Environment;

class FileSystemTest extends \PHPUnit\Framework\TestCase
{
    protected function setUp(): void
    {
        Environment::setup([
            'testDir' => __DIR__ . '/tmp',
            'purge' => true // Auto-cleanup after tests
        ]);
    }

    public function testFileCreation()
    {
        $tester = new Tester();
        file_put_contents('test.txt', 'Hello');
        $tester->assertFileExists('test.txt');
    }
}

4. Snapshot Testing

Compare outputs against stored snapshots:

use Contributte\Tester\Tester;
use Tester\Assert;

class SnapshotTest extends \PHPUnit\Framework\TestCase
{
    public function testUserJson()
    {
        $tester = new Tester();
        $user = ['id' => 1, 'name' => 'Alice'];
        $json = json_encode($user, JSON_PRETTY_PRINT);

        Assert::snapshot($json, 'users/alice.json');
    }
}

Integration Tips

  • Laravel Artisan Testing: Use Tester\Helpers::runArtisan() to test CLI commands:

    Helpers::runArtisan('migrate:fresh')
        ->assertExitCode(0)
        ->assertOutputContains('Migrated');
    
  • Database Transactions: Combine with Laravel’s RefreshDatabase trait:

    use Illuminate\Foundation\Testing\RefreshDatabase;
    
    class UserTest extends \PHPUnit\Framework\TestCase
    {
        use RefreshDatabase;
    
        public function testUserCreation()
        {
            $tester = new Tester();
            $response = $tester->post('/users', ['name' => 'Bob']);
            $tester->assertDatabaseHas('users', ['name' => 'Bob']);
        }
    }
    
  • Custom Assertions: Extend Tester\Assert for domain-specific checks:

    use Tester\Assert;
    
    class CustomAssertions
    {
        public static function assertValidEmail(string $email)
        {
            Assert::match('/^[^\s@]+@[^\s@]+\.[^\s@]+$/', $email);
        }
    }
    

Gotchas and Tips

Pitfalls

  1. PHP 8.5+ Deprecations:

    • Liberator (used for reflection) may fail with setAccessible() calls. Update to the latest version (^0.5) or patch locally:
      // Workaround for PHP 8.5+
      if (method_exists($reflectionProperty, 'setAccessible')) {
          $reflectionProperty->setAccessible(true);
      } else {
          $reflectionProperty->setAccessible(true); // Fallback
      }
      
  2. Test Isolation:

    • Environment::purge(true) may not clean up all files (e.g., symlinks). Use Environment::skip() for problematic directories:
      Environment::setup(['skip' => ['node_modules', 'storage/logs']]);
      
  3. Laravel-Specific Gaps:

    • No built-in support for Livewire or Inertia.js testing. Use Tester\Helpers cautiously for these cases.
  4. Mocking Limitations:

    • ContainerBuilder cannot mock final classes/methods by default. Use bypassFinals:
      $container = ContainerBuilder::buildWith([
          'bypassFinals' => true,
          'services' => [...]
      ]);
      
  5. Assertion Conflicts:

    • Avoid mixing Tester\Assert with Laravel’s assert() or Pest’s expect(). Stick to one style per test file.

Debugging Tips

  • Enable Verbose Output: Set the VERBOSE environment variable to debug test failures:

    VERBOSE=1 ./vendor/bin/phpunit
    
  • Inspect Test Environment: Dump the test directory structure:

    use Contributte\Tester\Environment;
    
    public function testEnvironment()
    {
        $tester = new Tester();
        $tester->dump(Environment::getTestDir());
    }
    
  • Snapshot Mismatches: Update snapshots manually with:

    ./vendor/bin/tester snapshots:update
    

Extension Points

  1. Custom Testers: Extend Tester for project-specific needs:

    class AppTester extends Tester
    {
        public function assertApiResponse($response, int $expectedStatus)
        {
            $this->assertSame($expectedStatus, $response->getStatusCode());
            $this->assertJson($response);
        }
    }
    
  2. Global Helpers: Register custom helpers in Tester\Helpers:

    use Tester\Helpers;
    
    Helpers::add('assertCustomRule', function ($value, $rule) {
        // Custom logic
    });
    
  3. CI/CD Integration: Add a custom PHPUnit listener for test reporting:

    use PHPUnit\Runner\AfterLastTestHook;
    
    class TesterListener implements AfterLastTestHook
    {
        public function executeAfterLastTest(): void
        {
            // Post-test actions (e.g., upload artifacts)
        }
    }
    

    Register in phpunit.xml:

    <listeners>
        <listener class="TesterListener"/>
    </listeners>
    

Performance Quirks

  • Snapshot Testing: Disable for slow tests by excluding snapshot files:

    Assert::snapshot($data, 'file.json', false); // Skip snapshot
    
  • Container Mocking: Cache container builds in setUp() to avoid rebuilding:

    private $container;
    
    protected function setUp(): void
    {
        $this->container = ContainerBuilder::buildWith([...]);
    }
    
  • Parallel Tests: Use Environment::setup(['testDir' => sys_get_temp_dir()]) for parallel test runs to avoid conflicts.

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