看看在Laravel中开始自动化测试有多么容易
关于为什么你应该为你的代码编写测试,有数百篇文章。为什么你应该这样 写测试 对于你的代码。而且我假设你已经阅读了很多遍。
许多开发者认识到编写测试的重要性,但他们只是没有开始。
为什么不
主要是因为一些误解。
- 他们面对着做错事的恐惧。
- 他们认为他们还不够好(现在)来写测试。
- 他们不确定哪种类型的测试适用于他们的项目。
作为一个曾经经历过的人,让告诉我,这些事情是暂时的。一旦你开始编写测试,所有这些都将成为过去。
为什么不今天
如果我告诉你,开始测试只需要你5-10分钟的时间,你会介意现在开始吗?
让今天是新事物的开始。
- 威廉·莎士比亚
好的。所以让我们从一个Laravel应用程序开始我们的测试之旅。你可以使用一个现有的网络应用程序或创建一个新的。
实际上,你可以跟随这篇文章进行任何其他编程语言/框架,因为我们只讨论高层次的内容。
Laravel的默认测试
Laravel自带了一些测试。打开你的终端,输入
php artisan test
如果你没有在你的网络应用中做任何更改,你将会看到类似的内容
太好了,我们有一个完美的起点。现在让我们写自己的测试。
一些网络应用代码
如果您有一个全新的Laravel Web应用程序,请在编写第一个测试之前,将其追加到routes/web.php
文件中。
use App\Models\User;
use Illuminate\Http\Request;
// existing code...
Route::post('/users', function (Request $request) {
$validated = $request->validate([
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'email', 'max:255'],
'password' => ['required', 'confirmed'],
]);
User::create($validated);
return back()->with('success', 'User created successfully.');
});
以下代码中发生了以下事情:
- 验证表单数据。
- 在数据库中创建用户。
- 用户成功后将其重定向回并显示成功消息。
我们的测试应该覆盖所有这些。
创建新的测试文件
我们将从创建一个新测试文件开始。请在您的终端执行以下命令
php artisan make:test UserTest
新的测试文件应该创建在tests/Feature/UserTest.php
中。
注意 - 重置数据库
如果您编写了与数据库交互的代码和测试,您应该在每次测试后重置数据库,以确保一个测试不会影响另一个测试的结果。Laravel通过提供可以添加到测试类中的特性来使这个过程变得非常简单。
请将以下特性添加到UserTest.php
文件中
use Illuminate\Foundation\Testing\LazilyRefreshDatabase;
class UserTest extends TestCase
{
use LazilyRefreshDatabase;
// existing code...
完成这些后,我们可以编写测试了。
您的第一个测试 - 快速路径
默认测试文件已经覆盖了对GET请求的测试。因此,我们可以直接编写对POST请求的测试。
当用户从浏览器中提交表单时,会提交一个包含输入值和值的POST请求。我们将要在测试中模拟相同的过程。
请在UserTest.php
文件中追加以下代码
// existing code...
public function test_new_user_can_be_added()
{
$response = $this->post('/users', [
'name' => 'Gaurav',
'email' => '[email protected]',
'password' => '123456',
'password_confirmation' => '123456',
]);
$response->assertRedirect('/')
->assertSessionHas('success', 'User created successfully.');
$this->assertDatabaseHas('users', [
'name' => 'Gaurav',
'email' => '[email protected]',
]);
}
Laravel提供了一个简单的从测试文件发送POST请求的方法,使用post()
方法。使用它,我们发起请求并验证用户详细信息被添加到数据库中,并且响应重定向到带有适当消息的会话中。
这不是很简单吗?让我们再来一个。
验证测试
为什么不添加一个测试来确保我们的验证按预期工作呢?请在UserTest.php
文件中追加以下代码
// existing code...
public function test_new_user_data_is_validated()
{
$response = $this->post('/users', [
'name' => '',
'email' => 'not_email_format',
'password' => '123456',
'password_confirmation' => '456789',
]);
$response->assertStatus(302)
->assertSessionHasErrors(['name', 'email', 'password']);
}
在这里,我们为表单输入传递无效数据,并确认(断言)存在重定向响应(HTTP状态码302)以及会话中的验证错误。
测试唯一的电子邮件地址
业务需求是,每个用户的电子邮件地址必须是唯一的,因此让我们添加一个测试来验证这一点。将此测试添加到UserTest.php
文件中
// existing code...
public function test_new_user_with_same_email_cannot_be_added()
{
User::factory()->create([
'email' => '[email protected]',
]);
$response = $this->post('/users', [
'name' => 'Gaurav',
'email' => '[email protected]',
'password' => '123456',
'password_confirmation' => '123456',
]);
$response->assertStatus(302)
->assertSessionDoesntHaveErrors(['name', 'password'])
->assertSessionHasErrors(['email']);
}
此测试使用Laravel工厂将用户添加到数据库中,然后尝试使用相同的电子邮件地址发起POST请求。让我们运行测试并查看结果。
哎呀,失败了。原因是什么呢?我们在代码中遗漏了添加唯一验证。
修复
现在,您的测试正在引导开发。(是的,TDD!)
请对routes/web.php
文件进行以下更新
- 'email' => ['required', 'email', 'max:255'],
+ 'email' => ['required', 'email', 'max:255', 'unique:users'],
更新后,给自己鼓掌,然后再次运行测试(php artisan test
)
还有更多吗?
您意识到您现在是写自动化测试的开发者了吗?祝贺您!
需要更多示例?请查看这个目录,里面包含了官方Laravel仓库中与各种模块相关的测试。
本文的目标只是帮助您开始编写测试。并不是涵盖不同的使用情况或场景。因此,我限制了实际编码的范围,并想在可以帮助您继续前进的 few 事情上分享一些其他信息。
可以帮助您的模式
许多开发者不确定应该对哪些代码部分编写测试。最简单的答案是:尝试为手动测试Web应用程序时检查的所有功能编写自动化测试。
在这种情况下,我们检查了数据库条目、验证消息和重定向,这是手动测试Web应用程序时的结果。这就是我们的自动化测试所覆盖的内容。
以下是一些帮助您规划测试的模式
1. 根据给定-当-那么
2. 安排-行为-断言
两者非常相似,您可以选择任何一种。其基本思想是
- 首先,您准备场景(添加现有数据库记录,登录用户等)
- 然后,您执行一个操作(访问URL,提交表单等)
- 最后,您验证结果/效果(数据库条目,会话调用,响应状态码等)
这种方法通常可以帮助您编写大部分测试用例。
(不太)复杂的内容
本文中涉及的是 功能测试。还有许多其他类型的测试(单元测试,功能测试,集成测试,验收测试等)。
不要急于学习/使用所有这些测试,您不必这么做。在需要的时候,您会自然感受到这种需要。
像 模拟 和 存根 这样的主题也属于同一类别。相信我,它们并非强制使用。但请记住,它们对中到大型项目来说非常方便。我们在项目中使用它们,无法离开它们。
PEST 注意事项
我们使用 PEST 来编写测试,但我决定不将其包括在这篇文章中,以保持内容的简洁。我希望(并且我相信)它会与 Laravel 开箱即发。
冲向月亮
我希望这篇文章能帮助您开始编写测试,并将这个习惯保持下去。如果您有任何问题,请在下面留言。希望这些工具给您带来更多的测试功能!
如果您有任何朋友也在找借口不开始编写测试,为什么不将这篇文章与他们分享,以给予他们推动呢?
祝酒敬礼。
driesvints, sophy, kkumar-gcc, sabotazh, rhecustein, gpeeyoo, wilker22, gjordanra, antonioushosny, mukeshchand123 和更多人喜欢这篇文章