在 Laravel 中为 REST API 实施功能测试
介绍
使用测试用例会让您感到害怕吗?您是否正在寻找一个简单的教程来开始在 Laravel 中进行功能测试?然后,我们坚持让您坚持这个循序渐进的指南,以消除您的疑虑并学习在 Laravel 应用程序中进行测试。
Laravel 中的功能测试:什么、为什么以及如何?
Laravel 中的功能测试是什么?
在开发应用程序时,您往往会担心在执行功能或模块时代码会被破坏。为了避免出现这种情况,在您的应用程序中实施测试很重要。
特性测试是最常用和最重要的测试类型之一。它允许您测试应用程序代码的主要部分,这些代码具有相互交互的对象、HTTP 请求、JSON 等。
为什么在 Laravel 中进行功能测试?
使工作顺畅
避免破坏整个应用程序
代码可维护性
应用稳定性
应用程序崩溃时轻松调试
轻松确定应用程序崩溃背后的原因
最好的部分是测试是自动化的。它会发现代码中的漏洞并允许您正确开发功能。
Laravel 中的特性测试是如何工作的?
Laravel 支持 PHPUnit 测试。您的 Web 应用程序附带一个 phpunit.xml 文件,其中包含测试 Laravel 应用程序所需的所有设置。您的 phpunit.xml 文件设置了用于测试的 laravel 环境。因此无需创建新的 XML 文件!
下面是 Laravel 8 框架附带的示例 phpunit.xml 文件。
<?xml version="1.0" encoding="UTF-8"?><phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="供应商/autoload.php"
颜色=“真”>
<测试套件>
<测试套件名称="单元">
<目录后缀="Test.php">./tests/Unit</directory>
</测试套件>
<测试套件名称="功能">
<目录后缀="Test.php">./tests/Feature</directory>
</测试套件>
</测试套件>
<覆盖过程UncoveredFiles="true">
<包括>
<目录后缀=".php">./app</directory>
</include>
</覆盖>
<php>
<server name="APP_ENV" value="testing"/>
<服务器名称="BCRYPT_ROUNDS" 值="4"/>
<server name="CACHE_DRIVER" value="array"/>
<server name="MAIL_MAILER" value="array"/>
<server name="QUEUE_CONNECTION" value="sync"/>
<server name="SESSION_DRIVER" value="array"/>
<server name="TELESCOPE_ENABLED" value="false"/>
</php></phpunit>
初始设置
对于本教程,我们将使用酒店评论 api。终端用户可以对酒店进行点评,可以对酒店点评进行添加、更新、删除以及酒店点评列表操作。
通过以下命令创建 laravel 应用程序
作曲家创建项目 --prefer-dist laravel/laravel hotel_review_api_testcd hotel_review_api_test
打开 .env 文件并更新数据库详细信息。
DB_CONNECTION=mysqlDB_HOST=127.0.0.1DB_PORT=3306DB_DATABASE=hotel_test_apiDB_USERNAME=root数据库密码=
创建模型和迁移
对于模型,运行以下命令。
php artisan make:model 酒店php artisan make:model 评论
对于迁移,请运行以下命令。
php artisan make:migration create_hotel_table php artisan make: 迁移 create_review_table
发展。维持。优化。部署 - 与 Bacancy!
您是否正在寻找熟练的开发人员来构建高度优化的应用程序?与我们联系以聘请 Laravel 开发人员。联系最好的,得到最好的!时期!
创建数据库表
现在通过下面提到的代码更新迁移文件。
我们将更新用户表、酒店表和评论表文件。按照指示添加列。您可以根据需要编辑列。
用户表
公共功能向上(){
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id')->unsinged();
$table->string('名字');
$table->string('email')->unique();
$表->时间戳();
});
}
酒店餐桌
公共功能向上(){
Schema::create('hotels', function (Blueprint $table) {
$table->bigIncrements('id')->unsinged();
$table->string('名字', 100);
$table->text('地址')->nullable();
$table->float('star')->nullable();
$table->tinyInteger('active')->default(1)->comment = '1 = active,0 = Inactive';
$表->时间戳();
$表->softDeletes();
});}
审查表
公共功能向上(){
Schema::create('reviews', function (Blueprint $table) {
$table->bigIncrements('id')->unsinged();
$table->string('标题', 100);
$table->text('描述', 100);
$table->unsignedBigInteger('user_id')->nullable();
$table->unsignedBigInteger('hotel_id')->nullable();
$表->时间戳();$表->softDeletes(); $table->foreign('user_id')->references('id')->on('users')->onDelete('CASCADE')->onUpdate('CASCADE'); $table->foreign('hotel_id')->references('id')->on('hotels')->onDelete('CASCADE')->onUpdate('CASCADE');
});
}
运行迁移
php 工匠迁移
生成 API 路由和 CRUD 业务逻辑
打开 \routes\api.php 并使用以下代码片段为我们的 API 生成路由。我们将有五个 API。
路线\ api.php
// 获取所有活跃的酒店数据Route::get('酒店', [HotelController::class,'getAllHotelData']);
// 获取特定酒店数据Route::get('hotel/{hotel_id}', [HotelController::class,'getHotelDataById']);
// 添加新的酒店评论Route::post('save-hotel-review', [HotelController::class,'storeHotelReviewData']);
// 更新酒店评论Route::put('update-hotel-review/{review_id}', [HotelController::class,'updateHotelReviewData']);
// 删除酒店评论Route::delete('review/{review_id}', [HotelController::class,'deleteHotelReview']);
增删改查业务逻辑
对于CRUD操作的业务逻辑,新建一个HotelController.php文件。我们不会指定 API 的代码片段。但是如果您想看一下,这里是指向HotelController.php的 Github 链接。我们将遵循这五个 API。
/api/hotels: 返回所有酒店数据
/api/hotel/{hotel_id}:返回特定酒店的数据
/api/save-hotel-review: 添加酒店评论
/api/update-hotel-review/{review_id}:更新酒店评论
/api/review/{review_id}: 删除酒店评论
在 Laravel 应用程序中创建功能测试
本节将为我们的应用程序创建我们的第一个功能测试。运行以下命令以生成一个名为 HotelTest 的用于测试的文件。
php artisan make:test HotelTest
该命令将使用以下代码在测试 > 功能文件夹中创建一个名为 HotelTest.php 的新文件。
断言真(真);
}}
更新 HotelTest.php
我们将为应用程序的每个单元编写测试。我们进行了书面测试以确保:可以添加、删除、更新和列出有效的酒店评论。使用以下代码更新HotelTest.php 。
<?php
命名空间测试\功能;
使用测试\测试用例;使用 App\Models\Hotel;使用 App\Models\User;使用 App\Models\Review;使用碳\碳;
获取特定酒店的活跃酒店数据
类 HotelTest 扩展了 TestCase{
/**
* 基于酒店ID获取活跃酒店数据的功能测试
*
* @return 无效
*/
公共功能 test_get_active_hotel_by_id()
{
$hotel_id = Hotel::where('active', 1)->get()->random()->id;
$response = $this->get('/api/hotel/' . $hotel_id)
->assertStatus(200)
->assertJsonStructure(
[
'代码',
'信息',
'数据'=> [
'ID',
'姓名',
'星星',
'评论'=> [
'*' => [
“ID”,
“标题”,
“描述”,
“作者”,
“创建”,
“更新时间”
],
]
],
]
);
}
获取所有活跃的酒店数据
/**
* 获取所有活跃酒店数据的功能测试
*
* @return 无效
*/
公共功能 test_get_all_active_hotels()
{
$response = $this->get('/api/hotels')
->assertStatus(200)
->assertJsonStructure(
[
'代码',
'信息',
'数据'=> [
'*' => [
“ID”,
“姓名”,
“地址”,
“星星”,
“创建”,
“更新时间”,
“积极的”,
“评论”=> [
'*' => [
“ID”,
“标题”,
“描述”,
“作者”,
“创建”,
“更新时间”
],
],
],
],
]
);
}
获取特定酒店的所有非活动酒店数据
/**
* 基于酒店ID获取非活跃酒店数据的功能测试
*
* @return 无效
*/
公共功能 test_for_get_inactive_hotel_by_id()
{
$hotel_id = Hotel::where('active', 0)->get()->random()->id;
$response = $this->get('/api/hotel/' . $hotel_id)
->assertStatus(200)
->assertJsonStructure(
[
'代码',
'信息',
]
);
}
添加新评论
/**
* 添加新评论的功能测试
*
* @return 无效
*/
公共功能 test_for_add_hotel_review()
{
$user = 用户::创建([
'名称' => 兰德(),
'电子邮件' => 兰德()。' .abc@xyz.com ',
'created_at' => Carbon::now(),
'updated_at' => Carbon::now(),
]);
//$user = User::create($userData);
$酒店=酒店::创建([
'名称' => 兰德(),
'明星'=> 2,
'address' => '市政厅对面,Nr。Sakar II & IV, Ashram Rd, Ellisbridge, Ahmedabad, Gujarat 380006',
'活动'=> 0,
'created_at' => Carbon::now(),
'updated_at' => Carbon::now(),
]);
$有效载荷= [
"hotel_id" => $hotel->id,
"user_id" => $user->id,
"review_title" => "测试",
“review_data”=>“测试说明”
];
$this->json('POST', 'api/save-hotel-review', $payload)
->assertStatus(200)
->assertJson([
'代码'=>'200',
'message' => '酒店评论已保存。',
]);
}
更新具体评论
/**
* 基于评论 ID 更新评论的功能测试
*
* @return 无效
*/
公共功能 test_for_update_hotel_review()
{
$user = 用户::创建([
'名称' => 兰德(),
'电子邮件' => 兰德()。' .abc@xyz.com ',
'created_at' => Carbon::now(),
'updated_at' => Carbon::now(),
]);
//$user = User::create($userData);
$酒店=酒店::创建([
'名称' => 兰德(),
'明星'=> 2,
'address' => '市政厅对面,Nr。Sakar II & IV, Ashram Rd, Ellisbridge, Ahmedabad, Gujarat 380006',
'活动'=> 0,
'created_at' => Carbon::now(),
'updated_at' => Carbon::now(),
]);
$hotelReview = 评论::创建([
'title' => '好莱坞好酒店',
'description' => 'HollywoodInn 是一家非常不错的酒店。',
'user_id' => $user->id,
'hotel_id' => $hotel->id,
'created_at' => Carbon::now(),
'updated_at' => Carbon::now(),
]);
$有效载荷= [
"hotel_id" => $hotel->id,
"user_id" => $user->id,
"review_title" => "测试",
“review_data”=>“测试说明”
];
$this->json('PUT', 'api/update-hotel-review/' . $hotelReview->id, $payload)
->assertStatus(200)
->assertJson([
'代码'=>'200',
'message' => '酒店评论已更新。',
]);
}
删除酒店评论数据
/**
* 删除酒店评论数据的功能测试
*
* @return 无效
*/
公共功能 test_for_delete_hotel_review()
{
$user = 用户::创建([
'名称' => 兰德(),
'电子邮件' => 兰德()。' .abc@xyz.com ',
'created_at' => Carbon::now(),
'updated_at' => Carbon::now(),
]);
$酒店=酒店::创建([
'名称' => 兰德(),
'明星'=> 2,
'address' => '市政厅对面,Nr。Sakar II & IV, Ashram Rd, Ellisbridge, Ahmedabad, Gujarat 380006',
'活动'=> 0,
'created_at' => Carbon::now(),
'updated_at' => Carbon::now(),
]);
$hotelReview = 评论::创建([
'title' => '好莱坞好酒店',
'description' => 'HollywoodInn 是一家非常不错的酒店。',
'user_id' => $user->id,
'hotel_id' => $hotel->id,
'created_at' => Carbon::now(),
'updated_at' => Carbon::now(),
]);
$this->json('DELETE', 'api/review/' . $hotelReview->id)
->assertStatus(200)
->assertJson([
'代码'=>'200',
'message' => '酒店评论删除成功。',
]);
}
存储新的审核所需数据
/**
* 存储新审核所需数据的功能测试
*
* @return 无效
*/
公共功能 test_for_add_hotel_review_required_fields()
{
$this->json('POST', 'api/save-hotel-review')
->assertStatus(200)
->assertJson([
'代码'=>'401',
'message' => '酒店 ID 字段是必需的。用户 ID 字段是必需的。评论标题字段是必需的。评论数据字段是必需的,
]);
}
更新审核所需数据
/**
* 更新审核所需数据的功能测试
*
* @return 无效
*/
公共功能 test_for_update_hotel_review_required_fields()
{
$user = 用户::创建([
'名称' => 兰德(),
'电子邮件' => 兰德()。' .abc@xyz.com ',
'created_at' => Carbon::now(),
'updated_at' => Carbon::now(),
]);
//$user = User::create($userData);
$酒店=酒店::创建([
'名称' => 兰德(),
'明星'=> 2,
'address' => '市政厅对面,Nr。Sakar II & IV, Ashram Rd, Ellisbridge, Ahmedabad, Gujarat 380006',
'活动'=> 0,
'created_at' => Carbon::now(),
'updated_at' => Carbon::now(),
]);
//$hotel = User::create($hotelData);
$hotelReview = 评论::创建([
'title' => '好莱坞好酒店',
'description' => 'HollywoodInn 是一家非常不错的酒店。',
'user_id' => $user->id,
'hotel_id' => $hotel->id,
'created_at' => Carbon::now(),
'updated_at' => Carbon::now(),
]);
$this->json('PUT', 'api/update-hotel-review/' . $hotelReview->id)
->assertStatus(200)
->assertJson([
'代码'=>'401',
'message' => '酒店 ID 字段是必需的。用户 ID 字段是必需的。评论标题字段是必需的。评论数据字段是必需的,
]);
}
更新不存在的评论
/**
* 更新不存在的评论的功能测试
*
* @return 无效
*/
公共功能 test_for_update_hotel_review_that_not_exist()
{
//数据库中不存在的评论id
$reviewId = random_int(100000, 999999);
$有效载荷= [
"hotel_id" => random_int(100, 999),
"user_id" => random_int(100, 999),
"review_title" => "测试",
“review_data”=>“测试说明”
];
$this->json('PUT', 'api/update-hotel-review/' . $reviewId, $payload)
->assertStatus(200)
->assertJson([
'代码'=>'401',
'message' => '无效的酒店 ID 或用户 ID 或评论 ID',
]);
}
删除不存在的评论
/**
* 删除不存在的评论的功能测试
*
* @return 无效
*/
公共功能 test_for_delete_review_that_not_exist()
{
//数据库中不存在的评论id
$reviewId = random_int(100000, 999999);
$this->json('DELETE', 'api/review/' . $reviewId)
->assertStatus(200)
->assertJson([
'代码'=>'401',
'message' => '没有找到评论,请重试',
]);
}}
解释
test_get_all_active_hotels() 是为应用程序运行测试的主要函数。现在,我们在这个函数中测试什么?它测试所有活跃酒店的数据,这些数据将由端点 /api/hotels 返回。
$this->get('/api/hotels') 获取酒店数据
->assertStatus(200) 验证从 API 返回的 HTTP 状态代码。
->assertJsonStructure( … ); 验证端点返回的响应的 JSON 结构。下面是 API 的示例响应。
{
“代码”:“200”,
"message": "酒店数据",
“数据”: [
{
“编号”:1,
"name": "海亚特",
“地址”:“17/A, Ashram Rd, Usmanpura, Ahmedabad, Gujarat 380014”,
“星”:4,
"create_at": "11/Jan/2022 15:40:56",
"update_at": "11/Jan/2022 15:40:56",
“活跃”:“活跃”,
“审查”: [
{
“编号”:2,
"title": "凯悦酒店",
"description": "Hyaat 是一家非常不错的酒店。",
“作者”:“帕特”,
"create_at": "11/Jan/2022 15:40:56",
“update_at”:“2022 年 1 月 11 日 15:40:56”
}
]
},
] }
test_get_active_hotel_by_id根据酒店ID验证酒店点评数据。
test_for_get_inactive_hotel_by_id在传递非活动酒店 ID 时验证酒店评论数据。
test_for_add_hotel_review在所有数据都通过 valid 时验证添加酒店评论功能
当所有数据通过有效时,函数test_for_update_hotel_review验证更新后的酒店评论功能
函数test_for_delete_hotel_review在传递有效酒店评论 ID 时验证删除酒店评论功能。
函数test_for_add_hotel_review_required_fields在调用添加新酒店评论 API 时没有数据通过时验证必填字段验证。
函数test_for_update_hotel_review_required_fields在更新调用的新酒店评论 API 时没有数据通过时验证必填字段验证。
函数test_for_update_hotel_review_that_not_exist验证通过的酒店评论 ID 在更新酒店评论功能的数据库中不存在的情况。
函数test_for_delete_review_that_not_exist验证通过的酒店评论 ID 在删除酒店评论功能的数据库中不存在的情况。
其他 assertJson 如下
assertTrue() 和 assertFalse()
assertEquals() 和 assertNull()
assertContains()、assertCount() 和 assertEmpty()
->assertJson([
'代码'=>'401',
'message' => '没有找到评论,请重试',
]);
assertJson 测试 JSON 结果是否符合我们的预期意味着从 API 返回相同的输出 JSON,就像比较两个字符串一样。
assertTrue() 和 assertFalse() 允许您断言一个值等于 true 或 false。这意味着它们非常适合测试返回布尔值的方法。
assertEquals() 用于比较变量的实际值和期望值。与 assertTrue()、assertFalse() 和 assertNull() 不同,assertEquals() 有两个参数。第一个是期望值,第二个是实际值。
assertContains() 断言提供的数组中存在预期值,assertCount() 断言数组中的项目数与指定的数量匹配,assertEmpty() 断言提供的数组为空。
访问Laravel 文档以了解其他功能。
运行测试用例
在根文件夹中使用以下命令运行测试用例。
php工匠测试
Github 存储库:Laravel 示例中的功能测试
您可以访问源代码并克隆存储库以使用代码。
结论
我希望在 Laravel 中针对 REST API 实施功能测试的教程能够如您所愿地为您服务。我们为像您这样的爱好者准备了几个 Laravel 教程。如果您想学习和探索有关 Laravel 的更多信息,请访问Laravel 教程页面。
还没有评论,来说两句吧...