简介
Laravel 提供了丰富的 API 用于模拟 HTTP 请求并对响应进行断言。 你无需实际启动 HTTP 服务器,就能在测试中重现应用的请求处理流程。get() 方法会向应用发送一个 GET 请求,assertStatus() 用于校验返回的 HTTP 状态码。
测试运行期间 CSRF 中间件会被自动禁用,不需要在测试中显式关闭。
发起请求
在测试中,可以使用get、post、put、patch、delete 等方法发起请求。
这些方法并不会真正发起网络请求,而是在应用内部模拟。
返回值是 Illuminate\Testing\TestResponse 的实例,提供了大量的断言方法。
自定义请求头
使用withHeaders() 可以自定义请求头。
Cookie
在发起请求前,可以通过withCookie() 或 withCookies() 设置 Cookie 值。
会话与认证
withSession() 可以在请求前设置 Session 数据。
actingAs() 可以让你以已认证用户的身份发起请求。通常与模型工厂配合使用。
actingAs() 的第二个参数传入 guard 名,即可以该 guard 进行认证,测试期间该 guard 会成为默认 guard。
actingAsGuest()。
调试响应
测试中查看响应内容,可以使用dump、dumpHeaders、dumpSession 方法。
dd、ddHeaders、ddBody、ddJson、ddSession。
异常测试
要测试是否抛出特定异常,可以使用Exceptions Facade。
assertNotReported 或 assertNothingReported。
withoutExceptionHandling()。
assertThrows()。
assertDoesntThrow()。
测试 JSON API
Laravel 提供了大量用于 JSON API 测试的辅助方法。 可以通过json、getJson、postJson、putJson、patchJson、deleteJson、optionsJson 等方法发起 JSON 请求。
assertJson() 会把响应转换为数组,判断指定数组是否包含在 JSON 响应中。即便 JSON 中还有其他字段,只要包含指定片段就会通过。完全一致断言
assertExactJson() 可以断言返回的 JSON 与指定数组完全一致。
JSON 路径断言
assertJsonPath() 可以校验指定路径下的值。
流式 JSON 测试
给assertJson() 传入闭包后,可以用 AssertableJson 实例以链式风格编写断言。
has() 和 missing()。
hasAll() 或 missingAll()。
JSON 集合断言
如果路由返回的是包含多个元素的 JSON,可以通过has() 校验数量或元素内容。
each()。
JSON 类型断言
使用whereType() 或 whereAllType() 可以校验属性的类型。
| 可以指定多个类型,符合其中之一即通过。
string、integer、double、boolean、array、null。
认证测试
通过actingAs() 可以以已认证用户的身份发起请求。
用户注册流程测试示例
下面是对真实注册接口的测试示例。会话测试
withSession() 可以在发起请求前预设 Session 数据。
assertSessionHas() 可以断言 Session 中存在某个值。
Session 断言一览
文件上传测试
使用Illuminate\Http\UploadedFile 类的 fake() 方法,可以生成用于测试的假文件或假图像。
结合 Storage Facade 的 fake() 方法,就可以轻松地测试文件上传。
assertMissing()。
自定义假文件
可以指定图像的尺寸和文件大小,便于测试校验规则。视图测试
也可以不模拟 HTTP 请求,而直接渲染视图进行测试。view() 方法接收视图名称和可选的数据数组,返回 Illuminate\Testing\TestView 实例。
TestView 类提供以下断言方法。
要以字符串形式获取渲染结果,可将
TestView 实例强转为字符串。
withViewErrors()。
组件测试
blade() 方法可以渲染原始 Blade 模板字符串。
component() 方法用于渲染 Blade 组件,返回 Illuminate\Testing\TestComponent 实例。
响应断言一览
以下是Illuminate\Testing\TestResponse 类提供的主要断言方法。
HTTP 状态
重定向
内容
JSON
请求头与 Cookie
视图
校验
实践 TDD 的要点
从 Feature 测试开始
从 Feature 测试开始
HTTP 测试应放在
tests/Feature/ 目录下。先定义从应用外部看到的行为(请求 → 响应),可以让待实现的功能更清晰。使用 RefreshDatabase
使用 RefreshDatabase
需要用到数据库的测试请使用
RefreshDatabase trait。每个测试后都会重置数据库,防止用例之间的数据干扰。测试的独立性可以让测试套件更稳定,不依赖执行顺序。积极使用工厂
积极使用工厂
使用
User::factory()->create() 这类模型工厂能极大简化数据准备。为常用状态定义 factory state 还能提升测试可读性。一个测试一个断言
一个测试一个断言
每个测试方法尽量只验证一件事。这样在失败时更容易定位原因。遵循 Arrange(准备)→ Act(执行)→ Assert(断言)的 AAA 结构会更清晰。
不要忘了认证测试
不要忘了认证测试
对需要认证的路由,务必同时编写“已认证”和“未认证”的测试,以尽早发现安全问题。
相关页面
测试入门
了解 Laravel 中编写测试的基础,以及
php artisan test 的使用。