接口测试对于大多数的公司来说,基本是一个常规武器,我们也在 Testerhome 的社区中学习到了很多同学分享出来的接口测试框架。不过除了平时使用 Jenkins 做接口的持续回归之外,我们的产品测试同学也会经常需要对一些接口进行一些手工的操作,CRUD 等等。目前业内有一些比较主流的接口测试工具,例如:
上述的工具都可以完成基本的 HTTP 请求,并且支持标准的 HTTP Authentication 以及对于 HTTP Header 的操作。但是我们的接口有一些特殊,需要对于每一个 URL 进行一个签名的操作。如果 signature 是一个函数的话,那么输入的参数就是时间戳 +URL ,输出就一个 signature 字符串,并且需要添加到 HTTP 头中作为一个校验字段。这样就意味着每一次请求都需要去计算一次 signature。
写一个 Python 脚本来专门计算 Signature,然后产品同学把脚本输出的结果填写到 Postman 中的 HTTP Header 头中来发请求 。想想这个效率实在是太低了,直接放弃。
JMeter 是一个压力测试工具,不过我们也看到有一些团队用它来做一些接口测试的工作。BeanShell 是 JMeter 支持的一个脚本语言,可以用来在 HTTP 请求前后做一些操作,例如修改请求参数,和 HTTP Header 头等。我们可以考虑把我们计算 Signature 的方法写在一个 BeanShell PreProcessor 中,这样就每次发送请求的时候,自动计算签名了。但是考虑到很多同学都没有使用过 JMeter,还有培训和掌握新工具的过程,所以还是放弃了。(充分考虑了产品测试小红薯们的对新测试工具的接受程度)
观察了很久后我们发现,其实小伙伴们都喜欢用 Chrome + Postman 的 Extension 来做接口的调试工作。那看来最好的方法,就是给他们发布一个新的 Chrome Extenstion 就能解决问题。当然我们不需要重头开始写,我们要做的就是在巨人的肩膀上加一个计算签名的功能。不过令人伤心的是 Postman 不是一个开源的项目,好在我们最后在 Github 上找到了这个项目ChromeRestClient, Chrome 上另外一个很流行的 Rest Client 插件。
如何做 Chrome Extension 开发我们就不在这里详述了,有兴趣的小伙伴可以移动到这里 Chrome Extension Development
ChromeRestClient 项目比较庞大,项目结构如下,
但是其中实际和 Chrome Extension 插件相关的目录是
gulp build
以后才会出现,有 4 个 level 的 build,分别是 dev,stable,canary,beta搭建开发环境的过程很简单,只需要本地有安装 nodejs 即可, 我们使用的版本是 6.3.1
, 接下来只要把项目从 github 克隆下来以后,在根目录下运行 npm install && bower install
,就会在 app 目录下下载对应的依赖了。当然整个过程自然不会那么的一帆风顺,我们给社区反馈了 3 个 issue 并得到了开发者的及时反馈。
安装完依赖以后,使用 Chrome 浏览器,打开 Menu->More Tools -> Extensions, 选择Load Unpacked Extension
, 然后选择 app 目录即可把本地的 extension 加载到 Chrome 中进行调试, 确保 app 目录下有manifest.json
文件,这是一个 Chrome Extension 的描述文件
接下来就可以在 Chrome 中进行插件调试开发了,如果本地修改了代码,需要在 Extension 菜单页面中,选择 Reload,重新加载你的插件。由于 Chrome Extension 使用的是标准的 Web 开发技术,包括 HTML + CSS + Javascript,所以可以方便的在 Chrome Develop Toolbar 中进行 Debug 了。
ChromeRestClient 插件的页面是使用了 Google 的 Polymer 项目进行开发,这个和 AngularJS 类似,都属于 Google 在力推的 Web Component 技术。我们可以在app/elements/
下找到一堆子目录,都是 Polymer 的 Plugin。当然我们最关心的是这个子目录arc-request-controller
我们可以看到arc-request-controller.js
中,最核心的一个函数是sendRequest
,
sendRequest: function () {
if (!this.request) {
StatusNotification.notify({
message: 'Request not ready'
});
return;
}
if (!this.request.url) {
StatusNotification.notify({
message: 'Add URL to the request first'
});
return;
}
this._setIsError(false);
this._setResponse(null);
this._setRequestLoading(true);
this._saveUrl();
this._callRequest();
this.showCookieBanner = false;
arc.app.analytics.sendEvent('Engagement', 'Click', 'Request start');
// Will help arrange methods bar according to importance of elements.
arc.app.analytics.sendEvent('Request', 'Method', this.request.method);
},
上面的代码中,大多数都是在做一些 Request Body 的初始化操作,最核心的是那句this._callRequest()
调用,我们来看一下_callRequest
的函数式怎么实现的
_callRequest: function () {
// Copy the object so MagicVariables will not alter the view
this._applyMagicVariables(Object.assign({}, this.request))
.then((request) => this._applyCookies(request))
.then((request) => this._applyAuthorization(request))
.then((request) => this.fu(request))
.then((request) => {
// Make it async so errors will be handled by socket object.
this.async(() => {
if (this.auth) {
request.auth = this.auth;
this.auth = undefined;
}
if (this.useXhr) {
this.$.xhr.request = request;
this.$.xhr.run();
} else {
this.$.socket.request = request;
this.$.socket.run();
}
});
});
},
接下来我们可以看到负责处理 HTTP Header 头的是_filterHeaders
函数,那么我们只要把我们的签名算法写到这个函数里,并添加正确的 HTTP Header 就好了。在添加签名算法的过程中涉及到了一下 JS 的依赖,我们也统一用 bower 进行管理,并把依赖模块加入到了bower.json
中
最后我们使用 Gulp 来编译我们的 Chrome Extension,例如编译一个 beta 的版本 gulp build --target beta --build-only
, 这样就会在 build 目录下创建一个 beta 目录,并把对应的 build 结果 copy 到里面。
有一个要提醒,如果有添加 JS 依赖的话,需要在tasks/builder.js
中声明这个依赖
var bowerDeps = [
'chrome-platform-analytics/google-analytics-bundle.js',
'dexie-js/dist/dexie.min.js',
'har/build/har.js',
'lodash/lodash.js',
'uri.js/src/URI.js',
'prism/prism.js',
'prism/plugins/autolinker/prism-autolinker.min.js',
'js-md5/src/md5.js',
'string-format-js/format.js'
];
万事大吉,接下来只要使用 Chrome 自带的 Pack Extension 功能把插件打包成一个.crx 的文件就可以分发给我们的产品测试同学了。(签名算法涉及到一些机密信息,所以我们没有上传到 Chrome Store 中)
希望这篇分享可以让你更好了解小红薯是如何在测试的工作中 think different 的,当然我们也更欢迎你加入我们的团队,和我们一起把测试变得有趣。有兴趣的同学可以看这篇招聘帖子,https://testerhome.com/topics/5045