CtrlK
BlogDocsLog inGet started
Tessl Logo

pest-control

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.

72

Quality

88%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Passed

No findings from the security scan

SKILL.md
Quality
Evals
Security

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:

// Company panel tests
class FooTest extends AbstractCompanyPanelTestCase
{
    #[Test]
    public function it_does_something(): void
    {
        // ...
    }
}

// Admin panel tests
class BarTest extends AbstractAdminPanelTestCase
{
    #[Test]
    public function it_does_something(): void
    {
        // ...
    }
}

// Pure unit tests (no DB, no framework boot)
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:

// Correct
$this->assertSame('expected', $actual);
$this->assertDatabaseHas('invoices', ['status' => 'paid']);
$this->assertCount(3, $results);

// Wrong — Pest chain
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

  • Remove "pestphp/pest-plugin": true from config.allow-plugins
  • Remove any pestphp/pest* entries from require-dev

Test files

  • Convert it('...', fn () => ...) → class method with #[Test] attribute
  • Convert test('...', fn () => ...) → class method with #[Test] attribute
  • Remove all uses(...) declarations
  • Replace expect(...)->toBe(...) chains with $this->assertSame(...)
  • Replace beforeEachsetUp(), afterEachtearDown()
  • Remove describe() wrappers; flatten into separate methods or classes

Config / tooling

  • Delete pest.php or tests/Pest.php if present
  • Remove any --pest flag from CI workflow commands
  • Update .gitignore comments: # PHPUnit / Pest# PHPUnit
  • Update Makefile comments that mention Pest

Documentation

  • Update CLAUDE.md testing section to state PHPUnit-only
  • Update any README or CONTRIBUTING docs that mention Pest

Rule 7 — Conversion Reference

PestPHPUnit 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')]
Repository
Bottelet/DaybydayCRM
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.