接口测试 自己设计的接口自动化测试框架以及 对于接口自动化测试的疑惑

徐旻 · 2017年02月02日 · 最后由 徐旻 回复于 2017年02月18日 · 2390 次阅读

春节结束,公司就要开始讨论接口自动化测试的议题了。
遇上参考了 testerhome 中接口测试的文档,自己写了一个接口自动化测试的原型。
因为没有接触过接口自动化测试,都是自己凭空想象的,肯定有很多不足的地方,希望大家指教。

语言:python2.7
数据驱动:execl
自动化测试对象:http 协议的接口,返回值是用 json 解析的。

第一步,参数
我以前做过一段时间单元测试,那个时候等号右边的叫做输出值,等号左边的叫做输入值。
于是我拿以前做单元测试经验来设计,我们的 request 就好比一个输入值,那么 response 就是一个输出值。
request 里其实就是很多参数的组合排列,如果想做一次覆盖率相对高的接口测试的话,个人觉得先把每个参数可能的值罗列出来
比如 有一个参数 n ,根据文档他可以是 -1,25950,25951,25952,25923 中的任意一个数,那么我们设计的时候处了这 5 个输入值考虑进入,还要考虑
0,
边界值:-2,0,25949,25924,
任意值:10 之类的,
空:就没有改参数没有写。
单单参数的排列组合,我觉得就是一个庞大的数字了。
作为覆盖率高为目标的话,我觉得要把这些排列组合都列出来,然后根据实际情况对 case 进行删除。
如果排列组合出来的 case 数量可以接受,也可以直接使用。

那我就先把参数进行一次排列组合

根据参数运行函数 init_para.py
生成了 work sheet,里面存放着 request 的参数的值进行排列组合后的全 case

第二步,发送 request,得到 response。
这个在社区里有很多列子了,百度也可以查到,就不需要多讲了。

第三步,解析 json
正如我前面说的,我们拿到了一个 json,我们就需要解析他。
我们先来看下我做的 json 解析的效果。


可以看到经过处理,我们可以拿到每个有实际内容的 json 的路径。
当然了,这个用一次制定的的参数提交的 request,然后拿到的 response 的 json 进行的解析,如果想拿到最大范围的解析,一定要仔细设计这次 request 的参数

第四步,期待值得设置
有了输入和输出,那么就需要写预期值。
我想到了 3 种预期值得输入方法。

1.手工填写
根据接口文档,去手动填写相对应的预期值。
这个绝对是一个体力活,除非 case 相对较少,不然不推荐。但是绝对精确(如果真的有人可以有耐心去正确填写完全部的预期值)

2.用逻辑去判断
比如返回值是在某个数组的当中
逻辑判断最大的有点是,如果你写的是一个 sql 语句,那么预期值就是直接冲数据库里动态拿到,这个我觉得是最重要的。

3.运行一次程序,得到 case 的相对应的结果,然后把结果复制给预判值。
这种方法适合用于回归测试,因为这种做法的前提就是假定当前的接口是没有错误的。

第五步,返回结果和预期值的比较
看图说话

底色为蓝色说明这个返回值因为没有给过期待值,但是和逻辑判断中的值符合
底色为绿色说明这个返回值和预期值一致。
底色为红色说明这个返回值和预期值不一致或者说没有和逻辑判断中的值符合

我能想到的接口测试框架暂时就这么多了。不足的地方,请大家指教。
很多细节的地方还没有考虑到,或者因为没有经验根本没有想到。

接下来就是请大家解惑。

  1. execl 宽是有限制的,我这个 execl 版本比较老,超过 256 个字段就不行了。 如果用 js + mysql 的话 应该可以比 256 个多的多。 到底在真实的工作中,那种组合用的比较多 python+execl js+mysql

2.如果接口自动化要推广,肯定需要一个相对易用的界面。有多少公司用了图形界面,有多少公司用的是命令行,或者直接使用脚本的?

3.我们在实际工作中接口测试真的会做到那么细致吗?
主要我把 request 的参数做了一次全遍历的组合,发现真的要到达一个高覆盖率的测试的话,case 可能是万级别的。
response 的 json 数据真的要去完全分析的话,可能都要分析到百级别的。

我看到社区很多自动化接口测试基本上都是基于回归测试,也就是说录制接口的返回数据脚本,生成一个预期值,再跑第二次,进行一次 diff。感觉就是项目中期介入。
如果是项目初期就开始设计接口测试,大家应该是怎么做的?

代码我这里就不贴了。
需要参考可以去这里看
https://git.coding.net/lunamagic/test_of_api.git

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 12 条回复 时间 点赞
徐旻 关于自动化接口测试平台的想法和实现 中提及了此贴 02月08日 09:55
陈小憩 接口自动化设计的疑问点整理 中提及了此贴 09月21日 10:05
徐旻 #12 · 2017年02月18日 Author

#11 楼 @wudongzhao5689 谢谢,的确这个版本没有写全,所以通过大家的帮忙,我在这个原型上搭建了另外一个框架。是https://testerhome.com/topics/7537 帮忙看下,修改后的框架有什么不足的地方。

接口是初期测试,中后期意义不大。都上线了,你测它有啥用,充其量算监控。你上面写的,第一 token 之类不要写死,可以去数据库获取,不然测试的意义不大。第二就是请求参数,这一步更倾向于功能测试。正如你所说,组合太多,所以我一直在开发一个生成接口数据的生成器,制定好规则后就自动生成,写入数据库中,可惜这是个美好的愿望。但接口最重要的几点你没有写全,一是返回结果的检查,二是数据交换,三是日志报告

徐旻 #10 · 2017年02月05日 Author

#9 楼 @chenhengjie123
你看下我说的第一步,就是通过给参数设置 各种数值,然后把他们排列组合一下,自动生成 testcase。 是否和你说的小工具的意思符合。

#8 楼 @lunamagic 你的安排也是可以的。不过我觉得这样安排条理性是提高了,但工作量还是比较大,毕竟一个接口一般都有数个参数,边界值排列组合起来的用例数量还是不小的,能够用工具生成效率会高不少咯。

PS:我还是比较建议先确保了正常场景和预期会出现的异常场景的覆盖,再考虑这种参数排列组合的用例,效果可能会好一些。

#6 楼 @chenhengjie123
关于边界值是否需要生成用例,你的小程序去生成,如果我这样安排如何。一张 execl 里面写主要 case,另外一张或者几张 execl 表里专门用来测试边界值,比如有参数 A,B,C,表格 1 里面的 case 是一些主要通过 case。 然后 表格 2 里面 我们固定 B,C,可以做一个 A 的边界值全 case 测试。如果有必要还可以有表格 3,固定 A,C,测试 B 的边界值的全 case 测试。这个以前我在单元测试的时候,因为遇上过参数的排列太多了。造成一张 execl 表不可能存储下全部 case,所以我们公司就用分表去解决这个问题。

用 sql 来做预期值其实是一种美好的期望,谢谢你指出来。虽然可能在动态的测试环境中减少一些工作量,但是的确根据测试环境的不同,不一定就是一句 sql 就可以完成的。这个时候你说的固定数据条件 可能就是最好的解决方案。 前提就是要有固定数据的条件或者规定。这个应该不算很难。的确是个好建议。

#2 楼 @lunamagic 52777879

—— 来自 TesterHome 官方 安卓客户端

#5 楼 @lunamagic 加上优先级其实还是没有减少多少工作量,毕竟还是要先穷举再去掉优先级不高的用例。我觉得边界值覆盖这种另外做个小程序来生成用例会比较好,既没有牺牲完整性,也减少了工作量。

举个例子,接口规则是参数 a 为 0~1000 的纯数字,那么那个小程序自动生成的用例就是-1、0、1000、1001、"0"、"a"、""、null 这几个边界值。当然,前提是你确认确实有达到这种覆盖率的必要,毕竟写这个小程序本身也有一定工作量。如果不重要,与其花时间把接口各个参数的排列组合覆盖全 ,还不如多写几个接口的测试用例。

另外,你提到的这种方式在我看来有点像是把接口的业务逻辑在接口测试中再次实现了一次,然后直接对比两种实现结果是否一致。这样就变成了验证接口是否正确执行了 sql 语句。

我觉得这样的测试有所欠缺,比如 sql 语句本身是否正确就没有测试到了,而且可能适用场景有限(很多时候接口背后的逻辑不仅仅是一句 sql ,此时实现业务逻辑的成本很高)。我比较偏向于设计几个比较具有代表性的参数 1,参数 2,参数 3,以及数据库预先配置好需要返回字段 a 的相关配置,即接口外部数据条件(接口数据、数据库数据)都是固定的,然后根据需求得出的接口返回值自然也是固定的。测试的时候直接比对接口返回的字段 a 的值是否和用例一致就行了。

#4 楼 @chenhengjie123 很感谢你提供的思路,我开始设计的初衷 是尽量保证 case 不遗漏,通过对参数的排列组合虽然可以尽可能的提高覆盖率,正如你说的,会多出很多非核心功能的 case。 如果给参数 加上一个优先级,那么在排列组合的时候,每个 case 的参数就会有一个自己的优先级,然后根据 case 的参数优先级排列,优先级高的排在前面,这种方法不知道可行否?

我突发奇想,开发设计一个接口,接口中有很多数据。我们去做预期值的时候 也可以当做一个我们测试自己写的小接口,由于这个接口只要返回一个值,相对来说准确度就很高。 我们拿 小接口去测试 开发写的大接口的特定的数据。 一个目的,冲两条路走,结果还是一样。这样的框架是否会提高自动化的程度。
举个例子
接口 api 的参数 1,参数 2,参数 3 然后返回了 json 我现在要做 json 字段 a 的检测(字段 a 数据是从数据库里通过开发写的 sql 拿到的)
我们测试用 参数 1,参数 2,参数 3 访问数据库,用 sql 语句直接拿到字段 a 的值。
然后比较开发写的接口中字段 a 的值 和我们写的字段 a 的值是否一致。
这样我们的自动化程度是否会提高呢?

作为覆盖率高为目标的话,我觉得要把这些排列组合都列出来

个人觉得参数边界值完整覆盖这个,如果确实需要,建议做个小程序通过规则自动生成。手写数量很多,维护性也不高,而且说实话,部分用例实用性并不强,因为实际使用场景遇到的可能性很小。

我觉得,我们应该追求用尽可能少的用例覆盖尽可能多的高优先级场景,先确保核心功能可用,然后再是异常场景(比如参数不合法)。在接口还没开发完成前,根据协议覆盖最核心的部分(正常流程、需求中明确说明的异常流程)就差不多了。毕竟接口一天没开发完,一天都还有可能改,用例多的话自己维护工作量就大了。

PS:有条件看到开发源码的话建议看下开发源码,这样设计出来的用例准确度更高。有些边界值在程序里面其实并不是边界值。

我也有同样的疑惑,希望有比较了解接口自动化的同行交流一下大家是怎么做接口自动化的?

#1 楼 @hu_qingen 看了你写的文章,有几个问题想当面问下,不知道可否给一个联系方式 qq 或者微信。

可以参考下我之前的几篇文章

—— 来自 TesterHome 官方 安卓客户端

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册