自动化测试的思考及其工具的设计

一方面是接口单元测试。

所有Rest/Dubbo等API都要做单元测试,

输入、输出,标准化。

输入示例:

{
  "m": "put",
  "t": 1,
  "u": "http://localhost:6680/test/nodepd/a003",
  "b": "{\"a\":12,\"b\":2}"
},
{
  "m": "get",
  "t": 0,
  "u": "http://localhost:6680/app/add",
  "q": {
    "a": ["12"],
    "b": ["2"]
  }
}

b代表body,m代表method,t代表数据传输方式(见下文)。


对于POST/PUT请求,有两种传输数据的方式

1、通过Headers["Content-Type"] = "application/x-www-form-urlencoded"格式传递。底层body传输格式其实为:

“key1=val1&key2=val2&...”的方式进行编码,key 和 val 都进行了 URL 转码。

大部分服务端语言都对这种方式有很好的支持。

    同理,还有一种“multipart/form-data”格式(详细定义参见 http://www.ietf.org/rfc/rfc1867.txt),都是浏览器原生支持的,而且现阶段原生 form 表单也只支持这两种方式。


2、现在主流的header["Content-Type"] = "application/json"格式。底层body传输的是标准json字符串。

如果设置t=1,m=post或put,("application/x-www-form-urlencoded"),那么map会转换成url param map<string,string[]>格式。

如果设置t=0,m=post或put,("application/json"),那么map会转换成json字符串。

如果m=get或delete,那么map会转换成url param map<string,string[]>格式。


输入标准化了,之后就是对于响应结果的验证。


另外,再补充一点,对于输入,可以像mockJS那样,以内置表达式,模拟各种取值,不需要手工造数据。举例:

    age字段:可以设置为随机数([0,150])

    name字段:可以设置为随机内置名字(从指定数组中随机选择一个)。

    对于数组array、list,可以随机设置元素个数。

并且,还可以主动模拟常规的测试手法(比如检查字符串的长度,检查数字的边界值,检查空值等)


对于响应结果,可以检查状态码、检查响应串、验证JSON、检查header、限制应答时间等。检验JSON串时,可以使用JavaScript脚本,支持JSON-Path校验,支持常见的字符串截取等函数。


当然,我歪歪了这么多,想法这么多,实际上早就有人把这一套软件做出来了,

参见:

《API自动化测试利器——Postman》http://www.bayescafe.com/tools/use-postman-to-test-api-automatically.html

《Postman教程——使用数据文件》https://www.jellythink.com/archives/187

《Apizza——极客专属的接口协作管理工具》https://www.apizza.net/

Apizza官方文档:https://thoughts.teambition.com/sharespace/5f8eeff75ace8e0016e0ed99/docs/5f8eeff15ace8e0016e0ed8d

另外,还有颇有名气的Python写的工具HTTP Runner:https://blog.csdn.net/lingdanfeng/article/details/84985034

除此之外,还有Hippie-Swagger等。


不过,上文作者说了:“如果单纯想做自动化测试的话还是用代码测试更好一点。Postman缺点很多,但首先是作为一个调试工具,开发的时候会一直用它来查看结果,也会用它来给同事展示API。做完这些会积累一批测试用例,顺便就可以拿来做测试。”


总结:

    1、这种自动化测试的工具或平台,也许已经具备非常强大的功能了。但是,通常是闭源的、商业化的。

    2、这个工具的核心功能,其实挺简单,自己造轮子也不难。我自己用Go语言就写了一个。不过,目前看来,有3个选择:

    用JavaScript+NodeJS编写,优点是:1)脚本语言,编写和运行都简单,学习难度较低,测试人员也能掌握;2)属于前端技术范畴,UI不用愁。

    用Golang编写,优点是:1)http性能比C语言还高,接近于极限,可以很好的做压力实测工具。2)跨平台安装运行,运维十分方便。

    用Java编写,优点是:1)后端开发人员上手容易,方便自己写测试用例。2)生态链最强大,没有什么做不到,可以做大做强。


    说白了,JS方案适合测试人员用,Java方案适合后端开发用,Golang方案适合运行在服务器上(跑自动化和压力测试)。


考虑如下几点:

    这个API测试工具到底谁来用???

    以我熟悉的订飞机票网站的功能来说,通常是要测试一个业务流程,这个流程大的可能涉及到几十个API。

    代入业务场景去测试,可能比程序员自己写用例要好得多。

    所以,对于面向业务方直接使用的API(不是那种中间能力层服务化API),则业务测试人员来使用会更好。

    如果是那种中间能力层服务化API,专门供其他系统RPC调用的,这种我建议是专门派API测试人员来使用。

    (测试人员可以分多种,一种是纯图形化、流程化的业务测试,另一种是面向自动化、工具化,对系统、中间件等进行测试的)


我个人建议,

做一个强大的可视化平台,倒是没必要。

要想灵活性和效率高,还是编程来得快。

我们只需把基础能力做成几个“程序库”,其他人要使用,直接引入即可。

至于编程语言,稍微复杂一点的功能,NodeJS和Go实现起来也并不简单,没有编程基础的人也未必能掌握。

所以,直接用主流的Java语言得了,对于可供不懂编程的测试人员来使用的最最核心和常用的功能,也可以弄一个Web UI页面给他们用。

但是又有点想用NodeJS(ES6),主要是对JSON天然支持用起来太爽了。于是,我深入研究了一下,NodeJS的生态和各种工具库,还是要比Java弱很多,对比了一些常用功能,质量通常也不及Java。JSON字符串的问题解决了,Java 15版本支持“文本块”,可以直接在代码里面写Json,不用被转义字符所干扰,配合强大的JsonPath库(https://github.com/json-path/JsonPath),对JSON字符的处理非常方便。NodeJS也有JsonPath库(https://github.com/JSONPath-Plus/JSONPath),但是感觉没有Java版本的质量高和性能好。嗯,跑自动化测试,应该也是Java好一些。Golang虽然性能更好,但是三方库还是太少了,而且接近C语言的编程风格,对非C系的程序员来说效率还是大打折扣。


测试自动化的关键,并不是推动程序员去自测(例如单元测试),而是需要推动专门的测试人员,一部分人要会编程,会使用Java编写如上所说的API测试程序。


由于有很多思考过程,所以本文的叙述较杂乱。在此做一个最后总结:

    目标是做一个Java库程序版本的“PostMan”,输入标准数据(支持根据规则Mock数据),获得响应结果后可以调用标准库函数验证,也可以自己写Java代码及JSON-Path表达式来验证结果。

    在支持智能单元测试的基础上,增加多接口串联测试功能,可以拉通一整个业务场景自动跑业务流程。

    后期如果有需要,可以在Java库程序基础上,做一个Web UI,给不会编程的测试人员使用。但最好的办法还是教会测试人员写简单的程序,哪怕他们不会编程语言也没关系,只要记住简单的表达式和Java程序运行方法就行了。


补充:为什么不直接使用PostMan或者商业测试平台,非得自己造轮子呢?

    其一:商业测试平台按团队规模、使用人数收费,并不便宜。最关键的是,不开源,无法快速定制。

    其二:UI界面并不是重点,我认为能深度编程的自动化测试工具,才是最强大的。

    其三:这个轮子造起来并不难,难的是要响应团队的需求,从这个角度来说,源码掌握在自己手里,才是最踏实的。


补充(2021.1.18):最近偶然发现,杭州有赞科技公司的接口自动化测试,跟我上面的思路差不多,也是自己用Java设计了一套自动化测试框架。但是,我不想说“框架”一词,显得太笨重,自动化测试框架我见过很多,大多很垃圾,都没有做到我上面设想的那样。不是说实现有多难,而是设计者水平不行。我想说的是自动化测试“工具/库”,这些是很轻量级的、可扩展的,每个项目自行引入,开发和测试人员都可以使用,我设想的是每一个后端项目,都有一个配套的测试子工程,开发和测试人员共同来维护,另外还有一些独立的自动化测试工程,主要用来跑复杂的业务场景(串联多个项目和API)。


© 2009-2020 Zollty.com 版权所有。渝ICP备20008982号