Weave 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

nette/tester

Nette Tester is a lightweight, enjoyable PHP testing framework with expressive assertions, mocks, code coverage, and parallel test execution. It requires no annotations or complex setup, making it a fast, practical choice for testing PHP projects.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require nette/tester --dev
    

    Add to composer.json under require-dev:

    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        }
    }
    
  2. First Test File: Create tests/MyTest.php:

    <?php
    use Tester\Assert;
    use Tester\TestCase;
    
    class MyTest extends TestCase
    {
        public function testBasicAssertion()
        {
            Assert::true(1 + 1 === 2);
        }
    }
    
    (new MyTest())->run();
    
  3. Run Tests:

    vendor/bin/tester tests/MyTest.php
    

First Use Case: Assertions

public function testLaravelSpecific()
{
    $response = new \Illuminate\Http\Response('Hello');
    Assert::same('Hello', $response->getContent());
    Assert::same(200, $response->getStatusCode());

    Assert::exception(function () {
        throw new \RuntimeException('Expected error');
    }, \RuntimeException::class);
}

Note (v2.6.2): TestCase::run() now runs every test method even after one fails and displays all failures together—results first, then details. This gives you a complete picture in a single run.

Implementation Patterns

1. Test Structure

Laravel Integration Pattern:

class UserTest extends TestCase
{
    protected function setUp(): void
    {
        parent::setUp();
        $this->app = require __DIR__.'/../bootstrap/app.php';
        $this->app->make(\Illuminate\Contracts\Http\Kernel::class)->bootstrap();
    }

    public function testUserCreation()
    {
        $user = \App\Models\User::factory()->create();
        Assert::true($user->exists);
        Assert::notNull($user->email);
    }
}

2. Data Providers

Use the @dataProvider annotation:

/**
 * @dataProvider providerUserRoles
 */
public function testUserRoles($role, $description)
{
    $user = \App\Models\User::factory()->create(['role' => $role]);
    Assert::same($role, $user->role);
    Assert::same($description, $user->description);
}

public function providerUserRoles()
{
    return [
        ['admin', 'Administrator'],
        ['user', 'Regular User'],
    ];
}

3. Mocking HTTP Requests

Since Tester lacks Laravel’s $this->get(), manually create and handle a request:

public function testGetUser()
{
    $request = \Illuminate\Http\Request::create('/api/user/1', 'GET');
    $response = $this->app->make(\Illuminate\Contracts\Http\Kernel::class)->handle($request);
    Assert::same(200, $response->getStatusCode());
    Assert::same(1, json_decode($response->getContent(), true)['id']);
}

4. Database Transactions

Manually wrap tests in a transaction:

protected function setUp(): void
{
    parent::setUp();
    $this->app = require __DIR__.'/../bootstrap/app.php';
    $this->app->make(\Illuminate\Contracts\Http\Kernel::class)->bootstrap();
    $this->app->make('db')->beginTransaction();
}

protected function tearDown(): void
{
    $this->app->make('db')->rollBack();
    parent::tearDown();
}

5. Parallel Test Execution

vendor/bin/tester tests/ --parallel

New in v2.6.2: Stack traces now include call arguments (e.g., redirect('https://…', 302)), making it immediately clear which call failed.

Gotchas and Tips

Common Pitfalls

  1. System php.ini Usage:

    • Since v2.6.0, Tester uses the system php.ini by default. Use -C to override:
      vendor/bin/tester tests/ -C /path/to/custom/php.ini
      
  2. Test Lifecycle:

    • tearDown() runs even when tests fail (since v2.6.0). Avoid side effects in assertions.
  3. Assertion Order:

    • Assert::equal() with $matchOrder = true can cause false positives if array order matters.
  4. Parallel Execution:

    • Windows users need PHP 8.5+ for true parallelism (not just process forking).
  5. @phpVersion Boundary Behaviour (v2.6.2):

    • Now handles boundary versions correctly: @phpVersion 8.4.3 runs on PHP 8.4.3, and < 8.0 no longer runs on 8.0. Common forms like @phpVersion 8.1 behave as before.
  6. Assert::exception() / Assert::error() Message Check (v2.6.2):

    • Now checks the message even when it is '' or '0'. To skip the message check, pass null as the third argument. This can break tests that relied on empty‑string messages being ignored.
  7. JUnit Report failures Attribute (v2.6.2):

    • Failed tests are now counted in the failures attribute instead of errors. Update your CI scripts if they read only errors.
  8. --stop-on-fail with Parallel Jobs (v2.6.2):

    • Running tests are now finished before the runner exits; Ctrl+C terminates them.
  9. Environment::lock() on Windows (v2.6.2):

    • Leaves the test its full time limit after waiting for the lock.
  10. HttpAssert with follow: true (v2.6.2):

    • Takes headers from the final response only.
  11. Code Coverage Exit Code (v2.6.2):

    • tester now exits with code 1 when the requested report cannot be generated. The summary line no longer mixes into TAP or JUnit output on stdout.
  12. Robustness Fixes (v2.6.2):

    • Edge cases in Assert::match() masks (UTF-8, %f%), FileMock (append, rb+, touch()), DomQuery selectors on PHP < 8.4, Dumper with references, and JUnit report with invalid UTF-8. @multiple with an invalid value and Helpers::purge() on a path resolving to the root directory are now reported as errors.

Debugging Tips

  1. Verbose Output:

    vendor/bin/tester tests/ -v
    
  2. Console Lines Mode:

    vendor/bin/tester tests/ --console-lines
    
  3. Dumper Integration:

    \Tester\Dumper::dump($this->app->make(\App\Models\User::class));
    
  4. Error Output Capture:

    Assert::exception(function () {
        // Code that might fail
    }, \RuntimeException::class, 'Expected error message');
    

Extension Points

  1. Custom Assertions: Create helper functions:

    function assertDatabaseHas(string $table, array $data): void
    {
        Assert::true(
            app('db')->table($table)->where($data)->exists()
        );
    }
    
  2. Test Templates: Extend TestCase for shared setup:

    abstract class LaravelTestCase extends \Tester\TestCase
    {
        protected $app;
    
        protected function setUp(): void
        {
            $this->app = require __DIR__.'/../../bootstrap/app.php';
            $this->app->make(\Illuminate\Contracts\Http\Kernel::class)->bootstrap();
        }
    }
    
  3. Code Coverage:

    vendor/bin/tester tests/ --coverage
    
  4. Custom Output Formats:

    vendor/bin/tester tests/ --format=junit
    

Laravel-Specific Quirks

  1. Service Container:

    • Use app() helper or $this->app->make() instead of direct instantiation.
  2. Artisan Commands:

    $exitCode = \Illuminate\Support\Facades\Artisan::call('migrate:fresh');
    Assert::same(0, $exitCode);
    
  3. Event Testing:

    \Illuminate\Support\Facades\Event::fake();
    // ... trigger event ...
    \Illuminate\Support\Facades\Event::assertDispatched('user.created');
    
  4. Queue Testing:

    \Illuminate\Support\Facades\Queue::fake();
    // ... dispatch job ...
    \Illuminate\Support\Facades\Queue::assertPushed(\App\Jobs\SendEmail::class);
    

PHP 8.6 support was added in v2.6.2, so you can run the suite on the latest PHP version.

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.
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels