| name | pest-control |
| description | Enforces PHPUnit-only testing in this project. Activates when writing tests, reviewing test files, or when any Pest syntax appears (it(), test(), describe(), uses(), expect() chains, beforeEach/afterEach hooks). Scans for and eliminates all Pest references from code, config, and documentation.
|
| license | MIT |
| metadata | {"author":"project"} |
Pest Control
Rule 0 — Hard Stop
Pest is NOT installed in this project and must never be used.
This project uses PHPUnit 12+ exclusively.
Never write, suggest, or accept:
it('description', fn () => ...)
test('description', fn () => ...)
describe('group', fn () => ...)
uses(SomeClass::class)
expect($value)->toBe(...)
beforeEach(fn () => ...)
afterEach(fn () => ...)
pest() configuration
Rule 1 — Correct Test Class Pattern
Every test MUST be a class extending one of the three base classes:
class FooTest extends AbstractCompanyPanelTestCase
{
#[Test]
public function it_does_something(): void
{
}
}
class BarTest extends AbstractAdminPanelTestCase
{
#[Test]
public function it_does_something(): void
{
}
}
class BazTest extends AbstractTestCase
{
#[Test]
public function it_does_something(): void
{
}
}
Base class locations: Modules/Core/Tests/
Rule 2 — Attribute Syntax
Use PHP 8.1+ attributes for test metadata:
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\Attributes\CoversClass;
#[Test]
public function it_creates_an_invoice(): void {}
#[Test]
#[DataProvider('invoiceDataProvider')]
public function it_validates_invoice_fields(array $data, string $error): void {}
Never use /** @test */ docblock annotations — use #[Test] attributes.
Rule 3 — Assertion Style
Use PHPUnit assertions, not Pest chains:
$this->assertSame('expected', $actual);
$this->assertDatabaseHas('invoices', ['status' => 'paid']);
$this->assertCount(3, $results);
expect($actual)->toBe('expected');
expect($results)->toHaveCount(3);
Rule 4 — Livewire Testing
Filament/Livewire tests use the Livewire facade directly:
use Livewire\Livewire;
Livewire::actingAs($this->user)
->test(ListInvoices::class, ['tenant' => 'ivplv2'])
->assertSuccessful();
Or the base class helper:
$this->testLivewire(ListInvoices::class)->assertSuccessful();
Rule 5 — File Placement
Modules/<Name>/Tests/Unit/ ← AbstractTestCase, no DB
Modules/<Name>/Tests/Feature/ ← AbstractCompanyPanelTestCase or AbstractAdminPanelTestCase
PHPUnit discovers tests via phpunit.xml:
<testsuite name="Unit"> <directory>Modules/*/Tests/Unit</directory> </testsuite>
<testsuite name="Feature"><directory>Modules/*/Tests/Feature</directory></testsuite>
Rule 6 — Pest Elimination Checklist
When asked to eliminate Pest from a codebase, check and fix all of the following:
composer.json
Test files
Config / tooling
Documentation
Rule 7 — Conversion Reference
| Pest | PHPUnit equivalent |
|---|
it('desc', fn() => ...) | #[Test] public function it_desc(): void |
test('desc', fn() => ...) | #[Test] public function test_desc(): void |
expect($x)->toBe($y) | $this->assertSame($y, $x) |
expect($x)->toEqual($y) | $this->assertEquals($y, $x) |
expect($x)->toBeTrue() | $this->assertTrue($x) |
expect($x)->toBeFalse() | $this->assertFalse($x) |
expect($x)->toBeNull() | $this->assertNull($x) |
expect($x)->toBeEmpty() | $this->assertEmpty($x) |
expect($x)->toHaveCount(n) | $this->assertCount(n, $x) |
expect($x)->toContain($y) | $this->assertContains($y, $x) |
expect($x)->toMatchArray([...]) | $this->assertEquals([...], $x) |
expect($x)->toBeInstanceOf(Cls::class) | $this->assertInstanceOf(Cls::class, $x) |
beforeEach(fn() => ...) | protected function setUp(): void |
afterEach(fn() => ...) | protected function tearDown(): void |
uses(RefreshDatabase::class) | use RefreshDatabase; inside the class |
dataset(...) | public static function provider(): array + #[DataProvider('provider')] |