From asyrafhussin-agent-skills-1
Provides testing patterns for Laravel 13 with Pest PHP 4 or PHPUnit 12. Covers HTTP tests, model factories, database assertions, facade mocking, authentication testing, and test organization.
How this skill is triggered — by the user, by Claude, or both
Slash command
/asyrafhussin-agent-skills-1:laravel-testingThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> **Supports both Pest PHP 4 and PHPUnit 12.** See Framework Detection below.
AGENTS.mdREADME.mdmetadata.jsonrules/auth-acting-as.mdrules/auth-sanctum.mdrules/db-assert-has.mdrules/db-assert-missing.mdrules/db-assert-soft-deletes.mdrules/factory-define.mdrules/factory-relationships.mdrules/factory-sequences.mdrules/factory-states.mdrules/fake-ai-agent.mdrules/fake-ai-data.mdrules/fake-ai-media.mdrules/fake-event.mdrules/fake-mail.mdrules/fake-notification.mdrules/fake-queue.mdrules/fake-storage.mdSupports both Pest PHP 4 and PHPUnit 12. See Framework Detection below.
PHPUnit version note: Laravel 13 ships with
phpunit/phpunit: ^12.5.12in its defaultcomposer.json. All patterns in this skill are compatible with PHPUnit 11, 12, and 13.
Comprehensive testing guide for Laravel 13 applications. Contains 24 rules across 6 categories for writing fast, readable, and reliable tests. Supports both Pest PHP 4 and PHPUnit 12 (Laravel 13 default).
Before writing or reviewing any test code, detect which testing framework the project uses:
# Look for these in require-dev:
# "pestphp/pest" → Pest
# "phpunit/phpunit" (without pest) → PHPUnit
pestphp/pest is present → use Pest syntaxphpunit/phpunit is present → use PHPUnit syntaxtests/Pest.php exists → Pest is configured, use Pest syntax"I couldn't detect the testing framework. Does this project use Pest PHP or PHPUnit?"
| Pest | PHPUnit | |
|---|---|---|
| Test function | test('...', fn() => ...) | public function test_...(): void |
| Readable name | it('...', fn() => ...) | #[Test] public function it_...() |
| Grouping | describe('...', fn() => ...) | Test class name / nested classes |
| Trait application | uses(RefreshDatabase::class) | use RefreshDatabase; inside class |
| Before each | beforeEach(fn() => ...) | protected function setUp(): void |
| After each | afterEach(fn() => ...) | protected function tearDown(): void |
| Parameterised | ->with([...]) | #[DataProvider] attribute |
| Global setup | uses(...)->in('Feature') in Pest.php | Base TestCase class |
assertStatus, assertJson, assertJsonPath, assertDatabaseHas, assertModelExists, actingAs, Mail::fake(), Queue::fake(), Event::fake(), Notification::fake(), Storage::fake() — all work the same in Pest and PHPUnit.
Reference these guidelines when:
| Priority | Category | Impact | Prefix |
|---|---|---|---|
| 1 | HTTP & Feature Tests | CRITICAL | http- |
| 2 | Model Factories | CRITICAL | factory- |
| 3 | Database Assertions | HIGH | db- |
| 4 | Faking Services | HIGH | fake- |
| 5 | Authentication Testing | HIGH | auth- |
| 6 | Test Organisation Patterns | MEDIUM | pest- |
http-test-structure - Arrange/Act/Assert with factories — Pest + PHPUnit exampleshttp-assert-response - assertStatus, assertJson, assertRedirect, assertJsonMissinghttp-assert-json-fluent - Fluent assertJson with AssertableJson closurehttp-refresh-database - RefreshDatabase vs DatabaseTransactions — when to use eachfactory-define - Define factories with typed fake data and PHP 8.3 syntaxfactory-states - Factory states for distinct test scenariosfactory-sequences - sequence() for varied data across multiple recordsfactory-relationships - has(), for(), recycle(), afterCreating()db-assert-has - assertDatabaseHas, assertModelExists for presence checksdb-assert-missing - assertDatabaseMissing, assertModelMissing for deletiondb-assert-soft-deletes - assertSoftDeleted, trashed() factory statefake-mail - Mail::fake(), assertSent vs assertQueued, assertNothingSentfake-queue - Queue::fake(), assertPushed, assertPushedOnfake-notification - Notification::fake(), assertSentTo, assertCountfake-event - Event::fake(), assertDispatched, assertNotDispatchedfake-storage - Storage::fake(), UploadedFile::fake(), assertExistsfake-ai-agent - Agent::fake(), assertPrompted, preventStrayPrompts (Laravel 13+)fake-ai-media - Image::fake(), Audio::fake(), Transcription::fake() (Laravel 13+)fake-ai-data - Embeddings::fake(), Reranking::fake(), Files::fake(), Stores::fake() (Laravel 13+)auth-acting-as - actingAs() for session/web authenticated testsauth-sanctum - Sanctum::actingAs() for API token authenticationpest-describe-it - describe()/it() (Pest) or test class organisation (PHPUnit)pest-datasets - with() datasets (Pest) or #[DataProvider] (PHPUnit)pest-hooks - beforeEach/afterEach (Pest) or setUp/tearDown (PHPUnit)<?php
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('authenticated user can create a post', function () {
$user = User::factory()->create();
$this->actingAs($user)
->postJson('/api/posts', ['title' => 'Hello World', 'body' => 'Content.'])
->assertStatus(201)
->assertJsonPath('data.title', 'Hello World');
$this->assertDatabaseHas('posts', ['title' => 'Hello World', 'user_id' => $user->id]);
});
<?php
namespace Tests\Feature;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class PostControllerTest extends TestCase
{
use RefreshDatabase;
public function test_authenticated_user_can_create_a_post(): void
{
$user = User::factory()->create();
$this->actingAs($user)
->postJson('/api/posts', ['title' => 'Hello World', 'body' => 'Content.'])
->assertStatus(201)
->assertJsonPath('data.title', 'Hello World');
$this->assertDatabaseHas('posts', ['title' => 'Hello World', 'user_id' => $user->id]);
}
}
Read individual rule files for detailed explanations and code examples.
Each rule file contains:
For the complete guide with all rules expanded: AGENTS.md
npx claudepluginhub joshuarweaver/cascade-code-languages-misc-1 --plugin asyrafhussin-agent-skills-1Writes tests with Pest 4/PHPUnit 12 for Laravel 13: feature tests, unit tests, mocking, fakes, factories, and TDD workflows.
Guides Laravel TDD with PHPUnit and Pest, covering factories, database testing, fakes, and 80%+ coverage targets. Activates for new features, bug fixes, or refactoring in Laravel apps.
Guides Test-Driven Development for Laravel apps using Pest PHP: write failing tests first for features, bug fixes, controllers, models, APIs, then minimal code to pass and refactor.