Pest 架构插件
发布于 作者 Steve McDougall
随着 PestPHP v2 的发布,我们现在可以测试应用程序的架构。在本教程中,我们将逐步介绍如何使用此插件。
它从在应用程序的 tests/Feature
下创建一个 ArchTest.php
文件开始。从这里,我们可以开始记录我们的架构要求和规则 - 使我们能够通过出色的 API 和极佳的开发人员体验来测试这些要求和规则。
我推荐您添加到测试中的一个测试将确保在我们的应用程序中没有留下任何杂乱的调试调用。
test('Not debugging statements are left in our code.') ->expect(['dd', 'dump', 'ray']) ->not->toBeUsed();
在我们深入研究可以使用的可用规则之前,让我们分析一下这些测试的结构。它从一个 test
调用开始,我们在其中定义测试的名称 - 确保它是一个可以理解的描述您正在测试的内容。然后,我们使用 Pest 高阶期望 API 来声明我们正在测试的内容。我们从期望某件事开始。在上面的例子中,我们期望以下内容都不会被使用,或者我们可以期望出现某些内容。
接下来,让我们看看我们可以创建更多具体的测试,以确保我们遵守架构规则。显然,我们首先需要做的就是确保我们理解我们的架构实践。您不能简单地实施您不打算遵循的规则。在本教程中,我将记录一些我喜欢在我的项目中应用的规则。作为一名不固执己见的开发人员,我坚持这一点。
test('Our API controllers return responses that we expect') ->expect('Illuminate\Contracts\Support\Http\Responsable') ->toBeUsedIn('App\Http\Controllers\Api');
在这个测试中,我们要确保在 API 中使用 Response 类。我们的控制器应该返回 Responsable 类,以便我们最大限度地减少代码重复,并始终以标准的方式返回。
test('We do not directly use Eloquent Models in our APIs.') ->expect('App\Models') ->not->toBeUsedIn('App\Http\Controllers\Api');
在这个测试中,我们要确保我们不会在 API 中直接使用 Eloquent 模型。在与数据库交互时,我们应该使用 Action、Command、Query 或 Service/Repository 类。这是一个我尽可能遵循的规则,因为它再次减少了代码重复。
test('We always use Resouce classes when responding') ->expect('App\Http\Resources') ->toBeUsedIn('App\Http\Controllers\Api');
在这个测试中,我们要确保始终在控制器中使用 Resource 类。这使我们能够确保我们有标准化的方法来从 API 返回数据。
以下规则将更具体地针对我的编码方式,因此可能与您无关 - 但它展示了您可以测试代码模块化方面的特定方法。
我非常依赖我针对 Laravel 的模块化方法,在需要的地方使用单独的命名空间。我还非常依赖 Command 用于写入操作,Query 用于读取操作。我可以确保它们的使用符合我的要求。
test('We use Query classes where we need them in the Catalog domain') ->expect('Domains\Catalog\Queries') ->toBeUsedIn('App\Http\Controllers\Api\V1\Products\Read');
目前,这是我将作为临时措施使用的东西,直到架构插件支持通配符。我们要确保在正确的地方使用查询。一旦架构插件允许使用通配符,我们就可以执行以下操作
test('Query classes are used for read operations') ->expect('Domains\*\Queries') ->toBeUsedIn('App\Http\Controllers\Api\*\*\IndexController') ->toBeUsedIn('App\Http\Controllers\Api\*\*\ShowController') ->not->toBeUsedIn('App\Http\Controllers\Api\*\*\StoreController') ->not->toBeUsedIn('App\Http\Controllers\Api\*\*\UpdateController') ->not->toBeUsedIn('App\Http\Controllers\Api\*\*\DeleteController');
通过这个测试,我们可以确保我们对所有读取端点使用查询,但不对写入端点使用查询,从而使我们能够更严格地控制代码架构和方法。
当然,这现在还不支持,但也许它可以使我们将来能够使用更少的架构规则,同时保持相同的覆盖范围。