测试学习6

Api测试

API测试基本步骤

  • 主要包括三大步骤

准备测试数据(可选)
通过API测试工具,发起对被测API的request
验证返回结果的response
对于API测试往往采用API测试工具,如命令行工具cURL,图形界面工具Postman,API性能测试Jmeter

基于Spring Boot构建API

功能简单,基于提供的ID值创建一个Account对象,并返回这个新创建Account对象

  • 使用cURL命令行工具进行测试,调用示例

curl -i -H “Accept: application/json” -X GET “http://127.0.0.1:8080/account/ID008”
这行命令中参数含义

第一个参数“-i”,说明需要显示response的header信息;
第二个参数“-H”,用于设定request中的header;
第三个参数“-X”,用于指定执行的方法,这里使用了GET方法,其他常见的方法还有POST、PUT和DELETE等,如果不指定“-X”,那么默认的方法就是GET。
最后“ http://127.0.0.1:8080/account/ID008 ”,指明了被测API的endpoint以及具体的ID值是“ID008”。
  • 当使用cURL进行测试时,常用参数还有两个
  • “-d”:用于设定http参数,http参数可以直接加在URL的query string,也可以用“-d”带入参数。参数之间可以用“&”串接,或使用多个“-d”。
  • “-b”:当需要传递cookie时,用于指定cookie文件的路径。

常用的cURL命令及使用场景

Session场景

-如果后端工程师使用session记录使用者登入信息,那么后端通常会传递一个session ID给前端,之后前端在发给后端的requests中header中需要设置此Session ID,后端从此ID识别出前端是哪个具体的session

  • 此时命令行:curl -i -H “sessionid:XXXXXXXXXX” -X GET “http://XXX/api/demoAPI”
    集体命令
// 将cookie保存为文件
curl -i -X POST -d username=robin -d password=password123 -c ~/cookie.txt "http://XXX/auth"
// 载入cookie到request中
curl -i -H "Accept:application/json" -X GET -b ~/cookie.txt "http://XXX/api/demoAPI"
  • cURL只能发起API调用,本身不具备结果验证能力(验证由人完成),严格意义上,cURL不算测试工具

使用图形界面工具postman进行测试

应用广泛,常被用于web service API测试

第一步,发起API调用

  • 需要选择postman的’request’模块,进入相应的界面后,输入URL,选择GET方法,点击Send发起API调用
  • 返回的response默认以JSON文件形式显示在下面的body中

第二步,添加结果验证

  • 假设测试过程中有以下四个验证点
请求的返回状态码(Status Code)应该是200;
请求的响应时间应该小于200 ms;
请求返回的response header中应该包含“Content-Type”参数;
请求返回的response body中,“type”的值应该是“friends”;
  • 如何验证,需要打开Tests界面,在SNIPPETS依次点击
Status code: Code is 200”
“Response time is less than 200 ms”
“Response headers:Content-Type header check”
“Response body: JSON value check”
  • 点击后,Tests会自动生成验证码,接着只要按照具体的测试要求,对生成的代码进行小修改就可以了
  • 在这里,只需要修改验证的JSON键值对即可,修改完成后点击SEND发起测试

保存测试用例

  • Collection是用来保存测试request的一个集合,Collection还可以建立目录结构以方便进一步的分类和管理
  • 点击Save AS按钮,在弹出的对话框中可以建立Collection,并且可以命名测试request并将其保存到Collection中,以后再要使用这个测试request时,直接在Collection中打开它
  • 先在Collection中新建一个,再点击Save AS选择对应的Collection即可

基于Postman的测试代码自动生成

  • 如果希望将测试requests作为回归测试用例集成到CI/CD的流程中
  • 1,将postman中的测试requests用自动化的方式直接转换成API测试代码
  • 目前Postman已经支持这个功能,可以将保存的request自动转换成常见测试框架支持的代码
  • 点击code按钮进入代码生成界面
  • 2,利用Newman工具直接执行Postman的Collection
  • 首先需要将postman中的collection导出为JSON文件,然后执行下面命令
  • newman run examples/sample-collection.json;

如何应对复杂场景的API测试

测试场景1:被测业务由多个API调用协作完成

  • 很对情况下,一个单一的前端操作可能会触发后端一系列的API调用,由于前端测试不确定性/性能测试要求,必须直接从后端通过模拟API顺序用来模拟测试过程
  • 涉及一系列API调用,会经常存在后一个API需要使用前一个API返回结果,以及需要根据前一个API结果决定后面应该调用哪个API情况
  • 可以通过代码将上个API调用返回结果的某个值传递给下一个API等
  • 如何才能高效获取单个前端曹祖偶所触发的API调用序列
  • 解决这个问题的核心思路是:通过网络监控手段,捕获单个前端操作所触发的API调用序列,可以通过Fiddler网络抓包工具获取调用序列,可以考虑基于用户行为日志,通过大数据手段获取序列

测试场景2,API测试过程中第三方依赖

  • API之间是存在依赖关系的,如果A内部调用了B,当B不可用时,那么A就会受影响
  • 在单体架构下,通常只会在涉及第三方API集成的场景中才会遇到这个问题,但是在微服务架构下,API间相互耦合的依赖问题就会非常严重
  • 这个问题的核心思路是,启用Mock Server来代替真实的API
  • Mock可以简单想象成为了辅助测试而使用的真实api替代品,如果Python一般使用requests框架

测试场景3,异步API的测试

  • 异步API是指,调用后会立即返回,但是实际任务并没有真正完成,而是需要稍后去查询或者回调的API
  • 对异步API测试主要分为两个部分:一是,测试异步调用是否成功,二是,测试异步调用的业务逻辑处理是否正确
  • 测试是否成功,主要检查返回值和后台工作线程是否被创建两个方面就可以
  • 测试业务逻辑比较复杂,因为异步API通常发生在比较慢的操作上,如数据库IO,消息对垒IO,此时测试需要去验证数据库中值,消息对垒中值,这需要测试代码有访问和操作消息队列的能力
  • 在实际工程项目中,这些能力一般会在测试框架级别提供,也就是说要求API测试框架包含对应的工具类去访问和操作数据库或者消息对垒等

API自动化测试框架的前世今生

  • 理解API测试是如何一步一步发展成今天的样子,以‘知其所以然’的方式加深对API自动化测试的理解

早期基于postman的API测试

  • 手工操作多,需要解决两个问题,当需要频繁大量执行测试用例时,基于界面的API测试显得有些笨拙;基于界面的测试难以与CI/CD流水线集成
  • 需要一套可以基于命令执行的API测试方案,这样API测试可以直接通过命令行发起

基于postman和newman的API测试

  • postman+newman+jenkins可以很方便实现API测试与CI/CD流水线的集成,newman是一个命令行工具,可以直接执行postman导出的测试用例
  • 如果涉及连续调用多个API并且有参数传递的情况,poatman+newman就不再是理想的方案了

基于代码的API测试

  • 为了解决上述问题,出现了基于代码的API测试框架,比较典型的是,基于java的OkHttp和Unirest,基于Python的http.client和Requests,基于NodeJS的Native和Request等
  • 对于大型互联网企业,一般会自己开发更适合自身业务上下文的API测试框架,这种框架在使用上有很多优点,而且灵活性也很好,主要体现在以下几个方面:
1,可以灵活支持多个API的顺序调用,方便在多个API之间传递,即上一个API调用返回结果中的某个字段值可以作为后续API调用的输入参数
2,方便在API调用之前或者之后执行额外的任意操作,可以在调用之前执行数据准备操作,可以在调用之后执行现场清理工作
3,可以很方便支持数据驱动测试,就是可以将测试数据和测试代码分离解耦
4,由于直接采用代码实现,所以可以更灵活处理验证断言(assert)
5,原生支持命令行的测试执行方式,可以方便地和CI/CD工具做集成
  • 基于代码地API测试虽然灵活性好,也可以方便和CI/CD集成,但是引入新的问题
  • 对于单个API测试的场景,工作量相比postman大得多,无法直接宠用postman里面积累的collection

自动生成API测试代码

  • 自动生成API测试代码是指,基于poatman的collection生成基于代码的API测试用例,直接使用,存在两个问题
测试中断言部分不会直接生成代码,就是测试代码生成只支持发起request部分,不会自动生成验证测试点代码
测试代码实现一般会和开发的API测试框架绑定,Postman不支持这类代码自动生成
  • 理想做法是实现一个代码生成工具,输入collection中的json文件,输出API测试框架的测试代码,同时把测试的断言一并转化为代码
  • 工具本质就是解析collection json文件中各个部分,然后根据API框架代码模板实现变量替换
首先,根据API框架的代码结构建立一个带有变量占位符的模板文件
然后,通过json解析程序,按照collection json文件的格式定义去提取header, method等信息
最后,用提取的具体值替换之前模板中的变量占位符
  • 有了这个工具后,工作模式可以转换
对于postman中已经积累的collection,全部由这个工具同一转换成基于代码的API测试用例
开发人员继续使用postman执行基本的测试,并将所有测试用例保存成collection,后续统一由工具转换成基于代码的API测试用例
对于
复杂测试场景,可以组装由工具转换得到的API测试用例代码,完成测试工作
  • 实际使用中,测试验证中的断言不好处理

Response结果发生变化时自动识别

  • 对于API测试来说,一个很重要的概念就是,后向兼容性(发布的新版本应该能兼容老版本API)
  • 后向兼容性除了要求API调用参数不能变,还要求不能删减或修改返回的response字段,因为返回的response会被下游的代码使用
  • 所以在这个基础下,诞生了’Response结果变化时的自动识别技术’,就是说,即使没有针对每个字段去做验证,我们仍然识别出那字段发生可
  • 推荐做法时,在API测试框架新建一个数据库,一般采用非关系型数据库,然后用这个数据库记录每次调用的requsts和response组合,当下次发送相同request时,API测试框架就会自动和上次的response做差异检测,对有变化的字段给出警告
  • 可以建白名单,把动态值的字段排除在外(token, session ID, 时间戳等)
  • 可以根据httprunner的yml脚本规则,再加上一些开源组件,做成web页面进行代理抓包,测试人员无论是从web页面还是app操作,只要设置代理过来,就可以看到自己的请求

微服务模式下API测试

  • 微服务架构下,API测试最大的挑战来自庞大的测试用例数量以及微服务之间的相互耦合

单体架构(Monolithic Architecture)

  • 单体架构是早期的架构模式,将所有的业务场景表示层、业务逻辑层和数据访问层放在同一个工程中,最终经过编译、打包、部署在服务器上
  • 单体架构具有发布简单、方便调试、架构复杂性低等优点
  • 随着产品承载的流量越来越庞大,问题:
灵活性差:无论是多小的修改,哪怕只修改了一行代码,也要打包发布整个应用,由于所有代码都放在一起,每次编译都需要很长时间
可扩展性差:在高并发场景下,无法以模块为单位灵活扩展容量,不利于应用的横向扩展
稳定性差:当单体应用中任何个一个模块有问题,都可能造成应用整体的不可用,缺乏容错机制
可维护性差:随着业务复杂性提升,代码复杂性也是直线上升
  • 正是一系列问题,催生了微服务架构

微服务架构(Microservice Architecture)

  • 微服务是一种架构风格,在微服务架构下,一个大型复炸软件系统不再由一个单体组成,而是由一系列相互独立的微服务组成,其中,各个微服务运行在自己的进程中,开发和部署都没有依赖
  • 不同服务之间通过一些轻量级交互机制进行通信,如RPC,HTTP等,服务可独立扩展伸缩,每个服务定义了明确的边界,只需要关注并很好的完成任务即可,不同服务可以根据业务需求实现的便利性而采用不同的编程语言来实现,由独立的团队来维护
  • 微服务架构特点:
每个服务运行在独立的进程中,开发采用的技术栈也是独立的
服务间采用轻量级通信机制进行沟通,通常是基于HTTP协议的restful api
每个服务都围绕具体的业务进行构建,并且能够被独立开发、独立部署、独立发布
对运维提出了非常高的要求,促进了CI/CD的发展与落地

微服务架构下的测试挑战

  • 由于微服务架构下,一个应用是由很多相互独立的微服务组成,每个微服务都会对外暴露接口,同时微服务之间粗壮乃级联调用关系,也就是说,一个微服务通常还会调用其他微服务
  • 挑战主要来自两个方面:过于庞大的测试用例数量;微服务之间的耦合关系

第一,过于庞大的测试用例数量

  • 需要既能保证API质量,又能减少测试用例数量的测试策略–基于消费者契约的API测试
  • 如服务分A,B,C需要测试C。按照测试逻辑需要构建覆盖C的所有测试用例,但是数量太多,发现C的使用者是一定的,即A,B,就变成了测试A,B调用C的所有可能方式
  • 本质上,这样的用例集合就是C对外提供的服务契约,所以叫做,基于消费者契约的API测试
  • 如何找到A,B对C的所有调用,在逻辑结构上只要在C前放置一个代理,所有进出C的请求和响应都会经过这个代理,并记录成json文件
  • 实际项目中,在微服务架构往往存在一个叫做API Gateway组件,用于记录所有API之间相互调用关系的日志,可以通过解析API Gateway日志分析得到每个Service的契约

第二,微服务之间的耦合关系

  • 解耦的方式就是实现Mock Service来替代被依赖的真实service,实现这个Mock Service的关键点就是要能真实模拟Service的请求和响应
  • 拿到契约后,契约的本质就是请求和响应的组合,具体表现形式往往是json文件,可以用这个json文件作为mock Service的依据,就是在收到什么请求回复什么响应
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值