Awesome-omni-skill phpunit
PHPUnit test structure, naming, assertions, and factory conventions for Laravel feature and unit tests.
install
source · Clone the upstream repo
git clone https://github.com/diegosouzapw/awesome-omni-skill
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/diegosouzapw/awesome-omni-skill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/backend/phpunit" ~/.claude/skills/diegosouzapw-awesome-omni-skill-phpunit && rm -rf "$T"
manifest:
skills/backend/phpunit/SKILL.mdsource content
Name: PHPUnit Description: PHPUnit test structure, naming, assertions, and factory conventions for Laravel feature and unit tests. Compatible Agents: general-purpose, testing Tags: tests/**/*.php, laravel, php, testing, phpunit, unit-test, feature-test
Rules
- Feature tests go in
and extendtests/Feature/Tests\TestCase - Unit tests go in
and extendtests/Unit/PHPUnit\Framework\TestCase - Always use
in feature tests that touch the databaseIlluminate\Foundation\Testing\RefreshDatabase - Unit tests have no Laravel bootstrap — pure PHP tests only
- Use
method prefix with snake_case names:test_test_user_can_create_resource - All test methods must have
return type: void - One assertion concern per test method — keep tests focused
- Prefer
overassertSame
for strict type + value comparisonassertEquals - Assert specific values, not just truthiness
- Every new model must have a corresponding factory in
database/factories/ - Use factories in tests instead of manual
/create()
callsinsert() - Define meaningful default factory values; use states for variations
Examples
// Feature test use Illuminate\Foundation\Testing\RefreshDatabase; use Tests\TestCase; class InvoiceControllerTest extends TestCase { use RefreshDatabase; public function test_user_can_create_invoice(): void { $user = User::factory()->create(); $order = Order::factory()->create(['user_id' => $user->id]); $response = $this->actingAs($user) ->postJson('/api/invoices', ['order_id' => $order->id]); $response->assertStatus(201); $this->assertDatabaseHas('invoices', ['order_id' => $order->id]); } }
// Unit test — no Laravel bootstrap use PHPUnit\Framework\TestCase; class MoneyHelperTest extends TestCase { public function test_formats_amount_in_cents_as_currency_string(): void { $result = MoneyHelper::format(1000, 'CHF'); $this->assertSame('10.00 CHF', $result); } }
// Factory with states // database/factories/UserFactory.php public function unverified(): static { return $this->state(fn (array $attributes) => [ 'email_verified_at' => null, ]); } // Usage in tests User::factory()->create(); User::factory()->unverified()->create();
Anti-Patterns
- Not using
in feature tests that write to the databaseRefreshDatabase - Using raw
orinsert()
calls in tests instead of factoriescreate() - Mixing multiple assertion concerns in a single test method
- Using
whenassertEquals
is needed for strict comparisonassertSame - Asserting truthiness (
) instead of a specific valueassertTrue($result !== null) - Unit tests that bootstrap the full Laravel application (use
only for feature tests)Tests\TestCase
References
- PHPUnit Documentation
- Laravel Testing
- Related:
— the preferred test framework (Pest over raw PHPUnit)PestTesting/SKILL.md