不管您正在处理的应用程序是什么,测试都是一个重要且经常被忽略的方面,您应该给予应有的关注。 今天,我们将在Laravel Web框架的上下文中进行讨论。
实际上,Laravel已经在核心本身中支持PHPUnit测试框架。 PHPUnit是整个PHP社区中最受欢迎的测试框架之一。 它允许您创建单元和功能测试。
我们将从单元和功能测试的基本介绍开始。 在继续进行时,我们将探索如何在Laravel中创建单元和功能测试。 我假设您熟悉PHPUnit框架的基础知识,因为我们将在本文的Laravel上下文中对其进行探索。
单元测试和功能测试
如果您已经熟悉PHPUnit框架,则应该知道可以将测试分为两种:单元测试和功能测试。
在单元测试中,您将测试给定功能或方法的正确性。 更重要的是,您可以在给定的时间测试代码的逻辑。
在开发中,如果发现实现的方法包含多个逻辑单元,则最好将其拆分为多个方法,以便每个方法都包含一个逻辑且可测试的代码。
让我们快速看一个示例,它是单元测试的理想案例。
public function getNameAttribute($value)
{
return ucfirst($value);
}
如您所见,该方法仅做一件事。 它使用ucfirst
函数将标题转换为以大写字母开头的标题。
单元测试用于测试单个逻辑代码单元的正确性,而功能测试则允许您测试特定用例的正确性。 更具体地说,它允许您模拟用户在应用程序中执行的操作,以运行特定的用例。
例如,您可以为某些登录功能实现功能测试用例,其中可能涉及以下步骤。
- 创建GET请求以访问登录页面。
- 检查我们是否在登录页面上。
- 生成POST请求以将数据发布到登录页面。
- 检查会话是否创建成功。
这就是您应该创建功能测试用例的方式。 从下一部分开始,我们将创建示例,演示如何在Laravel中创建单元和功能测试用例。
设置先决条件
在继续进行实际测试之前,我们需要设置一些将在测试中使用的东西。
我们将开始创建Post模型和相关的迁移。 继续并运行以下artisan命令以创建Post
模型。
$php artisan make:model Post --migration
上面的命令应该创建Post
模型类以及相关的数据库迁移。
Post
模型类应如下所示:
<?php
// 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
数据库迁移文件的代码,如下所示。
<?php
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')
列来存储帖子的标题。 接下来,您只需要运行migrate命令即可在数据库中实际创建该表。
$php artisan migrate
另外,让我们用以下内容替换Post
模型。
<?php
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);
}
}
我们刚刚添加了accessor
方法,该方法可以修改帖子的标题,而这正是我们将在单元测试用例中测试的内容。 就Post
模型而言就是这样。
接下来,我们将在app/Http/Controllers/AccessorController.php
创建一个控制器文件。 在以后的阶段中创建功能测试用例时,这对我们很有用。
<?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;
}
}
在index
方法中,我们从请求参数中检索发布ID,然后尝试加载发布模型对象。
让我们也在routes/web.php
文件中添加一个关联的路由。
Route::get('accessor/index', 'AccessorController@index');
有了这个,您可以运行http://your-laravel-site.com/accessor/index URL来查看它是否按预期工作。
单元测试
在上一节中,我们进行了初始设置,这将在本节和后续节中对我们有用。 在本节中,我们将创建一个示例,以演示Laravel中的单元测试的概念。
与往常一样,Laravel提供了一个artisan命令,使您可以创建单元测试用例的基本模板类。
运行以下命令以创建AccessorTest
单元测试用例类。 需要特别注意的是,我们传递了--unit
关键字来创建单元测试用例,并将其放置在tests/Unit
目录下。
$php artisan make:test AccessorTest --unit
然后应该在tests/Unit/AccessorTest.php
创建以下类。
<?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);
}
}
让我们用一些有意义的代码替换它。
<?php
// tests/Unit/AccessorTest.php
namespace Tests\Unit;
use Tests\TestCase;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
use App\Post;
class AccessorTest extends TestCase
{
/**
* Test accessor method
*
* @return void
*/
public function testAccessorTest()
{
// load post manually first
$db_post = DB::select('select * from posts where id = 1');
$db_post_title = ucfirst($db_post[0]->name);
// load post using Eloquent
$model_post = Post::find(1);
$model_post_title = $model_post->name;
$this->assertEquals($db_post_title, $model_post_title);
}
}
如您所见,代码与核心PHP中的代码完全相同。 我们刚刚导入了Laravel特定的依赖关系,使我们可以使用所需的API。 在testAccessorTest
方法中,我们应该测试Post
模型的getNameAttribute
方法的正确性。
为此,我们从数据库中获取了一个示例帖子,并在$db_post_title
变量中准备了预期的输出。 接下来,我们使用getNameAttribute
模型加载相同的帖子,该模型也执行getNameAttribute
方法,以准备帖子标题。 最后,我们使用assertEquals
方法像往常一样比较两个变量。
这就是在Laravel中准备单元测试用例的方法。
功能测试
在本节中,我们将创建功能测试用例,以测试我们之前创建的控制器的功能。
运行以下命令以创建AccessorTest
功能测试用例类。 由于我们没有使用--unit
关键字,因此它将被视为功能测试用例,并将其放置在tests/Feature
目录下。
$php artisan make:test AccessorTest
它将在tests/Feature/AccessorTest.php
创建以下类。
<?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);
}
}
让我们用以下代码替换它。
<?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;
use Illuminate\Support\Facades\DB;
class AccessorTest extends TestCase
{
/**
* A basic test example.
*
* @return void
*/
public function testBasicTest()
{
// load post manually first
$db_post = DB::select('select * from lvl_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);
}
}
同样,对于具有功能测试经验的人员,该代码应该看起来很熟悉。
首先,我们从数据库中获取示例帖子,并在$db_post_title
变量中准备预期的输出。 之后,我们尝试模拟/accessor/index?id=1
GET请求,并在$response
变量中获取该请求的$response
。
接下来,我们尝试将$response
变量中的响应代码与期望的响应代码进行匹配。 在我们的例子中,它应该是200,因为我们应该为GET请求获得一个有效的响应。 此外,响应中应包含以大写字母开头的标题,而这正是我们试图使用assertSeeText
方法进行匹配的标题。
这就是功能测试用例的一个例子。 现在,我们拥有可以进行测试的所有内容。 让我们继续在应用程序的根目录中运行以下命令以运行所有测试。
$phpunit
那应该在您的应用程序中运行所有测试。 您应该看到一个标准的PHPUnit输出,该输出显示应用程序中测试和断言的状态。
至此,我们到了本文的结尾。
结论
今天,我们探讨了在Laravel中进行测试的细节,Laravel已经在其核心中支持PHPUnit。 本文从单元和功能测试的基本介绍开始,随着我们的前进,我们在Laravel环境中探索了测试的具体细节。
在此过程中,我们创建了一些示例,这些示例演示了如何使用artisan命令创建单元和功能测试用例。
如果您只是开始使用Laravel或希望通过扩展来扩展您的知识,网站或应用程序,我们可以在Envato Market中提供多种学习方法 。
不要犹豫,使用下面的提要来表达您的想法!
翻译自: https://code.tutsplus.com/tutorials/testing-in-laravel--cms-30465