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
laratesto-write-tests
laratesto-write-tests
ichinya/laratesto
claude-code
testo
laratesto
laravel-testing
test-doubles
refresh-database
database-assertions
http-testing

Write or update Laravel tests running under Laratesto and Testo. Use for HTTP responses, container binding, database attributes, Laravel fakes, Artisan assertions, or Laravel setup and teardown in a Testo suite.

Install
php artisan boost:add-skill ichinya/laratesto

Save this content to: .claude/skills/laratesto-write-tests/SKILL.md

# Write Laravel tests under Testo

Check the installed package versions and project instructions. Follow Testo's
`testo-write-tests` and `testo-test-doubles` skills for general discovery,
assertions and doubles when available, or read them in the installed Testo
package's `skills/` directory. Laratesto adds the optional LaravelTestCase base
and application-aware trait to that workflow. Verify namespaces/API against
installed source rather than copying PHPUnit idioms.

## Application test example

Register LaravelPlugin for the suite and use a disposable test database. The
database example below needs the migration in
[references/database-migration.md](references/database-migration.md); read it
when running this example. Real project tests should use their existing schema.

```php
<?php

declare(strict_types=1);

namespace Tests\Feature;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Route;
use Laratesto\Attribute\RefreshDatabase;
use Laratesto\Testing\LaravelTestCase;
use Testo\Test;

final class BridgeSmokeTest extends LaravelTestCase
{
    protected function setUpLaravel(): void
    {
        Route::get('/laratesto-skill/ping', static fn() => response()->json(['pong' => true]));
    }

    #[Test]
    public function httpResponse(): void
    {
        $this->get('/laratesto-skill/ping')->assertOk()->assertJsonPath('pong', true);
    }

    #[Test]
    #[RefreshDatabase]
    public function persistsWidget(): void
    {
        DB::table('skill_widgets')->insert(['name' => 'example']);

$this->assertDatabaseHas('skill_widgets', ['name' => 'example']);
        $this->assertDatabaseCount('skill_widgets', 1);
    }

    #[Test]
    public function frameworkFake(): void
    {
        Event::fake();
        event(new \stdClass());

        Event::assertDispatched(\stdClass::class);
    }

    #[Test]
    public function artisanCommand(): void
    {
        $this->artisan('list')->assertSuccessful()->expectsOutputToContain('Available commands');
    }
}
```

Keep meaningful application behavior/assertions when adapting the example;
fakes should verify the expected side effect. Laratesto supplies the framework
assertion shim, so using Laravel's fake assertions does not require installing
PHPUnit. Its shim is not a replacement PHPUnit test runner or full MockObject
implementation; use Testo's doubles guidance for unsupported mock builders.

For trait mode, a complete equivalent binding is:

```php
<?php

declare(strict_types=1);

namespace Tests\Feature;

use Laratesto\Testing\InteractsWithLaravel;
use Testo\Assert;
use Testo\Test;

final class TraitSmokeTest
{
    use InteractsWithLaravel;

    #[Test]
    public function containerIsAvailable(): void
    {
        Assert::same($this->app()->environment(), 'testing');
    }
}
```

## Lifecycle and database choices

Class-level `#[Test]` works with LaravelTestCase and InteractsWithLaravel:
LaravelPlugin excludes the bridge's helper implementations from discovery.
Use method-level attributes when only some methods are tests. User-defined
methods, including inherited tests and overrides, retain Testo's usual discovery.
NamingConventionPlugin with `test*()` methods is an alternative if the suite
already uses that convention.

Initialize application-dependent state in protected `setUpLaravel()` after
injection; release it in protected `tearDownLaravel()`. Do not manually bootstrap
or inject an application, call PHPUnit lifecycle methods, or use constructors for
container/facade access. Testo can reuse instance fields across methods even
though LaravelPlugin supplies a fresh application per execution.

Choose native `Laratesto\Attribute\` strategies instead of Laravel's PHPUnit
database traits:

- `RefreshDatabase`: migrate and wrap the execution in a rollback transaction;
  supports `seed`, `seeder` and selected `connections`.
- `DatabaseTransactions`: rollback isolation with an already prepared schema.
- `DatabaseMigrations`: migrate before execution and rollback migrations after.
- `DatabaseTruncation`: migrate/truncate selected databases; review named
  connection behavior when porting Laravel's source trait.

Database preparation precedes Laravel setup; Laravel teardown precedes database
cleanup. `connections: null` selects the default, while `connections: []` selects
none. Avoid silently mixing strategies that express incompatible isolation.
Retry/Repeat have fresh Laravel state per attempt/iteration; Bench/PBT inner
loops share state. Only sequential/native Fiber Solo application tests are
supported. A failed setup releases bridge state without invoking user teardown.

Use `$this->get()`/`postJson()` and LaravelResponse assertions for HTTP, the
container via `$this->app()`/`make()` for services, and the native pending result
from `$this->artisan()` for command assertions. Assertions on that result execute
eagerly; migrated deferred Artisan assertions have a separate compatibility path.

Run the new test and its suite through `php vendor/bin/testo run --suite=Laravel
--json`. Verify discovery and native status, including skips and risky results.
The [Laratesto README](https://github.com/ichinya/laratesto/blob/v0.8.0/README.md)
lists the broader helper surface; installed source wins if names differ.

Write Laravel tests under Testo

Check the installed package versions and project instructions. Follow Testo's testo-write-tests and testo-test-doubles skills for general discovery, assertions and doubles when available, or read them in the installed Testo package's skills/ directory. Laratesto adds the optional LaravelTestCase base and application-aware trait to that workflow. Verify namespaces/API against installed source rather than copying PHPUnit idioms.

Application test example

Register LaravelPlugin for the suite and use a disposable test database. The database example below needs the migration in references/database-migration.md; read it when running this example. Real project tests should use their existing schema.

<?php

declare(strict_types=1);

namespace Tests\Feature;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Route;
use Laratesto\Attribute\RefreshDatabase;
use Laratesto\Testing\LaravelTestCase;
use Testo\Test;

final class BridgeSmokeTest extends LaravelTestCase
{
    protected function setUpLaravel(): void
    {
        Route::get('/laratesto-skill/ping', static fn() => response()->json(['pong' => true]));
    }

    #[Test]
    public function httpResponse(): void
    {
        $this->get('/laratesto-skill/ping')->assertOk()->assertJsonPath('pong', true);
    }

    #[Test]
    #[RefreshDatabase]
    public function persistsWidget(): void
    {
        DB::table('skill_widgets')->insert(['name' => 'example']);

$this->assertDatabaseHas('skill_widgets', ['name' => 'example']);
        $this->assertDatabaseCount('skill_widgets', 1);
    }

    #[Test]
    public function frameworkFake(): void
    {
        Event::fake();
        event(new \stdClass());

        Event::assertDispatched(\stdClass::class);
    }

    #[Test]
    public function artisanCommand(): void
    {
        $this->artisan('list')->assertSuccessful()->expectsOutputToContain('Available commands');
    }
}

Keep meaningful application behavior/assertions when adapting the example; fakes should verify the expected side effect. Laratesto supplies the framework assertion shim, so using Laravel's fake assertions does not require installing PHPUnit. Its shim is not a replacement PHPUnit test runner or full MockObject implementation; use Testo's doubles guidance for unsupported mock builders.

For trait mode, a complete equivalent binding is:

<?php

declare(strict_types=1);

namespace Tests\Feature;

use Laratesto\Testing\InteractsWithLaravel;
use Testo\Assert;
use Testo\Test;

final class TraitSmokeTest
{
    use InteractsWithLaravel;

    #[Test]
    public function containerIsAvailable(): void
    {
        Assert::same($this->app()->environment(), 'testing');
    }
}

Lifecycle and database choices

Class-level #[Test] works with LaravelTestCase and InteractsWithLaravel: LaravelPlugin excludes the bridge's helper implementations from discovery. Use method-level attributes when only some methods are tests. User-defined methods, including inherited tests and overrides, retain Testo's usual discovery. NamingConventionPlugin with test*() methods is an alternative if the suite already uses that convention.

Initialize application-dependent state in protected setUpLaravel() after injection; release it in protected tearDownLaravel(). Do not manually bootstrap or inject an application, call PHPUnit lifecycle methods, or use constructors for container/facade access. Testo can reuse instance fields across methods even though LaravelPlugin supplies a fresh application per execution.

Choose native Laratesto\Attribute\ strategies instead of Laravel's PHPUnit database traits:

  • RefreshDatabase: migrate and wrap the execution in a rollback transaction; supports seed, seeder and selected connections.
  • DatabaseTransactions: rollback isolation with an already prepared schema.
  • DatabaseMigrations: migrate before execution and rollback migrations after.
  • DatabaseTruncation: migrate/truncate selected databases; review named connection behavior when porting Laravel's source trait.

Database preparation precedes Laravel setup; Laravel teardown precedes database cleanup. connections: null selects the default, while connections: [] selects none. Avoid silently mixing strategies that express incompatible isolation. Retry/Repeat have fresh Laravel state per attempt/iteration; Bench/PBT inner loops share state. Only sequential/native Fiber Solo application tests are supported. A failed setup releases bridge state without invoking user teardown.

Use $this->get()/postJson() and LaravelResponse assertions for HTTP, the container via $this->app()/make() for services, and the native pending result from $this->artisan() for command assertions. Assertions on that result execute eagerly; migrated deferred Artisan assertions have a separate compatibility path.

Run the new test and its suite through php vendor/bin/testo run --suite=Laravel --json. Verify discovery and native status, including skips and risky results. The Laratesto README lists the broader helper surface; installed source wins if names differ.

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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource