lambdatest/agent-skills

phpunit-skill

Generates PHPUnit tests in PHP. Covers assertions, data providers, mocking, and test doubles. Use when user mentions "PHPUnit", "TestCase", "assertEquals", "PHP test". Triggers on: "PHPUnit", "TestCase PHP", "assertEquals PHP", "PHP unit test".

First seen Mar 5, 2026

Installation

$ npx skills add lambdatest/agent-skills --skill phpunit-skill

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from lambdatest/agent-skills · top by installs.

npx skills add lambdatest/agent-skills

Browse all from lambdatest/agent-skills

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 366
License LICENSE
Default branch main
Open issues 3
Status Active

Skill metadata

Parsed from SKILL.md frontmatter.

Version1.0
LicenseMIT
More metadata
author
TestMu AI
version
1.0

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 4,754 B
  • docs SUMMARY.md 264 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 222 installs

SKILL.md

PHPUnit Testing Skill

Core Patterns

Basic Test

<?php
use PHPUnit\Framework\TestCase;

class CalculatorTest extends TestCase
{
    private Calculator $calculator;

    protected function setUp(): void
    {
        $this->calculator = new Calculator();
    }

    public function testAddition(): void
    {
        $this->assertEquals(5, $this->calculator->add(2, 3));
    }

    public function testDivideByZero(): void
    {
        $this->expectException(\DivisionByZeroError::class);
        $this->calculator->divide(10, 0);
    }

    public function testMultipleAssertions(): void
    {
        $this->assertSame(4, $this->calculator->add(2, 2));
        $this->assertSame(0, $this->calculator->subtract(2, 2));
        $this->assertSame(6, $this->calculator->multiply(2, 3));
    }
}

Data Providers

/**
 * @dataProvider additionProvider
 */
public function testAdd(int $a, int $b, int $expected): void
{
    $this->assertEquals($expected, $this->calculator->add($a, $b));
}

public static function additionProvider(): array
{
    return [
        'positive numbers' => [2, 3, 5],
        'negative numbers' => [-1, -1, -2],
        'zeros'            => [0, 0, 0],
        'mixed'            => [10, -5, 5],
    ];
}

Assertions

$this->assertEquals($expected, $actual);
$this->assertSame($expected, $actual);          // Strict type
$this->assertNotEquals($unexpected, $actual);
$this->assertTrue($condition);
$this->assertFalse($condition);
$this->assertNull($value);
$this->assertNotNull($value);
$this->assertCount(3, $array);
$this->assertContains('item', $array);
$this->assertArrayHasKey('key', $array);
$this->assertInstanceOf(MyClass::class, $obj);
$this->assertStringContainsString('sub', $string);
$this->assertMatchesRegularExpression('/\d+/', $string);
$this->assertEmpty($collection);
$this->assertGreaterThan(5, $value);
$this->assertJsonStringEqualsJsonString($expected, $actual);

Mocking

public function testCreateUser(): void
{
    $mockRepo = $this->createMock(UserRepository::class);
    $mockRepo->expects($this->once())
        ->method('save')
        ->with($this->isInstanceOf(User::class))
        ->willReturn(new User(1, 'Alice'));

    $mockEmail = $this->createMock(EmailService::class);
    $mockEmail->expects($this->once())
        ->method('sendWelcome')
        ->with('[email protected]');

    $service = new UserService($mockRepo, $mockEmail);
    $result = $service->createUser('[email protected]', 'Alice');

    $this->assertEquals(1, $result->getId());
}

Lifecycle

public static function setUpBeforeClass(): void { }   // Once before all
protected function setUp(): void { }                    // Before each test
protected function tearDown(): void { }                 // After each test
public static function tearDownAfterClass(): void { }  // Once after all

Anti-Patterns

Bad Good Why
assertEquals for strict assertSame for type+value Type coercion
No data providers @dataProvider DRY
Global state setUp()/tearDown() Isolation
No groups @group smoke Run subsets

Setup: composer require --dev phpunit/phpunit

Run: ./vendor/bin/phpunit or ./vendor/bin/phpunit --group smoke

Config: phpunit.xml with testsuites and coverage

Deep Patterns

See reference/playbook.md for production-grade patterns:

Section What You Get
§1 Project Setup composer.json, phpunit.xml with suites, coverage config, project structure
§2 Test Patterns Assertions, #[DataProvider], Generator yields, strict comparisons
§3 Mocking createMock with callbacks, Mockery spies, consecutive returns
§4 Test Doubles In-memory fakes, repository pattern, test helpers
§5 Faker & Fixtures TestDataFactory with overrides, bulk generation
§6 Exception Testing Detailed exception assertions, warning testing
§7 HTTP & API Testing Symfony WebTestCase, auth, validation, pagination
§8 Database Testing Transaction rollback, repository integration, Doctrine
§9 CI/CD Integration GitHub Actions with MySQL/Redis, coverage thresholds
§10 Debugging Table 12 common problems with causes and fixes
§11 Best Practices 14-item production PHP testing checklist