如何测试 Laravel 框架:设置测试环境、单元和功能测试
Laravel 框架已经继承了 PHPUnit 单元测试组件。 PHPUnit 是 PHP 社区中使用最广泛、最受欢迎的测试框架之一。 PHPUnit 支持“单元测试”和“功能测试”。
会简单介绍PHPUnit“单元测试”和“功能测试”的基本用法。然后,解释如何在 Laravel 项目中创建“单元测试”和“功能测试”用例。
但是,在本文中,我们假设您已经对 PHPUnit 测试框架有了基本的了解,所以让我们重点讨论在 Laravel 中使用 PHPUnit 进行测试的主题。
单元测试和功能测试
如果您曾经与 PHPUnit 框架进行过交互,您应该知道它支持两种类型的功能 - “单元测试”和“功能测试”。
“单元测试”的目的是测试某个函数或方法的正确性。最重要的是,我们可以轻松实现代码逻辑的准确性。
如果在开发过程中发现一个功能包含多个逻辑步骤,最好将每个处理逻辑拆分为不同的方法,以确保每个方法和代码块都可以测试。
我们用最便捷的方式来看看单元测试的奥秘。
public function getNameAttribute($value)
{
return ucfirst($value);
}
如您所见,这种方法仅包含一个业务逻辑。方法中使用ucfirst函数先将字符转换为大写。
单元测试是为了保证各个独立单元中代码的正确性;进行功能测试是为了确保功能的正确性。简而言之,它涉及通过特定的测试用例来模拟用户访问应用程序的行为,以验证系统的完整性。
例如,我们可以为登录功能设置一个功能测试用例,包括以下步骤:
- 发起 GET 请求来访问登录页面;
- 看看我们是否在登录页面;
- 使用POST请求创建登录数据;
- 判断数据输入是否成功。
这是创建功能测试用例的秘诀。然后我们将创建具体的测试用例来解释如何在 Laravel 中使用“单元测试”和“功能测试”。
设置测试环境
创建测试模型
在开始创建测试用例之前,我们需要设置项目的依赖项以进行测试。
首先运行以下 artisan 命令来创建 Post 模板及其关联的迁移文件。
$ php artisan make:model Post --migration
上面的命令将为我们创建一个Post模型类和迁移文件。
帖子模板代码如下:
// app/Post.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
//
}
将在database/migrations文件夹中创建迁移文件YYYY_MM_DD_HHMMSS_create_posts_table.php。
帖子数据表存储帖子的标题。修改后的Post数据库迁移文件代码如下:
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePostsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('posts');
}
}
如您所见,我们使用新的$table->string('name')来存储帖子标题。接下来,运行数据库迁移命令,在数据库中创建对应的数据表。
$ php artisan migrate
创建数据库表后,我们需要在Post模型类中添加以下代码
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
/**
* Get the post title.
*
* @param string $value
* @return string
*/
public function getNameAttribute($value)
{
return ucfirst($value);
}
}
我们刚刚添加了输入法,其功能是更改帖子的标题。这就是我们想要在单元测试用例中测试的内容。以上就是Post模型中需要改变的地方。
创建测试控制器
接下来,我们需要创建一个文件名为 app/Http/Controllers/AccessorController.php 的控制器,该控制器将在接下来的功能测试中使用。
// app/Http/Controllers/AccessorController.php
namespace App\Http\Controllers;
use App\Post;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class AccessorController extends Controller
{
public function index(Request $request)
{
// get the post-id from request params
$post_id = $request->get("id", 0);
// load the requested post
$post = Post::find($post_id);
// check the name property
return $post->name;
}
}
在索引方法中,我们使用查询中的 id 参数从 Post 模型中查询帖子。
最后在route/web.php配置文件中定义相关路由。
Route::get('accessor/index', 'AccessorController@index');
安装好路由后,您可以通过http://your-laravel-site.com/accessor/index访问,看看该路由是否可以合法访问。
单元测试
在上一节中我们设置了测试环境。在本节中,我们将在 Laravel 中编写一个单元测试用例来测试 Post 模型。
值得庆幸的是,Laravel 提供了一个命令行工具来创建测试用例模板文件。
通过在命令行中执行以下命令来创建 AccessorTest 单元测试用例类。请注意,我们需要传递 --unit 参数选项来指示该命令正在创建单元测试用例。测试用例文件在tests/Unit 文件夹中创建。
$ php artisan make:test --unit
执行上述命令创建测试用例将创建一个名为tests/Unit/AccessorTest.php的文件。
// tests/Unit/AccessorTest.php
namespace Tests\Unit;
use Tests\TestCase;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class AccessorTest extends TestCase
{
/**
* A basic test example.
*
* @return void
*/
public function testExample()
{
$this->assertTrue(true);
}
}
将testExample方法替换为更实用的方法:
// tests/Unit/AccessorTest.php
namespace Tests\Unit;
use Tests\TestCase;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class AccessorTest extends TestCase
{
/**
* Test accessor method
*
* @return void
*/
public function testAccessorTest()
{
$db_post = DB::select('select * from posts where id = 1');
$db_post_title = ucfirst($db_post[0]->title);
$model_post = Post::find(1);
$model_post_title = $model_post->title;
$this->assertEquals($db_post_title, $model_post_title);
}
}
我们可以看到更新后的代码完全兼容了Laravel的编码方式。在类的开头,我们包含相关的依赖类文件。在 testAccessorTest 方法中,我们要检查 Post 模块中定义的 getNameAttribute 方法的有效性。
为了实现这样的测试功能,我们使用原生 SQL 通过 DB 类查询帖子,并将帖子的标题分配给 $db_post_title 变量。
之后,我们使用Post模型通过getNameAttribute方法获取同一篇文章的标题并将其设置为$model_post_title。
最后,使用assertEquals 方法比较两个变量是否相等。
以上就是如何在Laravel中使用单元测试。
功能测试
在本节中,我们将学习如何创建功能测试用例来“主动测试”之前创建的控制器。
使用下面给出的命令,我们将创建一个名为 AccessorTest 的功能测试用例。请注意,我们在这里没有使用 --unit 命令行选项,因此该命令将在 test/Feature 文件夹中创建一个“功能测试”实例。命令
$ php artisan make:test AccessorTest
将创建一个文件名为tests/Feature/AccessorTest.php的测试类。
// tests/Feature/AccessorTest.php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class AccessorTest extends TestCase
{
/**
* A basic test example.
*
* @return void
*/
public function testExample()
{
$this->assertTrue(true);
}
}
同样的方式,我们替换testExample方法。
// tests/Feature/AccessorTest.php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class AccessorTest extends TestCase
{
/**
* A basic test example.
*
* @return void
*/
public function testBasicTest()
{
$db_post = DB::select('select * from posts where id = 1');
$db_post_title = ucfirst($db_post[0]->name);
$response = $this->get('/accessor/index?id=1');
$response->assertStatus(200);
$response->assertSeeText($db_post_title);
}
}
熟悉功能测试的朋友应该对上面的代码很熟悉。
首先,我们仍然使用原生 SQL 使用 DB 类搜索帖子,并将帖子标题分配给 $db_post_title 变量。接下来,我们模拟对 /accessor/index?id=1 URI 的 GET 请求,并使用 $response 变量接收响应。
然后,如果响应代码为 200,我们将连接。将可用。确定标题是否与 $db_post_title 关联的方法是assertSeeText。
写完所有测试用例后。之后您需要执行这些测试用例。要在 Laravel 项目中运行 PHPUnit 测试用例,只需在项目目录中运行以下命令即可。
$ phpunit
此命令将运行项目中的所有测试用例。测试语句作为标准 PHPUnit 输出显示在控制台中。
总结
今天,我们讨论了如何在 Laravel 中实现 PHPUnit 测试用例。本文涵盖了PHPUnit“单元测试”和“功能测试”的基础知识。在工作中,我们需要根据实际情况对PHPUnit测试进行广泛的研究。
此外,我们还学习了如何使用 artisan 命令工具分别创建单元测试和功能测试的测试用例。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。