极客时间接口测试陈磊
刚开始都是点点点,后来搞ui自动化。
postman 这款工具也让我重新思考了测试工作,我开始逐渐体会到,测试工作也是一项技术驱动的工作,测试工程师也是一个技术岗位。
在工作中,开始自己写接口测试脚本,封装成测试框架,一直在维护使用。
开发了自动的自动化接口测试平台 AAT《京东质量团队转型实践:从测试到测试开发的蜕变》
从使用工具完成接口测试,到自己写代码完成接口测试,然后慢慢封装自己的框架,最后走到让测试框架更智能的技术路线上,这一路我走了十几年,走过不少弯路,也趟过不少坑。
接口测试,推荐大家了解一下去哪儿开源的 YApi
https://github.com/YMFE/yapi
推荐大家我开发的接口文档和测试的工具,写好接口文档,自动完成接口测试。无需开发环境,直接安装就可以用。https://github.com/arlicle/panda-api
应聘了测试开发工程师,想请问这和测试工程师最大区别是什么呢?
作者回复: 您好,你这个问题是一个我认为不好回答的问题,那么我从我自己的认知给你进行下说明,这又可能并不是行业内都能普遍认可的说法。
1、测试开发工程师,在当今有两个含义,一种是做测试自动化脚本的工程师,另外一种是在测试部门的开发工程师。那么第一种是将业务测试逻辑用自动化代码或者自动化工具等的形式表现出来,便于再次回归的时候,避免人的重复劳动。第二种就是为测试工程师打造一系列测试工具、测试平台的工程师,他们还是开发工程师,仅仅是服务在测试部门而已。
那么测试工程师,当前应该就是业务测试工程师,那么这在很多公司有可能有一个很显著的区别,和一个普遍的共同点,那么先说共同点,就是大家参与需求评审、case的设计、case执行完成业务测试,保障交付质量;区别就是有些公司把业务逻辑的自动化测试代码开发任务归到业务测试工程师的职责也就是测试工程师的职责,也有些公司将自动化测试脚本开发归为测试开发工程师的任务,测试工程师不做对应工作。
但是测试工程师和测试开发工程师并没有高低贵贱之分,他们仅仅是因为测试职业的细分而存在的两个不同的方向的角色而已,但是测试工程师并不是不懂代码的借口。
目前做了一年多功能测试,今年让我们使用httprunner开始做接口测试了,基本都是串接口的主流程功能测试,由于不太了解接口测试,感觉用httprunner实现接口都是套路,只要了解了如何用就都会了,想知道下还有没有别的能够提升的方面?
作者回复: 看看httprunner的代码,你会有更深入的理解,在用的过程中发现有些不好用的痛点,就开始尝试去修改,你会变的技术能力更强大。
https://blog.csdn.net/crisschan/article/details/86502089这个是我的博客,你可以去看看这个“快速划分测试用例优先级”文章
接口就是有特定输入和特定输出的一套逻辑处理单元
测试金字塔模型中,单元测试,接口测试,界面测试,单元测试一般是开发来做,
但是质量又是测试保障,所以由测试来进行接口测试能够在ui测试前面,发现问题,降低开发成本。
两种解决手段:一种是用一些智能化框架补充单元测试工作(如果你对智能化单元测试感兴趣,可以参考我在 2019 年 TiD 上的演讲内容“自动的自动化测试智能化一站式 API 测试服务”);另外一种,就是加大我们自己主导的接口测试的工作投入比重,来弥补单元测试的不足,这样,上面那个金字塔模型就会逐渐演变成菱形模型。
接口测试更容易和其他自动化系统相结合;
相对于界面测试,接口测试可以更早开始,也可以测试一些界面测试无法测试的范围,因此它使“测试更早的投入”这句话变成现实;
接口测试还可以保障系统的鲁棒性,使得被测系统更健壮。
接口测试是通过设计输入和预期输出来完成测试验证的,你之前掌握的测试用例设计方法等测试基本功,在这里还是有用武之地的;
接口测试是一个技术知识和业务知识相结合的工作,可以更好地提升你自己的技术实力,让那些说我们是“点工”的人早早闭嘴;
接口测试也是功能测试,要说有和界面测试不同的地方,仅仅是和我们交互的,不再是开发工程师设计的界面,而是测试工具或者代码。
接口测试的正确性:正确的request正确的返回结果,错误的request正确的拒绝。
一个理想的提测项目,在提测的过程中应该既包含前期参与的产品需求、原型设计,这些是由产品经理来提供的;也包含后端接口文档、代码单元测试脚本,这些是由开发工程师提供来的。
没有接口文档怎么办?
借助一些工具的辅助来完成接口分析;(fiddler)
通过工具截获一些接口信息;
通过分析接口的访问方式、参数等信息整理出一些问题,和研发工程师沟通这些问题,将一些不知道的参数含义、参数取值范围等问题问清楚。
刚来个要求,把app所有接口压测一遍,半天时间,有的时候最难的不是工作,而是遇到这样的傻逼领导(问题,如何进行接口压测?)
对于一个新项目,还是要项目经理,测试经理推动开发人员维护完善的接口文档,从项目流程保证和完善;
工具辅助。借助一些工具的辅助来完成接口分析。分析问题。通过分析接口的访问方式、参数等信息整理出要解决问题。询问解惑。针对问题和研发工程师进行沟通,把一些不知道的参数含义、参数取值范围等问题沟通清楚。
单接口测试的重点,其实就是保证该接口的正确性和健壮性,也就是说,你既要保证这个接口可以按照需求,正确处理传入的参数,给出正确的返回;也可以按照需求,正确的拒绝传入非正确的参数,给出正确的拒绝性返回。
业务流程接口测试,主要是保障通过多个接口的串联操作可以完成原来需求中提出的业务逻辑,验证业务逻辑的正确性。
“正确的流程可以完成处理,不正确的流程可以正确拒绝处理”
业务需求是:进入系统后,选择武器,然后和你选择的敌人决斗。
依据上面这种业务逻辑描述,还不能完成业务流程的接口测试,我们需要对其做进一步的分析和细化。依据这个业务需求,至少有下面这几个业务流程:
正确登录系统后,选择武器,与敌人决斗,杀死了敌人;正确登录系统后,选择武器,与敌人决斗,被敌人杀死;正确登录系统后,选择武器,与敌人决斗,两个人同归于尽;正确登录系统,选择武器,没有选择敌人,自尽而死;正确登录系统,选择一个未提供的武器编号,选择一个敌人,自尽而死;正确登录系统,选择武器,选择一个未出战的敌人(不在返回提示列表中),自尽而死。
对每一个流程,设计参数,执行测试。
在接口测试中,我们通过单个接口测试完成了全部异常状态的覆盖;而在业务流程中,我们更需要关心业务流和数据流的关系,并不需要再过度关心如何用业务流的方法覆盖更多的代码逻辑异常,这也是分层测试中为什么在单元测试和界面测试之间要加入一层接口测试的主要原因之一。
通过单接口测试,可以更加接近于单元测试;通过业务流的接口测试,可以更加接近于界面所承载的交互中的业务流验证,这也是为什么现在很多人在提倡将测试模型由原来的金字塔形往菱形转变的依据之一了。
借助 Newman 这款工具,它就是 shell 下的 Postman,我们将 Postman 的业务逻辑接口测试脚本导出后,push 到本地的 Git 仓库中,持续集成平台就可以通过 pull 对应的接口测试脚本,然后通过 Newman 执行,这样就可以完成持续集成平台的赋能了
在做接口测试脚本开发的技术选型上,我更建议你根据自己的技术实力和技术功底来选择,而不要以开发工程师的技术栈来选择。
课程中用到python的requests库,并将请求方法独立为common类,在另一节里,把测试数据存到了Excel中,并写类支持读取Excel。
# 定义一个common的类,它的父类是object
class Common(object):
# common的构造函数
def __init__(self):
# 被测系统的根路由
self.url_root = 'http://127.0.0.1:12356'
# 封装你自己的get请求,uri是访问路由,params是get请求的参数,如果没有默认为空
def get(self, uri, params=''):
# 拼凑访问地址
url = self.url_root + uri + params
# 通过get请求访问对应地址
res = requests.get(url)
# 返回request的Response结果,类型为requests的Response类型
return res
# 封装你自己的post方法,uri是访问路由,params是post请求需要传递的参数,如果没有参数这里为空
def post(self, uri, params=''):
# 拼凑访问地址
url = self.url_root + uri
if len(params) > 0:
# 如果有参数,那么通过post方式访问对应的url,并将参数赋值给requests.post默认参数data
# 返回request的Response结果,类型为requests的Response类型
res = requests.post(url, data=params)
else:
# 如果无参数,访问方式如下
# 返回request的Response结果,类型为requests的Response类型
res = requests.post(url)
return res
# Python代码中引入requests库,引入后才可以在你的代码中使用对应的类以及成员函数
from common import Common
# 首页的路由
uri = '/'
# 实例化自己的Common
comm = Common()
#调用你自己在Common封装的get方法 ,返回结果存到了response_index中
response_index = comm.get(uri)
# 存储返回的response_index对象的text属性存储了访问主页的response信息,通过下面打印出来
print('Response内容:' + response_index.text)
#登录页路由
uri = '/login'
# username变量存储用户名参数
username = 'criss'
# password变量存储密码参数
password = 'criss'
# 拼凑body的参数
payload = 'username=' + username + '&password=' + password
comm = Common()
response_login = comm.post(uri,params=payload)
print('Response内容:' + response_login.text)
多接口测试
# Python代码中引入requests库,引入后才可以在你的代码中使用对应的类以及成员函数
from common import Common
# 建立uri_index的变量,存储战场的首页路由
uri_index = '/'
# 实例化自己的Common
comm = Common()
#调用你自己在Common封装的get方法 ,返回结果存到了response_index中
response_index = comm.get(uri_index)
# 存储返回的response_index对象的text属性存储了访问主页的response信息,通过下面打印出来
print('Response内容:' + response_index.text)
# uri_login存储战场的登录
uri_login = '/login'
# username变量存储用户名参数
username = 'criss'
# password变量存储密码参数
password = 'criss'
# 拼凑body的参数
payload = 'username=' + username + '&password=' + password
comm = Common()
response_login = comm.post(uri_login,params=payload)
print('Response内容:' + response_login.text)
# uri_selectEq存储战场的选择武器
uri_selectEq = '/selectEq'
# 武器编号变量存储用户名参数
equipmentid = '10003'
# 拼凑body的参数
payload = 'equipmentid=' + equipmentid
comm = Common()
response_selectEq = comm.post(uri_selectEq,params=payload)
print('Response内容:' + response_selectEq.text)
# uri_kill存储战场的选择武器
uri_kill = '/kill'
# 武器编号变量存储用户名参数
enemyid = '20001'
# 拼凑body的参数
payload = 'enemyid=' + enemyid+"&equipmentid="+equipmentid
comm = Common()
response_kill = comm.post(uri_kill,params=payload)
print('Response内容:' + response_kill.text)
测试框架的形成是在撰写大量测试脚本的过程中不断抽象封装出来的,然后,再用这个不断完善的框架,改写原有的测试脚本。循环往复这个过程,你就会慢慢获得一个独一无二的、又完全适合你工作的接口测试框架。
从测试脚本到测试框架的转化过程:
不断撰写测试脚本,所有的抽象和封装都是站在已有的测试脚本基础之上的;多观察已经写好的测试脚本,找出其中的重叠部分,最后完成封装;以上两步是一个不断循环又循序渐进的过程,你要在你的工作中始终保持思考和警惕,发现重复马上进行框架封装。
测试框架的封装和抽象过程并不是一蹴而就的,它是靠一点一点的积累得来的,因此,你要通过自己的实践,慢慢积累和完善你的测试框架,而不要妄想一次就能有一个完善的测试框架。我相信,当你通过写脚本完成整个项目的接口测试后,你一定会得到一个完美的测试框架。
RESTful 风格的接口了。它主要就是一组设计原则和约束条件,本质上就是让消费者依据 URI 就可以找到资源,并通过简单的服务输入输出完成服务的交互。它所约束的每一个 URI,都是独一无二的一个资源,通过 HTTP 的方法进行资源操作,实现表现层的状态转化。
(就是一套规则,通过一个url去管理资源,通过不同的请求方式对资源做修改或者更新,可以用万能螺丝刀来比喻)
RESTful 的规定,使 HTTP 的很多方法都被利用到了,比如说,Get 方法用来获取资源,Post 方法用来新建资源(或者更新资源);再比如说,Put 方法用来更新资源、Delete 方法用来删除资源等等。
要想让框架支持restful接口,只需要在common中加入put和delete即可。
微服务接口:怎么用Mock解决混乱的调用关系?
如何测试陌生的协议?
初级测试工程师。他应该懂得接口测试,可以使用接口测试工具完成接口测试任务;他也要有接口测试的思维,能够将这种思维在实际项目中应用落地。
中级测试工程师。他要能编写测试代码,可以使用一种编程语言完成接口测试任务。
高级测试工程师。他必须有能力封装适合团队的测试框架,并能提供给持续集成、持续交付平台调用。要保持自己高级测试工程师的段位,你需要不断努力,不断学习和总结,时刻保持作为一个测试框架维护者的心。在这里,测试框架封装主要参数化的设计,不同接口、不同协议的支持等内容。
如何使自己不断成长为高级测试工程师呢?
我建议你可以通过三步来规划你的学习:
1、从实际动手开始学习测试技术。你最好还是从一个实际例子出发开始学习,这就和大部分编程语言都从 Hello World 开始一样。直击问题,这样才更能激发你的学习兴趣。
2、不断遇见问题,不断解决问题。你在实际工作中,肯定会遇见很多问题,你一定要一个一个去解决,并不断地从问题中总结可复用的经验,这样就会形成一套你自己独特的学习思路,以及更适合你自己的技术学习方法,更重要的是,这样学习更不容易遗忘。
3、掌握理论知识。我之所以将理论知识的学习放到最后,是因为当你知道如何用一个测试技术解决问题的时候,再去学习理论,就不会出现由于理论枯燥、记不住而放弃学习这样的情况了。同时,实践后再学习理论,每看到一个知识点你就会有“原来是这样实现的啊”这种感觉,你就很容易理解并记住它了。