deepdiver / spectator
为您的OpenAPI规范提供测试辅助工具
Requires
- php: ^7.4|^8.0
- ext-json: *
- cebe/php-openapi: ^1.5
- laravel/framework: ^8.40.0|^9.0.0
- opis/json-schema: ^2.0
Requires (Dev)
- nunomaduro/collision: ^5.1|^6.0
- orchestra/testbench: ^6.0|^7.0
- phpunit/phpunit: ^9.5
- dev-master
- v1.5.3
- v1.5.2
- v1.5.1
- v1.5.0
- v1.4.1
- v1.4.0
- v1.3.0
- v1.2.3
- v1.2.2
- v1.2.1
- v1.2.0
- v1.1.1
- v1.1.0
- v1.0.5
- v1.0.4
- v1.0.3
- v1.0.2
- v1.0.1
- v1.0.0
- v0.8.5
- v0.8.4
- v0.8.3
- v0.8.2
- v0.8.1
- v0.8.0
- v0.7.1.2
- v0.7.1.1
- v0.7.1
- v0.7.0
- v0.6.5
- v0.6.4
- v0.6.3
- v0.6.2
- v0.6.1
- v0.6.0
- v0.5.5
- v0.5.4
- v0.5.3
- v0.5.2
- v0.5.1
- v0.5.0
- v0.4.0
- v0.3.1
- v0.3.0
- v0.2.1
- v0.2.0
- v0.1.2
- v0.1.1
- v0.1.0
- dev-fix/nullable-oneof
- dev-fix/nullable-in-anyof
- dev-dev
- dev-feat/cache-specifications
- dev-issue/92-request-validation
- dev-type-presence
- dev-sanctum-support
This package is auto-updated.
Last update: 2022-08-15 07:53:31 UTC
README
仅在Composer中临时使用
Spectator
Spectator提供了轻量级的OpenAPI测试工具,您可以在现有的Laravel测试套件中使用。
编写测试以验证您的API规范不会偏离实现。
安装
您可以通过Composer安装此包。
composer require deepdiver/spectator --dev
然后,使用以下命令发布此包的配置文件:
php artisan vendor:publish --provider="Spectator\SpectatorServiceProvider"
配置文件将发布在config/spectator.php
中。
源代码
源代码是指您的API规范所在的位置。根据您或您团队的工作方式,或者规范所在的位置,您可能需要为不同的环境配置不同的源。
如配置所示,有三个源类型可供选择:local
、remote
和github
。每个源都需要定义您的规范所在的文件夹,而不是规范文件本身。这在使用一个项目中多个API或API分散在多个规范文件中的工作时提供了灵活性。
本地示例
## Spectator config
SPEC_SOURCE=local
SPEC_PATH=/spec/reference
远程示例
这是使用来自Github的原始访问链接,但可以指定任何远程源。可以使用SPEC_URL_PARAMS向远程URL追加任何其他所需参数。
## Spectator config SPEC_PATH="https://raw.githubusercontent.com/path/to/repo" SPEC_URL_PARAMS="?token=ABEDC3E5AQ3HMUBPPCDTTMDAFPMSM"
Github示例
这使用的是Github个人访问令牌,该令牌允许您访问包含您的合约的远程仓库。
您可以从此链接查看如何获取您的个人访问令牌的说明。
需要注意的是,SPEC_GITHUB_PATH必须包含分支(例如:main)以及包含您的合约的目录的路径。
## Spectator config SPEC_GITHUB_PATH='main/contracts' SPEC_GITHUB_REPO='orgOruser/repo' SPEC_GITHUB_TOKEN='your personal access token'
在测试中指定您的文件
在您的测试中,您将声明您想要测试的规范文件。
public function testBasicExample() { Spectator::using('Api.v1.json'); // ...
测试
范式转变
接下来,让我们看看一些更实用的东西。
最初,规范测试或合约测试可能看起来有些不合常理,尤其是与Laravel支持的“功能”或“功能”测试相比。虽然功能测试确保您的请求验证、控制器行为、事件、响应等在人们与您的API交互时以您期望的方式行为,但合约测试确保的是请求和响应符合规范,仅此而已。
编写测试
观众添加了一些简单的工具到现有的Laravel测试工具箱。
以下是一个典型的JSON API测试示例
<?php class ExampleTest extends TestCase { /** * A basic functional test example. * * @return void */ public function testBasicExample() { $response = $this->postJson('/user', ['name' => 'Sally']); $response ->assertStatus(201) ->assertJson([ 'created' => true, ]); } }
下面是一个合同测试示例
<?php use Spectator/Spectator; class ExampleTest extends TestCase { /** * A basic functional test example. * * @return void */ public function testBasicExample() { Spectator::using('Api.v1.json'); $response = $this->postJson('/user', ['name' => 'Sally']); $response ->assertValidRequest() ->assertValidResponse(201); } }
测试验证请求和响应是否符合规范,在本例中位于Api.v1.json
中。这种测试类型促进了TDD:您可以在端点之前先编写端点合同测试,然后确保规范和实现是一致的。
在您的规范中,应该记录每个可能的响应。例如,一个单一的POST
端点可能导致2xx
、4xx
甚至5xx
代码响应。此外,您的端点可能还有特定的参数验证需要遵守。这就是合同测试与功能测试不同的地方:在功能测试中,对成功和失败的响应进行测试以验证结果;在合同测试中,对请求和响应进行测试以验证一致性,结果并不重要。
调试
对于某些验证错误,会抛出特殊的异常消息,显示与预期模式一起显示的错误消息。例如
---
The properties must match schema: data
All array items must match schema
The required properties (name) are missing
object++ <== The properties must match schema: data
status*: string
data*: array <== All array items must match schema
object <== The required properties (name) are missing
id*: string
name*: string
slug: string?
---
使用了一些自定义符号
- "++": 对象支持
additionalProperties
- "*": 项目是
required
- "?": 项目可以是
nullable
使用方法
定义要测试的规范文件。这可以在您的setUp()
方法或特定的测试方法中定义。
<?php use Spectator/Spectator; class ExampleTest extends TestCase { public function setUp(): void { parent::setUp(); Spectator::using('Api.v1.json'); } public function testApiEndpoint() { // Test request and response... } public function testDifferentApiEndpoint() { Spectator::using('Other.v1.json'); // Test request and response... } }
在测试端点时,有一些新的方法
$this->assertValidRequest(); $this->assertValidResponse($status = null); $this->assertValidationMessage('Expected validation message'); $this->assertErrorsContain('Check for single error'); $this->assertErrorsContain(['Check for', 'Multiple Errors']);
当然,您仍然可以继续使用所有现有的HTTP测试方法
$this ->actingAs($user) ->postJson('/comments', [ 'message' => 'Just over here spectating', ]) ->assertCreated() ->assertValidRequest() ->assertValidResponse();
但是,混合功能测试和合同测试可能会在以后变得难以管理和阅读。
您可以使用内置的->assertStatus($status)
方法来验证响应,也可以验证有效的响应确实是您要检查的响应。例如,您可能从单个端点收到一个200
或202
,您想确保您正在验证正确的响应。
$this ->actingAs($user) ->postJson('/comments', [ 'message' => 'Just over here spectating', ]) ->assertValidRequest() ->assertValidResponse(201);
当抛出非特定于本包目的的异常时,例如拼写错误或缺少导入,输出将默认以相当简短的消息和没有堆栈跟踪的格式化。可以通过禁用Laravel内置的验证处理程序来更改此设置,这在使用测试时可以更容易地进行调试。
可以通过几种不同的方式完成此操作
class ExampleTestCase { public function setUp(): void { parent::setUp(); Spectator::using('Api.v1.json'); // Disable exception handling for all tests in this file $this->withoutExceptionHandling(); } // ... }
class ExampleTestCase { public function test_some_contract_test_example(): void { // Only disable exception handling for this test $this->withouthExceptionHandling(); // Test request and response ... } }
核心概念
方法
Spectator通过注册一个自定义中间件来工作,该中间件对规范执行请求和响应验证。
依赖
对于有兴趣为Spectator做出贡献的人来说,了解用于规范测试的核心依赖项是很有用的
cebe/php-openapi
:用于将规范解析为可用的数组opis/json-schema
:用于在规范中对对象/数组执行验证
致谢
许可
MIT许可(MIT)。有关更多信息,请参阅许可文件。