在Web应用或APP的功能测试中,测试借助Charles可以清楚地看到Web应用或APP与server之间发生了什么,是测试同学必备的好帮手。
在特定的测试场景下,测试人员需要对Web应用或APP与server之间发送和接收的数据做变更,即改写接口,构造常规手段难以产生的接口数据,以提高测试覆盖率和效率。
此时,Charles能很好的帮助测试同学达到目的。
Charles提供了Compose、Breakpoints、Map Local、Rewrite四款可以改写接口的功能,它们都很优秀,但各有侧重点。
1 Compose,改写接口的Request,类似Postman
这个功能Charles的官网上没有具体的介绍,实际使用后感觉更像是Charles内置了一个简易版但可能更好用的postman。
Compose可以在已经被Charles抓取到的接口的基础上对接口的参数进行修改,然后执行接口,向服务器发出请求,因此,实际测试中,Compose可能会比postman更方便使用。
有两种方式启用Compose。
1.1 方式1:手动创建新接口,类似Postman那样
路径: Charles → Tools → Compose/Compose New
按照要求填写对应内容,点击Compose,想要改写的接口出现在Charles左边窗口,接口左边有钢笔图标,表示该接口可以编辑,且对应该接口的右边窗口也为可编辑状态。
可根据需要补充接口请求必带信息,然后点击Excute,下发接口
还有其他操作,可以根据需要自行选择。
1.2 方式2:基于已有的接口创建
此方式大大节省了编辑时间,只需按照需要增删改对应的参数即可。
选中要想改写的接口,然后鼠标右键,出现的操作列表里点击Compose
紧接着选中接口的下方新增一条相同的接口记录,且接口左边有钢笔图标,即该接口为可编辑状态
1.3 小结
实际使用过程中,第2种方式使用的更多,测试人员往往只需要改变某些参数的值,就可以覆盖不同的场景。
例如有鉴权的接口,如果通过第一种方式或者postman,首先需要根据token或者签名的规则去生成一个,而这个规则会涉及到参数拼接以及代码编译,并且测试人员重点并不在这里,此时,第二种方式的优势就出来了,不需要测试人员写鉴权脚本,在修改了目标参数的值后,对应的token或者签名随之生成,精力能专注在测试场景的构造上,提高测试覆盖率和效率。
2 Breakpoints,接口的Request和Response均可改写,但拼手速
和开发同学调式代码时打断点(Breakpoints)一样的原理,对设置了断点的接口,再次捕捉到该接口,会中断接口的request或者response,然后就可以按照需要改写接口了。
这里也有2种方式给接口添加断点:
2.1 方式1:Charles → Proxy → Breakpoints Setting
2.2 方式2:右键要设置断点的接口,在弹出的操作列表上点击Breakpoints
接口开启断点后,接口request经过Charles,会自动单独打开一个断点窗口,tab页Edit Request可以改写接口请求。
接口的response经过Charles,自动增加tab页Edit Response,可以改写接口返回。
Abort按钮会将接口的request/response彻底截断,然后返回一条错误信息;
Cancel按钮会将接口的改动忽略掉,然后下发request或者返回response,使接口就像未被中断一样的请求和返回数据;
Excute按钮使接口带着其request/response的改动点继续往下执行。
2.3 小结
方式2是接口设置断点的快捷方式,方式1可以批量导入备份的接口断点配置,也可以将当前断点配置导出备份;
所有的断点配置可以在方式1下查看,可以选择性的开启部分接口的断点,关于断点的所有配置和操作都在方式1下。
3 Map Local,改写接口的Response,移花接木
类似开发同学mock数据提高开发效率一样,测试同学会使用Map Local的功能来满足不同测试场景下所需要的对应接口返回的数据,从而提高前端功能测试的覆盖度和效率。
顾名思义,Map Local是映射到本地文件,实际并没有对接口的Response做真正的改动,可以理解为将接口的请求重定向到了本地,当接口被Charles捕捉到,自动将本地文件作为接口Response的内容返回给前端,因此完全可以根据测试用例所需要的数据来定制接口返回结果。
Map Local也有2种开启方式,类似Breakpoints
3.1 方式1:Charles → Tools → Map Local
3.2 方式2:鼠标右键,点击操作列表下的Map Local
首先需要将接口的Response以文件的形式保存到本地,然后按照测试场景需要在文件中替换上需要的数据,最后将需要改写的接口映射到这个本地文件,让本地文件的数据代替线上数据返回给前端。
3.3 小结
借助Map Local,测试同学想怎么测就怎么测,大大提升了测试的覆盖率和效率。
需要注意的是,Map Local生效后,无论接口参数如何改变,该接口的返回都是加载本地文件内容,当需要接口实时返回服务器端数据时,记得取消掉该接口的Map Local配置。
开启了Map Local,但按照映射路径并未找到本地文件,接口请求会发送到服务器,并直接将服务器上的数据返回,即Map Local配置因路径问题未生效,接口会正常请求和返回结果。
4 Rewrite,接口的Request和Response均可改写,改的不动声色
该功能的命名很直接,就是接口改写,确实,该功能可以在接口不被中断的情况下,在向服务器发起请求以及将服务器响应结果返回的过程中,不动声色地按照改写规则替换对应内容,而且该方式可以同时针对同一接口做不同目的的改写。
启用该功能只有1种方式,路径: Charles → Tools → Rewrite
配置Rewrite的步骤较多,这里不详细介绍了,第6部分的实例部分会详细介绍了Rewrite的配置过程。
小结
Rewrite的改写功能很强大,但是相较于其他3个接口改写功能(Compose、Breakpoints、Map Local),配置起来是最复杂的,极容易出现配置不生效的情况,而且难以定位不生效的原因,所以在使用的过程中,可以由最简单的规则开始一点一点试探,借助Rewrite错误日志,确保Rewrite规则已经捕捉到了目标接口,然后再来配置最终想要的改写规则。
5 总结
Compose:类似postman,不能对接口Response做改写,方便测试同学遍历接口不同参数值对应不同返回结果,提高测试覆盖率。
Breakpoints:类似开发代码调试打断点,但是对于响应时间有要求的场景,Charles断点极容易改写失败。因为Charles的断点不会像开发同学的断点那样能坚持等到下一条指令,可能在没等到接口的Request修改完继续执行,接口就自动做超时处理了,或者前端在一定时间内没等到接口的Response,也自己做了相应的超时处理了,此时就要拼手速了,手速快,可能接口的改动可以赶在超时自动处理之前,下发到服务器或者返回给前端了。
Map Local:类似mock数据,将本地文件内容作为接口的结果返回,但如果业务逻辑存在先后请求同一接口(前后接口参数不同,返回结果不同),但只需修改某一次的接口返回结果,Map Local不再适用了。
Rewrite:Breakpoints和Map Local无法实现的场景,可以使用Rewrite,可以将Rewrite看作Map Local的升级版。
改写接口的Request,可以选择Compose、Breakpoints和Rewrite,例如要验证开发同学修复bug后返回数据是否正确,但又不想从前端操作,可以直接使用Compose将接口再次执行一遍,但是如果想要看数据返回到前端的效果,可以选择Breakpoints和Rewrite。
改写接口的Response,可以选择Breakpoints、Map Local和Rewrite,例如只关注接口返回数据在前端的展示效果,我们可以使用Map Local的方式,只需修改本地文件然后保存,当前端再次请求接口数据时,本地文件的改动就可以生效,所得即所改。
6 实战
不同类型的商品,在订单详情页会出现购买须知或者其他协议,这里需要重点查看,当接口返回多个购买须知和购买协议时,前端需要折行展示,而不是超出屏幕。
由于协议是在后台随商品一起配置,且流程较复杂,比较耗时,我们完全可以通过改写接口,增加接口返回的协议数来达到目的。如下图所示是通过Rewrite功能改写接口实现的效果,可以说是一劳永逸。
因为要改写接口的Response,首先尝试经常使用的Map Local方式,当设置好Map Local后,前端交互发生异常,经了解发现,从购物车到结算页,前端需要请求2次结算接口,但2次接口所带参数不同,对应的返回结果也不同,使用Map Local后,2次结算接口的请求都被映射到了本地同一文件,导致2次结算接口请求返回结果相同,与业务逻辑不符,故出现异常,而协议内容是第2次请求接口返回的,只需要而且只能改写第2次接口的返回,所以Map Local并不适用此测试场景;
其次尝试了Breakpoints,但由于该功能在全端都要做,其中Android端手速最快时可以改写成功,但iOS端以最快速度改写接口返回结果后,接口状态直接变为异常,iOS端没能及时接收到接口的返回数据,所以Breakpoints此时也败下阵来;
最后通过Rewrite成功改写了各端请求checkout接口后的返回结果,在满足业务逻辑的前提下,成功模拟了接口返回多个购买协议的场景,目标达成。
下图是App端从购物车到结算页,前端请求2次结算接口,参数不同,返回结果也不同。
我们需要改写第2次接口,改写前,接口返回结果如下
接下来,通过配置Rewrite的改写规则,将接口Response Body里的购买须知由1个变为4个,满足前端折行显示需要的购买须知数量。
6.1 打开Rewrite Settings页面
Charles工具栏,依次点击 Tools → Rewrite,进入到 Rewrite Settings 页面,如下所示
左侧显示已添加各端checkout接口的改写规则,下面详细说明Add、Remove、Import、Export四个按钮的功能和使用
Add:新增1个rewrite配置
Remove:将选中的rewrite配置删除;选中是指鼠标左击选中,对应的rewrite配置会高亮显示,Windows系统,按CTRL键,鼠标左击可以选择多个,同时remove多个
Import:导入已存在的rewrite配置文件
Export:将rewrite配置导出成配置文件,方便保存和传递
6.2 Add操作
点击左侧【Add】,新增一个改写配置,然后按照如下序号所示步骤逐步配置
6.3 添加需要改写的接口
填写完成后,点击OK,保存Location配置
备注:
Location下的内容填写的越详细,匹配的接口范围越小,改写规则影响到的范围就越小
1个rewrite配置下可以添加多个接口(Location)
6.4 添加接口改写规则(Rule)
改写checkout接口返回的协议数据,即agreement字段的值,实现接口返回的购买协议由1个变为多个
备注:
Match处填写内容:{"link":"https://hostname/******/8739936ea16c.html","name":"《用户购买须知》"}
Replace处填写内容:{"link":"https://hostname/******/8739936ea16c.html","name":"《用户购买须知》"},{"link":"https://hostname/******/8739936ea16c.html","name":"《用户购买须知1》"},{"link":"https://hostname/******/8739936ea16c.html","name":"《用户购买须知2》"},{"link":"https://hostname/******/8739936ea16c.html","name":"《用户购买须知3》"}
rewrite原理,对于经过Charles代理的接口,通过Location和Rule,精准定位到要修改的内容,然后使用Replace处填写的内容进行替换,从而达到改写接口返回数据的效果
在1个接口(Location)下可以添加多个Rule,同时改写接口返回多个字段的值
6.5 勾选改写接口和Enable Rewrite
以上步骤配置完成后,注意Rewrite接口配置前复选框和Enable Rewrite前复选框
然后,一次点击Apply和OK,将Rewrite配置保存
最后,我们看到配置生效后接口的返回,购买须知由1个变为了4个,改写成功
7 文末小建议
关于Charles的各个功能的用途和使用,建议直接去看官网介绍
本文重点讲述了4个功能的特点和侧重点,偏重理论,对于功能的具体使用步骤并没有展开讲解,如果在实际使用过程中遇到问题,欢迎留言,我会一一回答的哦^v^