关于 controller-testing
controller-testing 是用于编写 Laravel 控制器 HTTP 行为特性测试的技能,帮助开发者依据路由、授权、校验及持久化行为设计测试,并区分 Web 与 JSON API 模式。
主要功能
- 01控制器动作测试流程
- 02Web 与 JSON API 测试模式
- 03嵌套路由与绑定检查
- 04授权与校验断言
- 05按动作分类的参考模板
适用场景
- 01测试 Laravel 控制器的 HTTP 动作
- 02检查嵌套路由绑定与访问权限
- 03验证校验结果和持久化行为
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ hosmelq/ skills --skill controller-testing安装后在 Claude Code 中输入/controller-testing确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/route-patterns.mdreferences/actions/create.mddestroy.mdedit.mdindex.mdshow.mdstore.mdupdate.mdreferences/modes/api-json.mdreferences/validation/api-login-validation.mdprepare-for-validation.mdrequired-with-and-array.mdscoped-exists-and-unique.mdstore-validates-fields.mdupdate-validates-fields.md详细介绍
控制器测试
适用场景
仅当任务涉及 Laravel 控制器功能测试(控制器的动作级 HTTP 行为),且包含以下信号时,才启用此技能:
- 测试文件路径位于
tests/Feature/Http/Controllers/**下(包括tests/Feature/Http/Controllers/Api/**)。这是主要触发条件。 - 任务明确涉及控制器动作,并使用动作级
describe('create' | 'destroy' | 'edit' | 'index' | 'show' | 'store' | 'update')。 - 使用
route(...)进行控制器路由断言、检查嵌套参数和路由模型绑定范围。 - 认证/授权结果和控制器传输断言:
- Web/会话(
get、post、patch、delete、assertInertia、重定向),或 - API/JSON(
getJson、postJson、patchJson、deleteJson、JSON 断言)。
- Web/会话(
不要仅因出现 describe('store') 就启用此技能(许多非控制器功能测试也会使用相同动词,例如 Fortify/认证流程)。
不要将此技能用于模型/单元测试、服务层测试、控制台命令或非 HTTP 行为。
停用开关/优先级
对于以控制器为重点的功能测试,此技能优先于 pest-testing。
如果控制器测试任务已选择 pest-testing,请立即停止并切换到 controller-testing。
快速开始
# Create file only when needed
php artisan make:test --pest Http/Controllers/<Name>ControllerTest --no-interaction
# Run only the affected file
php artisan test --compact tests/Feature/Http/Controllers/<Name>ControllerTest.php
# Optional focused rerun
php artisan test --compact --filter="<test name>"
决策流程
- 检查控制器动作、表单请求、策略、资源和路由定义,以推导待测试的契约。
- 选择传输模式:Web/会话或 API/JSON。
- 确定路由形态(扁平或嵌套)和参数键。
- 对每个待测动作,按以下顺序应用基线(视情况而定):
- 需要认证
- 策略拒绝(
403) - 绑定不匹配(
404) - 验证数据集(
store/update) - 成功响应+持久化断言
- 仅加载该动作/规则模式所需的参考文件。
输出约束(保持控制器测试简洁)
这些约束旨在避免测试冗杂且不一致。
- 将控制器契约视为事实依据。模板仅供起步参考;请根据控制器实际实现的请求载荷、响应形态、重定向、资源和策略流程进行调整。
- 保持
403测试简洁。对于禁止访问的情况,通常无需发送完整载荷(授权应在验证之前失败)。 - 验证数据集必须精简且稳定:
- 每个数据集的
data只应包含触发相应规则所需的字段。不要在每个用例中重复完整的“有效载荷”。 - 对每个验证失败的字段都断言其验证消息。不要在这些数据集中只使用键名作为预期结果。
- 当多个字段共用
sometimes|required样式的空值规则时,优先使用一个用例,为所有这些字段提交空字符串,并分别断言每个字段的必填消息。不要将此模式简化为只测试一个代表性字段。 - 优先直接使用
post(...)/patch(...);除非无法可靠地断言重定向回来源页面,否则避免使用from(...)。
- 每个数据集的
- 优先使用基于路由的重定向:存在命名路由时使用
assertRedirectToRoute(...);仅当目标不是命名路由或由配置驱动时,才使用assertRedirect(...)。
403 与 404 的规范规则
以此为准:
- 如果路由绑定成功解析,但授权拒绝访问,则断言
assertForbidden()(403)。 - 如果路由模型绑定失败(父级/子级链错误、范围绑定不匹配),则断言
assertNotFound()(404)。
用于确保结果确定性的执行者上下文:
403测试:使用范围内的执行者进行身份认证,使其能够解析绑定,但没有相应权限。- 验证和成功路径测试:使用已获授权的范围内执行者进行身份认证。
404绑定不匹配测试:可使用任意已认证的执行者,因为绑定会先行失败。
参考索引
按需加载:
- API/JSON 适配指南和完整示例:
references/modes/api-json.md
- 嵌套路由命名和参数组合:
references/route-patterns.md
- 按操作划分的模板(优先适用于 Web/会话模式):
references/actions/create.mdreferences/actions/destroy.mdreferences/actions/edit.mdreferences/actions/index.mdreferences/actions/show.mdreferences/actions/store.mdreferences/actions/update.md
- 验证规则目录(仅合并所需规则):
references/validation/store-validates-fields.mdreferences/validation/update-validates-fields.md
- 专项验证模式(存在匹配规则时优先使用):
references/validation/required-with-and-array.mdreferences/validation/scoped-exists-and-unique.mdreferences/validation/prepare-for-validation.mdreferences/validation/api-login-validation.md
操作参考是优先适用于 Web/会话模式的模板。对于 API/JSON 控制器,保留相同的操作结构,并根据被测控制器/资源契约,使用 references/modes/api-json.md 调整断言。
按传输方式划分的基线断言
Web/会话模式:
requires authentication-> 重定向到登录路由。- 验证失败 ->
assertRedirectBackWithErrors(...)。 - 页面操作 ->
assertOk()+assertInertia(...)。 - 修改操作 -> 重定向 + 持久化断言。
- Toast/闪存消息断言是可选项,具体取决于应用。
API/JSON 模式:
- 受保护的端点:
requires authentication->assertUnauthorized()。 - 公开端点:除非端点受保护,否则跳过身份验证必需测试。
- 验证失败 ->
assertUnprocessable()+assertJsonValidationErrors(...)。 - 成功操作 ->
assertOk()/assertCreated()/assertNoContent()+ JSON + 持久化断言。 - 断言验证消息,而不只是键,以便测试验证确切的 API 契约。
说明
- 单层、双层和三层示例只是模式,并非层级限制。
- 对于
destroy,根据模型行为选择持久化断言:- 对软删除模型使用
assertSoftDeleted(...)。 - 其他情况使用
assertModelMissing(...)。
- 对软删除模型使用
- 在断言中使用应用的标识符形式(
id、public_id、slug、路由键)。
评论
支持 Markdown