在Laravel中测试

不管您正在处理的应用程序是什么,测试都是一个重要且经常被忽略的方面,您应该给予应有的关注。 今天,我们将在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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值