通过 Node.js 的 got 库可以方便的进行 http 请求,如果被测系统的 API 只有几个,可以按照上一讲(API 自动化测试 01: 使用库函数模拟发送请求)提到的方法,直接写发送请求的函数,就能完成测试任务。当一个项目有很多的 API 需要去测试时,每个 API 一个方法的方式就难于管理。这就需使用某种框架来管理这些用例。
市面上现在有很多集成的框架可供选择,比如有测试驱动框架(TDD),关键字驱动框架 (Keyword Driven) 等等,这里为大家介绍使用行为驱动(BDD) 框架来开发 API 的自动化测试。
行为驱动测试(BDD)是业界比较流行的概念,通过自然语言描述业务需求,提高团队间的敏捷开发。行为驱动框架比较流行的有 Cucumber,Cucumber 支持的编程语言有 Java、JavaScript、Ruby 等,Cucumber.js 的 github 地址为:https://github.com/cucumber/cucumber-jsCucumber 的 JavaScript 库支持最好的是 CukeTest,本次演练使用开发 Cucumber.js 的专业工具 CukeTest。下载地址为:http://cuketest.com/download。。而对
Cucumber 的脚本主要分为两部分,场景描述部分以 .feature 为文件后缀名 ,另一部分为代码实现部分,以 .js 为后缀名 。Cucumber 使用特定语法将业务描述与业务实现链接起来。
业务描述文件类似如下:
场景大纲: Get 方法样例
假如发送Get请求 "<URL>" 服务器应该返回数据 '<expectval>'
例子:
| URL | expectval |
| http://localhost:3000/users/1 | { "id": 1, "name": "therebelrobot", "location": "USA" } |
| http://localhost:3000/users/2 | { "id": 2, "name": "visiting-user", "location": "UK" } |
| http://localhost:3000/posts/1 | { "id": 1, "title": "json-mock", "body": "The internet is cool!", "author": "therebelrobot", "userId": 1 } |
其中 场景大纲
为关键字,主要表示这个场景可以使用不同的数据来测试不同的场景,场景下面为每个操作步骤的描述,定义操作步骤的执行, 在操作步骤中,使用 "","" 作为请求数据的占位符,在例子下面定义具体对应的数据。
这个场景比较简单,只有一个步骤描述。你可以根据需要为场景添加多个步骤,对 API 测试来说,就是按照业务逻辑关系,先后调用一组相关的 API。
与此操作步骤描述对应的业务实现代码为:
Given(/^发送Get请求 "([^"]*)" 服务器应该返回数据 '([^']*)'$/, function (url, expectval) {
return got.get(url, jsonFormat).then(function (result) {
var data = result.body;
var assertdata = JSON.parse(expectval);
return assert.deepEqual(data, assertdata);
});});
在脚本执行中,Cucumber 会自动将步骤描述中的数据作为参数传进来,执行的时候会根据描述数据的行数,有多少行数据,这个场景就运行多少次。该步骤函数中,它接收到 url 参数并访问此 url,然后将返回结果与期望的返回值参数比较,相同则验证通过。
上面操作中我们简单介绍了使用 Cucumber 框架的一般步骤,好处就是将业务描述与代码相结合,根据描述,实现相应的代码即可。对于没有多少开发经验的测试人员来说,使用 Cucumber 可以很快就能上手进行操作。但是当用例特别多的时候,管理用例是一个挑战,并且每个用例都要与代码之间相互关联,如果对某个用例进行修改,其它实现代码可能就受到影响。所以下面使用 Cucumber.js 专业的编辑工具 CukeTest 为例,说明如何构建基于 Cucumber 的行为驱动框架。
打开 CukeTest,欢迎界面 -- 教学样例,点击【api_service】将样例代码存储到本地目录,可以看到如下界面。
CukeTest 会将 .feature 文件在可视化界面中打开,在可视化界面中,双击可以进行编辑修改。在每个操作步骤后面点击绿色按钮,可以直接定位到代码实现部分。这对于脚本修改提供了很大的便利。在 js 代码中,也可以右键定位到描述文件。关于更多使用语法可以参考我们在腾讯课堂上放的免费视频:
API 自动化测试教程
https://ke.qq.com/course/280876
下面讲如何根据样例框架上进行更改。
在 package.json 文件中已经定义好要使用到的库文件,在项目根目录下执行 npm install 可以自动安装依赖。
在样例文件中,使用 json-mock 库模拟一个 RESTful API 服务,同时提供了 data.json 作为源数据。根据 feature 文件中的说明,在项目的根目录下执行 node_modules.bin\json-mock data.json 启动 RESTful API 服务器.
可以看到命令行中 如下输出信息:
{^_^} Hi!
Loading database from data.json
http://localhost:3000/users
http://localhost:3000/posts
http://localhost:3000/comments
You can now go to http://localhost:3000/Enter `s` at any time to create a snapshot of the db
说明服务已经启动,你可以访问本机的 3000 端口调用这个模拟的 API。
点击 CukeTest 上运行项目运行按钮,即可运行。运行完成后自动生成测试报告。
上面样例中,在 feature 文件的可视化界面可以看到每个场景的具体操作行为。点击操作步骤后面的绿色按钮可以定位到自动化脚本实现部分,便于操作。在 step_definitions.js 文件中,同样我们使用上一讲中介绍的 got 作为实现库。
使用 CukeTest,可以很方便将整个框架整合起来。以 CNode 社区的 API 为例,下面介绍如何将上一讲中的代码整合进来。
新建 feature 文件,可视化界面中可以简单描述。
对应的文本描述为:
# language: zh-CN
功能: Cnode Test
cnode社区api测试用例
场景: 主题首页
假如发送Get请求到主题首页,limit 参数为值为1时,返回结果只有1条
场景: 新建主题
假如发送Post请求新建主题,成功后返回对象中success值为true
在 step_definitons 目录下新建 cnode.js 文件并打开。点击 feature 文件可视化界面中每个操作步骤后面的灰色按钮可以在 cnode.js 文件中自动生成脚本文件。
在 cnode.js 文件中,引入 got 库,根据业务描述实现对应的代码。
var { Given, When, Then } = require('cucumber');
var got = require('got');
var assert = require('assert');
Given("发送Get请求到主题首页,limit 参数为值为{int}时,返回结果只有{int}条", async function (arg1, arg2) {
let res= await got('https://cnodejs.org/api/v1/topics?limit=1')
// console.log(res.body)
// 将返回结果解析为JSON对象
let result = JSON.parse(res.body);
// 判断状态码
assert.equal(200, res.statusCode);
// 判断返回的帖子长度是否为1
assert.equal(1, result['data'].length);
});
Given("发送Post请求新建主题,成功后返回对象中success值为true", async function () {
let bodydata = {
accesstoken:"xxx自己注册账号的tokenxxx",
tab:'dev',
title:'hello,world!',
content:'this is a test topic'
};
let result = await got.post('https://cnodejs.org/api/v1/topics',{
// 设置数据类型为JSON 数据类型
json:true,
body:bodydata
});
console.log(result.body);
let result_data = result.body;
assert.equal(true,result_data['success'])
});
点击运行项目按钮,即可进行测试用例的执行。并生成测试报告:
报告中每个 API 测试都有文字描述及参数信息,非常直观。
通过上面的例子,只要我们熟悉业务描述,根据业务描述使用对应的库函数调用相关方法就能对相应功能进行验证。这就是使用行为驱动的便利之处,当然,这些仅是初步功能,方便我们快速入门。Cucumber 中还支持添加数据,比如在操作步骤中添加 DocString 或者 Data Table,场景类型也分为 背景 ,场景 ,场景大纲 。不同的场景类型有着不同的含义。具体可以参考 Cucumber 的 api 或者查阅 CukeTest 的文档 http://cuketest.com/zh-cn/ 进行学习。