前段时间我在自动化测试中出错。这是一个非常有趣的错误,与电子邮件地址验证有关,所以今天我将向您展示如何使用 Faker 和 freeEmail 功能进行测试。
开始
哦!我希望你熟悉 Laravel ??
我们的应用程序需要一个端点,用户可以在其中创建他们的帐户。他们将需要一个电子邮件地址、密码和昵称。我们走吧!
首先,我们将运行一些命令:
php artisan make:controller AuthController
php artisan make:request UserRegisterRequest
好现在我们将转到端点的控制器。
<?php
namespace App\Http\Controllers;
use App\Http\Requests\UserRegisterRequest;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Response;
class UserRegisterController extends Controller
{
public function register(UserRegisterRequest $request): JsonResponse
{
return new JsonResponse(
data: User::query()->create($request->validated()),
status: Response::HTTP_CREATED,
);
}
}
下一步 - 表格请求
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class UserRegisterRequest extends FormRequest
{
public function rules(): array
{
return [
'email' => 'required|email|max:255',
'password' => 'required',
'name' => 'required|max:200'
];
}
}
最后——路由
Route::group(['prefix' => 'auth', 'as' => 'auth.'], function () {
Route::post('/register', [AuthController::class, 'register'])->name('register');
});
完美的!
如您所见,我们使用电子邮件规则来检查电子邮件地址。这种方法是合适的,但有一个缺点——它不检查给定地址是否存在。
让我们写一个小测试。
<?php
namespace Tests\Feature;
use Tests\APITestCase;
class AuthControllerTest extends APITestCase
{
/** @test */
public function user_can_create_an_account()
{
// Send a request.
$response = $this->postJson(
route('auth.register'),
[
'email' => $this->faker->unique()->email,
'password' => 'Th1s1sVeryGoodP@ssword',
'name' => $this->faker->name,
]
);
// Check if the request was successful
$response->assertSuccessful();
}
}
结果:
好的现在让我们检查一下电子邮件规则有什么问题。获取相同的测试文件并更改一个参数:
<?php
namespace Tests\Feature;
use Tests\APITestCase;
class AuthControllerTest extends APITestCase
{
/** @test */
public function user_can_create_an_account()
{
// Send a request.
$response = $this->postJson(
route('auth.register'),
[
'email' => 'lukasz@hello', // <--- Here my friend!
'password' => 'Th1s1sVeryGoodP@ssword',
'name' => $this->faker->name,
]
);
// Check if the request was successful
$response->assertSuccessful();
}
}
结果如何?
经过?这是一个不完善的电子邮件规则,默认使用RFC参数。我们如何解决这个问题?
解决方案
我们需要在表单请求文件中的电子邮件规则中添加一个额外的参数。让我们添加它!
转到 UserRegisterRequest 并更新它。
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class UserRegisterRequest extends FormRequest
{
public function rules(): array
{
return [
'email' => 'required|email:rfc,dns|max:255',
'password' => 'required',
'name' => 'required|max:200'
];
}
}
伟大的。现在我们可以尝试再次运行测试。
极好的!这就是我们所需要的。现在,没有人可以使用奇怪的电子邮件,例如:“lukasz@hello”、“john@doe”等。
我们现在可以安全地返回到我们的测试文件并恢复更改。我们支持使用 Faker 生成电子邮件地址。
<?php
namespace Tests\Feature;
use Tests\APITestCase;
class AuthControllerTest extends APITestCase
{
/** @test */
public function user_can_create_an_account()
{
// Send a request.
$response = $this->postJson(
route('auth.register'),
[
'email' => $this->faker->unique()->email,
'password' => 'Th1s1sVeryGoodP@ssword',
'name' => $this->faker->name,
]
);
// Check if the request was successful
$response->assertSuccessful();
}
}
在这一点上,你可以完成你的任务,将更改推送到 git,创建一个 Pull Request,然后事情就完成了。
你确定吗?我不这么认为
我敢打赌,您会不时收到测试失败的信息。重新启动它会有所帮助,但对于在多个地方使用“电子邮件”验证规则的大型/大型应用程序,它可能会出现很大问题。
但问题是什么?
Faker->电子邮件
“电子邮件”函数会生成一个随机域的随机电子邮件地址,因此它有可能不存在——如果你明白我的意思的话。
文档中有示例:“ orval.treutel@blick.com ”、“ hickle.lavern@erdman.com ”
那么还有其他选择吗?
Faker->freeEmail
翻阅 Faker 文档,我找到了一个很好的解决方案:freeEmail。此函数使用允许的域列表生成电子邮件地址,因此我们可以假设该域将存在并且我们的规则将能够检查 DNS。
在FakerPHP包的Provider文件夹中,可以找到按地区排序的文件夹。对于英国(我在这里生活和工作),文件夹是en_GB。在文件夹中,我们将找到文件:
我们需要打开Internet.php文件,其中有一个名为 $freeEmailDomain 的静态属性。
protected static $freeEmailDomain = ['gmail.com', 'yahoo.com', 'hotmail.com', 'gmail.co.uk', 'yahoo.co.uk', 'hotmail.co.uk'];
凭良心,我们可以回到我们的测试并进行更改:
<?php
namespace Tests\Feature;
use Tests\APITestCase;
class AuthControllerTest extends APITestCase
{
/** @test */
public function user_can_create_an_account()
{
// Send a request.
$response = $this->postJson(
route('auth.register'),
[
'email' => $this->faker->unique()->freeEmail,
'password' => 'Th1s1sVeryGoodP@ssword',
'name' => $this->faker->name,
]
);
// Check if the request was successful
$response->assertSuccessful();
}
}