一键导入
phpunit-test-naming
Enforces grammatically correct, intention-revealing PHPUnit test method names
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Enforces grammatically correct, intention-revealing PHPUnit test method names
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | phpunit-test-naming |
| description | Enforces grammatically correct, intention-revealing PHPUnit test method names |
| triggers | ["writing new test methods","reviewing test files","renaming test methods","when a test name contains test_, it_user_, a_user_, or is otherwise grammatically wrong"] |
Every test method MUST start with it_ and form a grammatically correct English
sentence when you replace underscores with spaces.
it_{verb}_{object}_{optional_qualifiers}
"it" is the grammatical subject — "it" = the feature/system under test.
"It returns 404 for a nonexistent record."
"It stores the entity and fires the expected event."
"It rejects the action when a precondition is not met."
public function it_returns_200_when_record_is_found(): void {}
public function it_redirects_to_index_when_user_lacks_permission(): void {}
public function it_stores_entity_with_valid_payload(): void {}
public function it_rejects_invalid_status_for_task(): void {}
public function it_soft_deletes_parent_and_preserves_children(): void {}
public function it_sends_403_json_when_access_is_denied(): void {}
public function it_creates_line_item_and_attaches_it_to_parent(): void {}
public function it_calculates_total_price_excluding_tax(): void {}
public function it_authorized_user_can_delete_task(): void {} // ✅ reads: "it [is that an] authorized user can delete task"
public function it_unauthorized_user_cannot_delete_task(): void {} // ✅ same pattern
| Bad name | Problem | Fix |
|---|---|---|
it_user_can_view_document | "it user" is not English | it_authorized_user_can_view_document |
a_user_can_view_document | Doesn't start with it_ | it_authorized_user_can_view_document |
test_duplicates_are_removed | test_ prefix — use #[Test] attribute instead | it_removes_duplicate_statuses_in_response |
test_it_can_access_create_task | Double prefix: test_it_ | it_can_access_task_create_page |
it_can_list_clients_index | Redundant "index" after verb "list" | it_lists_all_clients_on_index_page |
it_user_* smellit_user_can_* was historically used for user-permission tests. The fix is NOT to
rename to a_user_* — that just swaps one broken convention for another. The correct
patterns are:
// For permission tests: keep "user" as a qualifier on the subject
it_authorized_user_can_delete_task()
it_unauthorized_user_cannot_delete_task()
// Or: drop the subject, make it about the outcome
it_deletes_task_when_user_has_delete_permission()
it_returns_403_when_user_lacks_delete_permission()
Never use test_ prefix. Always annotate with #[Test]:
// ❌
public function test_creates_record() {}
// ✅
#[Test]
public function it_creates_record(): void {}
All test methods must declare : void.
it_?returns, stores, rejects, sends, deletes, redirects, calculates, creates, lists, shows)it_rejects_payment_when_invoice_is_not_sent > it_cannot_add_payment): void declared?# Find non-conforming names (test_, a_user_, it_user_, no it_ prefix)
grep -rn "public function " tests/ --include="*.php" \
| grep -vE "setUp|tearDown|__construct|protected |abstract " \
| grep -vE "public function it_" \
| grep -v "Browser/"
Defines structural rules for Laravel architecture, layering, and code organization
Defines DTO structure, lifecycle, and transformation rules across the application
Defines application service structure and business orchestration boundaries
Governs safe, incremental, repository-wide development workflow with continuous validation gates
Ensures correct execution order of migrations, seeders, and tests in CI
Defines the schema-to-factory-to-seeder contract chain — NOT NULL alignment, factory/seeder ownership boundaries, and schema drift rules