支持Laravel.io的持续发展 →

你为什么不先写测试?

8 Aug, 2022 8 min read

看看在Laravel中开始自动化测试有多么容易

Cover

关于为什么你应该为你的代码编写测试,有数百篇文章。为什么你应该这样 写测试 对于你的代码。而且我假设你已经阅读了很多遍。

许多开发者认识到编写测试的重要性,但他们只是没有开始。

为什么不

主要是因为一些误解。

  • 他们面对着做错事的恐惧。
  • 他们认为他们还不够好(现在)来写测试。
  • 他们不确定哪种类型的测试适用于他们的项目。

作为一个曾经经历过的人,让告诉我,这些事情是暂时的。一旦你开始编写测试,所有这些都将成为过去。

为什么不今天

如果我告诉你,开始测试只需要你5-10分钟的时间,你会介意现在开始吗?

让今天是新事物的开始。

  • 威廉·莎士比亚

好的。所以让我们从一个Laravel应用程序开始我们的测试之旅。你可以使用一个现有的网络应用程序或创建一个新的。

实际上,你可以跟随这篇文章进行任何其他编程语言/框架,因为我们只讨论高层次的内容。

Laravel的默认测试

Laravel自带了一些测试。打开你的终端,输入

php artisan test

如果你没有在你的网络应用中做任何更改,你将会看到类似的内容

First tests with Laravel

太好了,我们有一个完美的起点。现在让我们写自己的测试。

一些网络应用代码

如果您有一个全新的Laravel Web应用程序,请在编写第一个测试之前,将其追加到routes/web.php文件中。

use App\Models\User;
use Illuminate\Http\Request;

// existing code...

Route::post('/users', function (Request $request) {
    $validated = $request->validate([
        'name' => ['required', 'string', 'max:255'],
        'email' => ['required', 'email', 'max:255'],
        'password' => ['required', 'confirmed'],
    ]);

    User::create($validated);

    return back()->with('success', 'User created successfully.');
});

以下代码中发生了以下事情:

  1. 验证表单数据。
  2. 在数据库中创建用户。
  3. 用户成功后将其重定向回并显示成功消息。

我们的测试应该覆盖所有这些。

创建新的测试文件

我们将从创建一个新测试文件开始。请在您的终端执行以下命令

php artisan make:test UserTest

新的测试文件应该创建在tests/Feature/UserTest.php中。

注意 - 重置数据库

如果您编写了与数据库交互的代码和测试,您应该在每次测试后重置数据库,以确保一个测试不会影响另一个测试的结果。Laravel通过提供可以添加到测试类中的特性来使这个过程变得非常简单。

请将以下特性添加到UserTest.php文件中

use Illuminate\Foundation\Testing\LazilyRefreshDatabase;

class UserTest extends TestCase
{
    use LazilyRefreshDatabase;

    // existing code...

完成这些后,我们可以编写测试了。

您的第一个测试 - 快速路径

默认测试文件已经覆盖了对GET请求的测试。因此,我们可以直接编写对POST请求的测试。

当用户从浏览器中提交表单时,会提交一个包含输入值和值的POST请求。我们将要在测试中模拟相同的过程。

请在UserTest.php文件中追加以下代码

    // existing code...

    public function test_new_user_can_be_added()
    {
        $response = $this->post('/users', [
            'name' => 'Gaurav',
            'email' => '[email protected]',
            'password' => '123456',
            'password_confirmation' => '123456',
        ]);

        $response->assertRedirect('/')
            ->assertSessionHas('success', 'User created successfully.');

        $this->assertDatabaseHas('users', [
            'name' => 'Gaurav',
            'email' => '[email protected]',
        ]);
    }

Laravel提供了一个简单的从测试文件发送POST请求的方法,使用post()方法。使用它,我们发起请求并验证用户详细信息被添加到数据库中,并且响应重定向到带有适当消息的会话中。

这不是很简单吗?让我们再来一个。

验证测试

为什么不添加一个测试来确保我们的验证按预期工作呢?请在UserTest.php文件中追加以下代码

    // existing code...

    public function test_new_user_data_is_validated()
    {
        $response = $this->post('/users', [
            'name' => '',
            'email' => 'not_email_format',
            'password' => '123456',
            'password_confirmation' => '456789',
        ]);

        $response->assertStatus(302)
            ->assertSessionHasErrors(['name', 'email', 'password']);
    }

在这里,我们为表单输入传递无效数据,并确认(断言)存在重定向响应(HTTP状态码302)以及会话中的验证错误。

测试唯一的电子邮件地址

业务需求是,每个用户的电子邮件地址必须是唯一的,因此让我们添加一个测试来验证这一点。将此测试添加到UserTest.php文件中

    // existing code...

    public function test_new_user_with_same_email_cannot_be_added()
    {
        User::factory()->create([
            'email' => '[email protected]',
        ]);

        $response = $this->post('/users', [
            'name' => 'Gaurav',
            'email' => '[email protected]',
            'password' => '123456',
            'password_confirmation' => '123456',
        ]);

        $response->assertStatus(302)
            ->assertSessionDoesntHaveErrors(['name', 'password'])
            ->assertSessionHasErrors(['email']);
    }

此测试使用Laravel工厂将用户添加到数据库中,然后尝试使用相同的电子邮件地址发起POST请求。让我们运行测试并查看结果。

A failing test

哎呀,失败了。原因是什么呢?我们在代码中遗漏了添加唯一验证。

修复

现在,您的测试正在引导开发。(是的,TDD!)

请对routes/web.php文件进行以下更新

-        'email' => ['required', 'email', 'max:255'],
+        'email' => ['required', 'email', 'max:255', 'unique:users'],

更新后,给自己鼓掌,然后再次运行测试(php artisan test

Passing tests

还有更多吗?

您意识到您现在是写自动化测试的开发者了吗?祝贺您!

Congrats!

需要更多示例?请查看这个目录,里面包含了官方Laravel仓库中与各种模块相关的测试。

本文的目标只是帮助您开始编写测试。并不是涵盖不同的使用情况或场景。因此,我限制了实际编码的范围,并想在可以帮助您继续前进的 few 事情上分享一些其他信息。

可以帮助您的模式

许多开发者不确定应该对哪些代码部分编写测试。最简单的答案是:尝试为手动测试Web应用程序时检查的所有功能编写自动化测试。

在这种情况下,我们检查了数据库条目、验证消息和重定向,这是手动测试Web应用程序时的结果。这就是我们的自动化测试所覆盖的内容。

以下是一些帮助您规划测试的模式

1. 根据给定-当-那么

2. 安排-行为-断言

两者非常相似,您可以选择任何一种。其基本思想是

  1. 首先,您准备场景(添加现有数据库记录,登录用户等)
  2. 然后,您执行一个操作(访问URL,提交表单等)
  3. 最后,您验证结果/效果(数据库条目,会话调用,响应状态码等)

这种方法通常可以帮助您编写大部分测试用例。

(不太)复杂的内容

本文中涉及的是 功能测试。还有许多其他类型的测试(单元测试,功能测试,集成测试,验收测试等)。

不要急于学习/使用所有这些测试,您不必这么做。在需要的时候,您会自然感受到这种需要。

模拟存根 这样的主题也属于同一类别。相信我,它们并非强制使用。但请记住,它们对中到大型项目来说非常方便。我们在项目中使用它们,无法离开它们。

PEST 注意事项

我们使用 PEST 来编写测试,但我决定不将其包括在这篇文章中,以保持内容的简洁。我希望(并且我相信)它会与 Laravel 开箱即发。

冲向月亮

我希望这篇文章能帮助您开始编写测试,并将这个习惯保持下去。如果您有任何问题,请在下面留言。希望这些工具给您带来更多的测试功能!

如果您有任何朋友也在找借口不开始编写测试,为什么不将这篇文章与他们分享,以给予他们推动呢?

祝酒敬礼。

上次更新1年前。

driesvints, sophy, kkumar-gcc, sabotazh, rhecustein, gpeeyoo, wilker22, gjordanra, antonioushosny, mukeshchand123 和更多人喜欢这篇文章

26
喜欢这篇文章吗? 让作者知道并且给他们鼓掌!
gauravmak (Gaurav Makhecha) 全职自由职业者 | Laravel,Vue.js 粉丝 | 分享社区更新及我的自由职业、生产力、及其他方面的学习心得

您可能会喜欢的其他文章

March 11th 2024

如何使用 Larastan 将您的 Laravel 应用从0到9

在 Laravel 应用执行之前就能发现其中的漏洞,这是可能的,要归功于 Larastan,它...

阅读文章
2024年7月19日

无需 Traits 标准化 API 响应

我发现大多数用于 API 响应的库都是通过 traits 实现的,并且...

阅读文章
2024年7月17日

在 Laravel 项目中通过 Discord 通知收集反馈

如何在 Laravel 项目中创建反馈模块,当收到消息时如何接收 Discord 通知...

阅读文章

我们想感谢这些 极其出色的公司 对我们的支持

您的标志在这里?

Laravel.io

Laravel 的问题解决、知识分享和社区建设的门户。

© 2024 Laravel.io - 版权所有。