mcpField
P
php-testing

php-testing

github.com/pluginagentmarketplaceTesting & quality442 installsUpdated 42w ago
Repository

About php-testing

php-testing is a learning skill for PHP developers covering testing from fundamentals to CI/CD. It organizes guidance by topic and level, with examples for PHPUnit, Pest, and Mockery.

Key features

  1. 01PHPUnit 11 fundamentals
  2. 02Pest 3 testing patterns
  3. 03Mocking with Mockery and Prophecy
  4. 04TDD and integration testing
  5. 05CI/CD guidance and examples

Use cases

  1. 01Learning PHPUnit test structure and assertions
  2. 02Choosing mocks, stubs, or spies
  3. 03Testing database and API integrations
  4. 04Troubleshooting tests that fail in CI

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/pluginagentmarketplace/custom-plugin-php --skill php-testing

After installing, type/php-testingin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

assets/
config.yaml
schema.json
references/
GUIDE.md
PATTERNS.md
scripts/
validate.py

Details

From the project README

PHP Testing Skill

Atomic skill for mastering PHP testing strategies

Overview

Comprehensive skill for PHP testing covering PHPUnit 11, Pest 3, TDD methodology, mocking strategies, and CI/CD integration.

Skill Parameters

Input Validation
interface SkillParams {
  topic:
    | "phpunit"          // PHPUnit framework
    | "pest"             // Pest framework
    | "mocking"          // Mockery, Prophecy
    | "tdd"              // Test-driven development
    | "integration"      // Database, API testing
    | "ci-cd";           // GitHub Actions, GitLab CI

  level: "beginner" | "intermediate" | "advanced";
  framework?: "laravel" | "symfony" | "none";
  coverage_goal?: number;
}
Validation Rules
validation:
  topic:
    required: true
    allowed: [phpunit, pest, mocking, tdd, integration, ci-cd]
  level:
    required: true
  framework:
    default: "none"

Learning Modules

Module 1: PHPUnit Fundamentals
beginner:
  - Test case structure
  - Basic assertions
  - Running tests

intermediate:
  - Data providers
  - Fixtures (setUp/tearDown)
  - Test doubles

advanced:
  - Attributes (#[Test], #[DataProvider])
  - Code coverage
  - Parallel execution
Module 2: Pest Framework
beginner:
  - Expectations syntax
  - Test organization
  - Groups and filtering

intermediate:
  - Higher-order tests
  - Datasets
  - Hooks

advanced:
  - Mutation testing (--mutate)
  - Architecture testing
  - Custom expectations
Module 3: Mocking Strategies
beginner:
  - Mock basics
  - Stubs vs mocks
  - Simple expectations

intermediate:
  - Partial mocks
  - Spies
  - Argument matching

advanced:
  - Mock chains
  - Return callbacks
  - Exception testing

Error Handling & Retry Logic

errors:
  TEST_FAILURE:
    code: "TEST_001"
    recovery: "Compare expected vs actual, check setup"

  MOCK_ERROR:
    code: "TEST_002"
    recovery: "Verify mock expectations and injection"

  FLAKY_TEST:
    code: "TEST_003"
    recovery: "Check isolation, fix race conditions"

retry:
  max_attempts: 2
  backoff:
    type: linear
    delay_ms: 100

Code Examples

PHPUnit Test (PHP 8.2+)
<?php
declare(strict_types=1);

namespace Tests\Unit;

use App\Services\Calculator;
use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\Attributes\DataProvider;

final class CalculatorTest extends TestCase
{
    private Calculator $calculator;

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

    #[Test]
    public function it_adds_two_numbers(): void
    {
        $result = $this->calculator->add(2, 3);

        $this->assertSame(5, $result);
    }

    #[Test]
    #[DataProvider('divisionProvider')]
    public function it_divides_correctly(int $a, int $b, float $expected): void
    {
        $result = $this->calculator->divide($a, $b);

        $this->assertEqualsWithDelta($expected, $result, 0.0001);
    }

    public static function divisionProvider(): array
    {
        return [
            'whole' => [10, 2, 5.0],
            'decimal' => [7, 2, 3.5],
        ];
    }

    #[Test]
    public function it_throws_on_division_by_zero(): void
    {
        $this->expectException(\DivisionByZeroError::class);

        $this->calculator->divide(10, 0);
    }
}
Pest Test
<?php
use App\Models\User;
use function Pest\Laravel\{actingAs, post, assertDatabaseHas};

describe('User Registration', function () {
    it('allows new user registration', function () {
        post('/register', [
            'name' => 'John',
            'email' => '[email protected]',
            'password' => 'password',
            'password_confirmation' => 'password',
        ])
        ->assertRedirect('/dashboard');

        assertDatabaseHas('users', ['email' => '[email protected]']);
    });

    it('requires valid email', function () {
        post('/register', ['email' => 'invalid'])
            ->assertSessionHasErrors('email');
    });
})->group('auth');
Mocking with Mockery
<?php
declare(strict_types=1);

namespace Tests\Unit;

use App\Services\UserService;
use App\Repositories\UserRepository;
use Mockery;
use PHPUnit\Framework\TestCase;

final class UserServiceTest extends TestCase
{
    public function test_creates_user(): void
    {
        // Arrange
        $repository = Mockery::mock(UserRepository::class);
        $repository
            ->shouldReceive('create')
            ->once()
            ->with(['name' => 'John', 'email' => '[email protected]'])
            ->andReturn(new User(['id' => 1]));

        $service = new UserService($repository);

        // Act
        $user = $service->createUser([
            'name' => 'John',
            'email' => '[email protected]',
        ]);

        // Assert
        $this->assertEquals(1, $user->id);
    }

    protected function tearDown(): void
    {
        Mockery::close();
    }
}
CI/CD Configuration (GitHub Actions)
name: Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.3'
          coverage: xdebug

      - name: Install dependencies
        run: composer install --no-progress

      - name: Run tests
        run: vendor/bin/phpunit --coverage-clover coverage.xml

      - name: Upload coverage
        uses: codecov/codecov-action@v3

Troubleshooting

ProblemCauseSolution
Tests pass locally, fail in CIEnvironment differencesCheck PHP version, database state
Mock not calledNot injectedVerify DI, don't instantiate inside class
Database pollutionShared stateUse RefreshDatabase trait
Slow testsToo many DB operationsUse mocks, run parallel

Quality Metrics

MetricTarget
Code coverage≥80%
Test speed<5 min full suite
Flaky rate0%
Test isolation100%

Usage

Skill("php-testing", {topic: "mocking", level: "intermediate"})

Comments

Markdown supported