Laravel 中的行为驱动开发

发布于 作者

Behavioural Driven Development in Laravel image

BDD 或行为驱动开发,是许多组织中流行的测试方法,并且在将跨团队的测试工作统一起来方面拥有经过验证的成功记录。但问题仍然是,如何在 Laravel 中实现这一点,而无需学习新的测试框架或新的语言语法,例如 Gherkin

作为一个企业,能够以易于阅读的方式定义流程,并在我们的测试套件中体现出来,这是一个巨大的优势。就像领域驱动设计允许我们为代码创建无所不在的语言一样,BDD 将使我们能够为测试拥有无所不在的语言。

让我们来浏览一些 BDD 测试的示例,然后对其进行分解。假设我们有一个具有注册表单的 Web 应用程序。当完成此表单后,我们希望用户将被注册,并且他们应该自动登录。让我们在典型的功能测试中看看这一点

it('allows a user to register for an account', function (string $email) {
expect(
User::query()->count(),
)->toEqual(0);
 
post(
route('register'),
['name' => 'test', 'email' => $email, 'password' => 'password']
)->assertRedirect(route('dashboard'));
 
expect(
User::query()->count(),
)->toEqual(1);
})->with('emails');

这是一个使用 pestPHP 测试此端点的简单示例,它复制表单提交。如您所见,作为开发人员,如果您习惯于使用 pest 进行测试,这相对容易理解。但是,您的 QA 工程师会对此感到困惑,因为他们不习惯使用 pestPHP,而且它没有他们理解的语法。

我们如何重构它以使用 BDD 和我们的 QA 工程师和更广泛的团队可能理解的语法?幸运的是,pestPHP 插件将允许我们使用“给定、何时、然后”方法,这在 BDD 世界中很常见。这是 给定、何时、然后插件,并且入门非常简单。运行以下 composer 命令安装此插件

composer require milroyfraser/pest-plugin-gwt --dev

从这里开始,我们可以开始为 BDD 编写具体的测试。此时我们要牢记的一件事是,我们是想替换我们的测试,还是想让 BDD 增强我们当前的测试套件?我建议改进现有的测试套件,以避免丢失有价值的测试。

让我们以我最近遇到的一个例子为例。我并没有为我的 Laravel 应用程序使用任何特定的 Auth 包。相反,我需要创建一个自定义身份验证流程 - 使用一次性密码。我的注册表单是一个 Livewire 组件,它为我处理逻辑。所以,让我们先写一个功能测试,以确保我们的组件正常工作。

it('will submit the form and create a new user', function (string $email) {
Livewire::test(
RegisterForm::class,
)->set(
'name', 'test',
)->set(
'email', $email,
)->set(
'password', 'password',
)->call(
'submit'
)->assertHasNoErrors(
['name', 'email', 'password']
);
})->with('emails');

我们正在测试我们是否可以填写并提交表单。我们可以在其中添加关于此的预期结果,以确保用户在数据库中创建,但我们可以在此简化我们的功能测试,并将其中一些逻辑转移到集成测试中。

在我们的例子中,就像我的大部分代码一样,我在 Action 类中执行逻辑,所以将它转移是有意义的。我通常为所有需要执行的读写操作创建单个 Action 类,以便 CLI、Web 和 API 可以使用所有类似的逻辑 - 唯一的区别是调用方式。在上面的示例中,我们的 Livewire 组件将调用 Action 来创建用户。

所以现在,让我们看看业务流程在 Gherkin 语法中是什么样子的

Scenario: The Register Action is handled
Given the RegisterAction is created
When the handle method is called
Then a new user will be created

诚然,我们可以用标准测试写这个,这对我们作为开发人员来说是有意义的 - 但我喜欢 DDD 原则之一是您创建的无所不在的语言 - 就像一种商业语言。

对于我们的 BDD 测试,我将在 test 下创建一个 Integration 目录,以便我有:Unit:测试驱动开发 Feature:测试驱动开发 Integration:行为驱动开发

在我们的 Integrations 目录中,我们将使用我们安装的插件将所有创建的场景存储为 pestPHP 测试。

scenario('The RegisterAction is handled')
->given(fn () => new RegisterAction())
->when(fn (RegisterAction $action) => $action->handle(
name: 'test',
password: 'password',
))->then(fn () => assertDatabaseHas('users', [
'name' => 'test',
'email' => '[email protected]',
]));

如您从上面的代码中看到的,它很容易理解。它与我们期望在大多数 BDD 测试套件中看到的内容非常相似 - 但在一个我们习惯的框架中。在许多情况下,我们通常可以直接将它翻译成用户故事。

让我们再举一个例子,但这次我们将从用户故事开始

作为一个用户,当我激活我的帐户时,我必须收到一封电子邮件。

现在让我们将其移动到 Gherkin 语法中

Scenario: A user can activate their account
Given a new user
When they activate their account
Then an email is sent to confirm the activation.

最后,让我们继续使用我们正在测试的插件的 pestPHP

scenario('A user can activate their account')
->given(fn (): User => User::factory()->inactive()->create())
->when(fn () => Bus::fake())
->when(fn (User $user): User => $user->activate())
->then(function (User $user) {
Bus::assertDispatched(ActivateUser::class);
});

所以您可以看到,这种测试方法对您的测试套件和团队有优势。我并不是说您应该总是使用这种方法 - 但是对于那些关键的业务流程来说,它允许您将流程从企业理解的语言直接映射到您理解的测试套件。

您在应用程序中发现了其他任何改进测试策略的令人兴奋的方式吗?让我们在 Twitter 上知道您的想法!

Steve McDougall photo

Laravel 新闻 的技术作家,Treblle 的开发者倡导者。API 专家,资深 PHP/Laravel 工程师。 YouTube 直播员

Cube

Laravel 新闻通讯

加入 40,000 多名其他开发者,绝不错过新的技巧、教程等。

Laravel Forge logo

Laravel Forge

轻松创建和管理您的服务器,并在几秒钟内部署您的 Laravel 应用程序。

Laravel Forge
Tinkerwell logo

Tinkerwell

Laravel 开发人员必备的代码运行器。使用 AI、自动完成和本地和生产环境的即时反馈进行微调。

Tinkerwell
No Compromises logo

没有妥协

Joel 和 Aaron,两位来自 No Compromises 播客的经验丰富的开发人员,现在可以为您的 Laravel 项目雇用。 ⬧ 固定费率为 7500 美元/月。 ⬧ 没有冗长的销售流程。 ⬧ 没有合同。 ⬧ 100% 退款保证。

没有妥协
Kirschbaum logo

Kirschbaum

提供创新和稳定性,以确保您的 Web 应用程序成功。

Kirschbaum
Shift logo

Shift

运行旧版本的 Laravel 吗?即时、自动化的 Laravel 升级和代码现代化,以保持您的应用程序最新。

Shift
Bacancy logo

Bacancy

只需 2500 美元/月,即可使用经验丰富的 Laravel 开发人员(拥有 4-6 年的经验)为您的项目增效。获得 160 小时的专用专业知识和 15 天无风险试用。立即安排电话会议!

Bacancy
Lucky Media logo

Lucky Media

立即获得 Lucky - Laravel 开发的理想选择,拥有十多年的经验!

Lucky Media
Lunar: Laravel E-Commerce logo

Lunar:Laravel 电子商务

Laravel 的电子商务。一个开源包,将现代无头电子商务功能的强大功能带到 Laravel。

Lunar:Laravel 电子商务
LaraJobs logo

LaraJobs

官方 Laravel 工作板

LaraJobs
SaaSykit: Laravel SaaS Starter Kit logo

SaaSykit:Laravel SaaS 启动工具包

SaaSykit 是一个 Laravel SaaS 启动工具包,它具有运行现代 SaaS 所需的所有功能。付款、精美结账、管理面板、用户仪表板、身份验证、即用型组件、统计信息、博客、文档等。

SaaSykit:Laravel SaaS 启动工具包
Rector logo

Rector

您无缝升级 Laravel、降低成本和加速创新的合作伙伴,为成功企业提供服务

Rector
MongoDB logo

MongoDB

通过 MongoDB 和 Laravel 的强大集成来增强您的 PHP 应用程序,使开发人员能够轻松高效地构建应用程序。支持事务性、搜索、分析和移动用例,同时使用熟悉的 Eloquent API。了解 MongoDB 的灵活、现代数据库如何改变您的 Laravel 应用程序。

MongoDB
Maska is a Simple Zero-dependency Input Mask Library image

Maska 是一个简单的零依赖输入掩码库

阅读文章
Add Swagger UI to Your Laravel Application image

将 Swagger UI 添加到您的 Laravel 应用程序

阅读文章
Assert the Exact JSON Structure of a Response in Laravel 11.19 image

在 Laravel 11.19 中断言响应的精确 JSON 结构

阅读文章
Build SSH Apps with PHP and Laravel Prompts image

使用 PHP 和 Laravel 提示构建 SSH 应用程序

阅读文章
Building fast, fuzzy site search with Laravel and Typesense image

使用 Laravel 和 Typesense 构建快速、模糊的网站搜索

阅读文章
Add Comments to your Laravel Application with the Commenter Package image

使用 Commenter 包为您的 Laravel 应用程序添加评论

阅读文章