跳转到主要内容
Chinese, Simplified

【API测试】使用Dredd测试您的API

 

通常,在开发应用程序时,前端和后端开发人员在实现路径上采用两条不同的路径。前端开发人员更多地是设计驱动的,而后端开发人员则更注重数据。这通常会导致潜在的整合差距,其中一个团队在提供的数据,响应的结构等方面具有某些期望,而另一个团队实现完全不同的东西。

介绍

在本文中,我们将展示一个技术堆栈,旨在弥合前端和后端开发人员之间的差距,使我们能够记录API并在实现后不断测试它。

本文中介绍的堆栈包含以下内容:

  • Dredd - 使用API​​ Blueprint和Swagger API描述格式的API测试工具
  • API Blueprint - 规范语言,允许我们以类似Markdown的语法记录我们的API
  • Drakov - 可以使用我们API的API蓝图描述并设置模拟服务器来托管端点的工具

本文中的示例将使用简单的Node.js API和Express中间件显示。

安装和设置

Dredd基于Node.js,因此在安装之前,请确保在您的计算机上安装了Node.js和npm。 它可以使用以下命令安装为npm包:

> npm install -g dredd

安装完成后,您可以通过运行来检查它是否正确安装:

> dredd --version

API Blueprint描述文件的简单示例

假设我们有一个带端点的API来创建新用户:

POST /api/users

它接受包含电子邮件和密码值的JSON请求正文:

{
 "email": "testing@email.com",
 "password": "pa55w0rd"
}

用于测试以下端点的API Blueprint规范如下所示:

FORMAT: 1A
# Dredd example
## Users [/api/users]
### Create User [POST]
+ Request (application/json)
 {
 "email": "test@email.com",
 "password": "pa55w0rd"
 }
+ Response 200 (application/json; charset=utf-8)
 + Headers
 jwt-token: (string, required)
 + Body
 {
 "id": 1,
 "email": "test@mail.com",
 "password": "pa55w0rd",
 "provider": "local",
 "role": "user"
 }

我们可以通过两种方式根据Blueprint文件验证API实现。

手动运行

Dredd使我们能够通过指定API蓝图文件的名称和API的URL来运行临时测试:

> dredd api-description.apib http://localhost:9090

上面的命令假设API Blueprint文件名为api-description.apib,并且您的API在端口9090上的本地计算机上运行。根据您的设置,值可能会有所不同。

配置运行

还有一种更简单的方法来设置Dredd,即运行> dredd init命令,该命令运行配置向导以帮助您在项目根目录中创建dredd.yml文件。 从交互式向导回答几个问题后,只需输入以下命令即可运行测试:> dredd。 如果配置正确,Dredd将使用您向向导提供的命令启动后端服务器进程并开始测试。

在这两种情况下,输出都与此类似:

> dredd
info: Configuration './dredd.yml' found, ignoring other arguments.
warn:
Apiary API Key or API Project Subdomain were not provided.
Configure Dredd to be able to save test reports alongside your Apiary API project:
https://dredd.readthedocs.io/en/latest/how-to-guides/#using-apiary-reporter-and-apiary-tests
info: Starting backend server process with command: npm run start
info: Waiting 3 seconds for backend server process to start
> dredd-example@0.0.1 start /Users/code/dredd-example
> node server/app.js
Express server listening on 9000, in development mode
info: Beginning Dredd testing...
pass: POST (200) /api/users duration: 55ms
complete: 1 passing, 0 failing, 0 errors, 0 skipped, 1 total
complete: Tests took 901ms
POST /api/users 200 4.167 ms - 151
complete: See results in Apiary at: https://app.apiary.io/public/tests/run/f1642892-a4eb-4970-8423-5db5c986a509
info: Backend server process exited

由于我们没有指定任何API密钥,Dredd警告我们测试运行不会保存到我们的Apiary帐户。 在这种情况下,它们被保存为公共运行并保存24小时,这对于本文来说已经足够了。 让我们使用输出中的URL打开我们的测试运行(注意 - 您的URL会有所不同):https://app.apiary.io/public/tests/run/f1642892-a4eb-4970-8423-5db5c986a509

在Test Run Viewer中,我们可以检查测试运行中的每个请求,返回的响应,差异和结果。

使用挂钩进行设置和拆卸

与许多其他测试框架一样,Dredd还支持添加挂钩以运行设置和拆卸代码,编写自定义期望,处理授权以及在测试之间共享数据。 钩子可以用许多支持的语言编写,在本文中,我们将看到如何在本机支持的Node.js中添加钩子。

我们首先在项目中添加一个钩子文件(在我们的例子中,我们可以将它添加到项目根目录并命名为dredd-hooks.js)。

有两种方法可以让Dredd使用钩子文件。 一种是手动添加命令参数和我们的钩子文件的路径:

> dredd --hookfiles=dredd-hooks.js
 

另一种方法是编辑我们的dredd.yml文件并通过设置hookfiles属性来更新配置。

dry-run: null
hookfiles: dredd-hooks.js
language: nodejs
sandbox: false
server: npm run start
server-wait: 3
init: false
custom: {}
names: false
only: []
reporter: apiary
output: []
header: []
sorted: false
user: null
inline-errors: false
details: false
method: []
color: true
level: info
timestamp: false
silent: false
path: []
hooks-worker-timeout: 5000
hooks-worker-connect-timeout: 1500
hooks-worker-connect-retry: 500
hooks-worker-after-connect-wait: 100
hooks-worker-term-timeout: 5000
hooks-worker-term-retry: 500
hooks-worker-handler-host: 127.0.0.1
hooks-worker-handler-port: 61321
config: ./dredd.yml
blueprint: api-description.apib
endpoint: 'http://localhost:9000'

现在我们有了文件,我们可以开始围绕每个事务编写代码。 Dredd在API蓝图描述文件(.apib)中按名称标识事务。 要在测试运行期间列出事务名称,可以添加--names命令参数:> dredd --names。

在我们的示例中,我们有一个名为Users> Create User的事务,我们将在代码中引用它。

当我们的API中有很多端点时,挂钩尤其重要,我们不希望依赖于它们执行的任何特定顺序。 例如,如果我们有一个删除用户的端点,为了单独测试它(不依赖于首先运行的Create User端点),我们必须在执行测试之前创建一个测试用户。 这是钩子文件的样子:

var hooks = require('hooks');
var User = require('../dredd-example/server/api/user/user.service');
var testStash = {
 newUserId: null
};
hooks.before('Users > Delete User', function(transaction) {
 hooks.log('Executing hook "before" transaction "Users > Delete User"');
 User.save({
 email: 'user@test.com',
 password: '12345'
 }, function(err, newUser) {
 if (!err) {
 hooks.log('New user created');
 testStash.newUserId = newUser.id;
 } else {
 transaction.fail = 'Unable to create new user';
 }
 })
});
hooks.after('Users > Delete User', function(transaction) {
 hooks.log('Executing hook "after" transaction "Users > Delete User"');
 // In case the actual test failed, we want to clean up the data
 if (testStash.newUserId != null) {
 User.delete(testStash.newUserId);
 }
});

上面的代码中有几点需要考虑:

我们声明了一个名为testStash的新变量,我们用它来保存跨多个测试钩子的新创建用户的ID。

在before hook中,如果我们无法创建用户,我们可以通过使用失败消息设置fail属性来手动测试失败。

在挂钩后,我们从存储中获取用户的ID,并在测试后通过删除用户来清理它。

设置模拟服务器

使用API​​ Blueprint格式记录的API时,另一个很酷的功能是我们也可以使用相同的文件来启动模拟服务器来托管我们的端点。这对前端开发人员特别有用,因为他们不必等待API完成和部署。相反,他们可以使用.apib文件来启动模拟服务器,将客户端应用程序与它集成,并确保真正的API也符合相同的规范。

该工作的工具称为Drakov,它也可以通过运行以下命令安装为npm包:

> npm install -g drakov

安装完成后,我们只需键入以下内容即可将Drakov指向我们的API Blueprint文件:

> drakov -f api-description.apib

此命令将使用默认参数运行Drakov并显示以下输出:

> drakov -f api-description.apib
[INFO] No configuration files found
[INFO] Loading configuration from CLI
 DRAKOV STARTED
[LOG] Setup Route: GET / Get Message
[LOG] Setup Route: POST /api/users Create User
[LOG] Setup Route: GET /api/users/:id Get User Info
[LOG] Setup Route: DELETE /api/users/:id Delete User
 Drakov 1.0.4 Listening on port 3000

现在,我们可以对模拟的API执行任何HTTP操作,并开始获取文档中定义的HTTP响应。

最后的话

今天提供的工具既简单又直接,但也非常强大。 它们涵盖了许多任务,包括记录API,测试实现以及运行模拟服务器以方便使用。

Dredd有很多选项,可以配置各种类型的请求。 它还可以与所有主要的CI工具集成,以便重复测试,为开发人员提供了一个很好的安全网。

API Blueprint是一种非常富有表现力的降价格式,可用于描述请求和响应的几乎所有细节。

Drakov非常简单,可以通过运行一个简单的命令来开箱即用。

所有这些只需要几个小时来准备和配置,之后您将能够告别未记录的API。

Article
知识星球
 
微信公众号
 
视频号