Skill for creating and editing PHP tests following project conventions. Use when creating tests, updating test files, or refactoring tests. Applies proper structure, naming, factory usage, and Laravel/PHPUnit best practices.
View on GitHubRasmusGodske/dev-agent-workflow
project-roles
project-roles/skills/php-test-writer/SKILL.md
January 20, 2026
Select agents to install to:
npx add-skill https://github.com/RasmusGodske/dev-agent-workflow/blob/main/project-roles/skills/php-test-writer/SKILL.md -a claude-code --skill php-test-writerInstallation paths:
.claude/skills/php-test-writer/# PHP Test Writer Skill
You are an expert at writing PHP tests for Laravel applications. Your role is to create well-structured, maintainable tests that follow the project's established conventions.
## Test Method Naming - CRITICAL Pattern
**ALWAYS use the `test_` prefix. DO NOT use the `#[Test]` attribute.**
```php
// ✅ CORRECT - Use ONLY test_ prefix
public function test_order_calculates_total_correctly()
{
// test implementation
}
// ❌ WRONG - Do not use #[Test] attribute
#[Test]
public function test_order_calculates_total_correctly()
{
// test implementation
}
// ❌ WRONG - Do not use #[Test] without prefix
#[Test]
public function order_calculates_total_correctly()
{
// test implementation
}
```
**Why:** The project uses the `test_` prefix pattern consistently. While `#[Test]` is valid in PHPUnit, it's unnecessary when using the prefix and adds visual noise to test files.
## Project Context
**Important System Details:**
- **Multitenancy**: Most models have `customer_id` - use `->recycle($customer)` to avoid N+1 customer creation
- **Database Schema**: Uses squashed schema (`database/schema/testing-schema.sql`)
- **Laravel Sail**: All commands must use `./vendor/bin/sail` prefix
- **TestCase Properties**: Feature tests have protected properties like `$customer`, `$user`, `$customerUser` - **DO NOT override these**
## Critical Guidelines
### 1. Always Read TestCase.php First
**MANDATORY**: Before writing any feature test, read `tests/TestCase.php` to understand:
- Protected properties that cannot be overridden
- Available helper methods (e.g., `getCustomer()`, `getAdminUser()`, `actingAsCustomerUser()`)
- Setup methods that run automatically (e.g., `setupGroups()`, `setupCurrencies()`)
```php
// ❌ BAD - Will cause errors
class MyTest extends TestCase
{
protected $customer; // ERROR: Property already exists in TestCase
}
// ✅ GOOD - Use TestCase helper methods
class MyTest extends TestCase
{
public function test_something()
{