为实现代码复用或者功能复用而实现的,通过Http协议、Socket协议等提供给其他人调用的函数,我们测试的80%的接口都是基于HTTP协议的网络服务。
1.按调用关系分类 垂直层:应用层与服务层传递数据的HTTP 接口 水平层:服务层与服务层间传递数据的接口 常见http、rpc 系统级别调用:提供给第三方系统调用的接口 常见http 、rpc、websocket 比如:淘宝开发api、气象局的天气预报接口、中国航空信息公司提供的航班信息服务、第三方登录接口 2.按技术实现划分:restful风格、webservice风格、rpc、WebSocket
把网络上的所有事物都抽象为资源,每一个资源都有唯一的URI标识符(统一资源定位符)指向它。接口使用标准的http协议,通过GET、POST、PUT、DELETE方法改变资源的状态。 restful风格的接口类似于还原、无包装的http协议。 好处:开发简单、轻量级 缺点:随意性比较强、规范性不好 安全性、稳定性、性能需求依赖于后期优化
比如: SOAP WebService 要求请求和响应的正文内容都是标准的xml格式的,接口的所有参数配置和信息描述都在一个xml文件里–WSDL,有严格的规范和标准,包括安全,事务等各个方面的内容,也要借助于各种网络协议传输(最常见 绑定http协议),类似被包装过的”http”协议。 好处:规范(传递数据必须是xml格式接口描述放在wsdl中)、安全性高 http 只用post 且传递数据为xml的协议为soap协议,是http协议的子类 缺点:笨重、调用麻烦
RPC 是一个技术概念 ,不是协议 比如在大型系统的内部,单独有一个订单系统,支付系统,商品系统,用户系统等,每个系统都是分开部署,单独上线。 如果系统A的代码,想调用一个内部服务B的某个函数(服务),如果直接使用http协议,必须有明确的请求地址,携带完整的参数调用(包括头),要单独添加监控机制或负载均衡,一旦请求失败,即使有失败重连的机制,也会造成不好的用户体验,动态扩展需要增加配置。 RPC 是一种C/S模式,使用RPC框架,可以无感知调用(我只认识服务,像调用一个远程函数一样方便),长链接,不必每次通信都要像http 一样去3次握手,减少了网络开销;RPC框架一般都有注册中心,有丰富的监控管理;发布、下线接口、动态扩展等;有较为健全的负载均衡和容错机制;安全性高;测试起来也比较直观。
Dubbo 框架,是众多RPC思想实现的框架之一,阿里研发后开源。现在逐渐被阿里换代成:HSF、SOFA。 使用dubbo框架,需要对外提供jar包,如果jar包更新,其他端也需要更新。但是性能比restful的高
简单的理解是:将数据定义为xml格式,通过http协议进行远程传输 类库:xmlrpclib --标准库 import xmlrpclib server = xmlrpclib.Server(‘http://地址+接口名’) server.方法名(参数列表)
安装注册中心:zookeeper 安装简单监控中心:simple-monitor web容器:提供访问 jetty、spring、tomcat dubbo管理后台:dubbo-admin 项目 api --定义接口信息 provider --接口逻辑的实现部分 依赖api项目 启动spring容器运行后 向注册中心注册服务 consumer --调用者
1、dubbo是支持hessian+http协议调用的,hessian是一种二进制序列化的方式,请求和响应的参数都是二进制形式。 2、用python调用的dubbo的时候,可以使用hessian+http的方式调用。dubbo项目要配置使用hessian方式序列化,需开发在项目中修改配置文件 dubbo.protocol.name = hessian 3、使用hessian+http这种方式调用dubbo,需要安装一个第三方模块,python-hessian pip install python-hessian 4、调用dubbo接口需要知道dubbo接口的调用地址、方法、入参对象和入参,可通过接口文档或者注册中心后台管系统查询。
5、调用函数去请求接口
#从pyhessian导入HessianProxy,用来发请求 from pyhessian.client import HessianProxy #把python的数据类型序列化成二进制的 from pyhessian import protocol def dubbo_api(url,interface,method,param_obj,**kwargs): ''' :param url: url地址 :param interface: 接口名称,因为这里可能还有别的服务要测,接口名不一样,这里定义成变量 :param method: 调用哪个方法 :param param_obj: 入参的对象 :param kwargs: 这个用关键字参数,因为每个接口的参数都不一样,不固定,所以这里用关键字参数 :return: ''' # 构造二进制的入参 req_param = protocol.object_factory(param_obj,**kwargs) try: # 生成一个请求对象 req_obj = HessianProxy(url+interface) #getattr是python的内置获取对象的方法,可从构造的请求对象里获取到方法 #调用生成的方法把前面生成的序列化好的参数传进去,然后获取到返回的数据 res = getattr(req_obj,method)(req_param) except Exception as e: print('有异常了,异常信息是:%s'%e) #这个是自己定义的异常 res = {"msg":"异常:%s"%e,"code":300} return res if __name__ == '__main__': url = 'http://192.168.1.100:8181/api/' interface = 'yz.dubbo.api.HelloApi' method = 'hello' param_obj = 'yz.dubbo.api.param.Param' params = {"sth":"dubbo","ints":[1,2,3],"maps":{"name":"dubbo"}} #这个入参,为了不定义多个变量,咱们把它写成字典形式的,就和stu=dubbo这种方式调用是一样的 over = dubbo_api(url,interface,method,param_obj,**params) print(over)#打印结果WebSocket
1、WebSocket是html5中的一个应用层新协议,使得浏览器具备了实时双向通信的能力。 2、http协议的无状态性和单向性,如果要等待服务器的通知,传统方式要轮询服务器,造成资源浪费。使用WebSocket 只需要经过一次HTTP请求,就可以做到源源不断的信息传送了(异步请求或者回调都是这个原理)
安装:pip install websocket-client
import websocket ws = websocket.create_connection('ws://xxx.xxx.xx') ws.send("string") ws.recv()统一资源定位符 scheme://username:password@host:port/path/params?query#frag 端口:用来标识进程地址 path:资源路径
1、http是标准的单向、无状态协议 2、http请求结构 请求行、请求头、请求正文 请求行包含:请求方法(get\post)、请求地址(url)、请求协议(http/https) 请求头:通知服务器有关于客户端请求的信息,比如token、请求格式、Encoding等 请求正文:有四种格式 a.binary:数据流,只能上传一个文件、传给服务器二进制流格式。 b.raw:纯文本格式 ,支持xml\html\json\text等格式 text/plain 纯文本。浏览器不解析 text/html html。浏览器自动解析 text/xml 或 application/xml 后者可指定编码格式 application/json:消息主体是序列化后的 JSON 字符串 c.form-data:将表单中数据全部上传,可上传文件,参数以键值对字典的格式发送到服务器 d.x-www-form-urlencoded: 浏览器默认的表单提交格式,不能上传文件,以键值对形传参,对数据进行序列化处理。参数会以“key=value&key=value&key=value” 的形式发送到服务器 3、http响应结构 响应行、响应头、响应正文 响应行:http-version 服务器端Http协议的版本、status-code 响应头:以明文的字符串格式传送,以冒号分隔的键/值对 响应头部通知客户端有关于服务端的应答信息 Server、 Content-Type … 响应正文:待测试数据 html格式、xml格式、json格式
1.GET: 发送一个请求取得服务器上的某个资源。 2.HEAD:本质同get类似,但是HEAD仅包含HTTP头信息,用于判断某个资源是否存在。 3.POST: 向服务器提交数据。 4.PUT: 和POST类似,都是向服务器发送数据。区别在于PUT指定了资源的存放位置,而POST的数据存放位置由服务器自己决定。HTTP表单不支持put。PUT常用于上传文件。 5.OPTIONS:用于获取当前URL所支持的方法。若获取成功,HTTP头会包含”Allow”的头,如“GET, POST”。 6.DELETE: 删除某个资源 7.TRACE:获取服务器请求过程中的代理信息
1.get没有正文、post有正文 2.get 参数在地址栏中,参数有限,post请求的参数可以放在url后传递、也可以放在请求体中(大小不受限制) 3.get请求安全性差,所有参数都是明文传送、会被浏览器缓存 4.设计用途不同:get用来查询,解决小数据量传输,post结果大数据量传输与修改
HTTP是超文本传输协议,被用于在Web浏览器和网站服务器之间传递信息,HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此,HTTP协议不适合传输一些敏感信息,比如:信用卡号、密码等支付信息。
为了解决HTTP协议的这一缺陷,需要使用另一种协议:安全套接字层超文本传输协议HTTPS,为了数据传输的安全,HTTPS在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。 https需要身份认证+加密传输数据
客户端在使用HTTPS方式与Web服务器通信时有以下几个步骤,如图所示。 (1)客户使用https的URL访问Web服务器,要求与Web服务器建立SSL连接。 (2)Web服务器收到客户端请求后,会将网站的证书信息(证书中包含公钥)传送一份给客户端。 (3)客户端的浏览器与Web服务器开始协商SSL连接的安全等级,也就是信息加密的等级。 (4)客户端的浏览器根据双方同意的安全等级,建立会话密钥,然后利用网站的公钥将会话密钥加密,并传送给网站。 (5)Web服务器利用自己的私钥解密出会话密钥。 (6)Web服务器利用会话密钥加密与客户端之间的通信。
一、基于IP认证
二、基于用户认证basic/digest
测试的对象是接口,测试步骤输入不同的数据组合-调用接口-获取响应-检查响应。接口测试也算是黑盒测试,通过测试接口可以检查业务逻辑、检查数据库读写、覆盖代码分支、测试性能和安全。
通过调用接口,输入不同的数据组合,测试业务的逻辑实现、测试数据库读写、覆盖代码分支、性能及安全等。
1.重视服务端的测试 服务端提供的接口也是产品,需优先测试。 2.提高整体研发团队的效率和质量 1.)测试提早介入接口测试可防止测试资源闲置,提早发现问题; 2.)协助前后端联调; 3.)如果只有服务端做修改,直接测试接口,效率高; 4.)做接口实时监控 3.安全防范 隐藏域攻击、篡改关键参数其实都是想绕过前端,攻击接口 a.对于接口参数传递 格式、非空、长度 有没有基本的容错能力(或者说是参数限制) b.接口返回的字段中是否包含多余信息(比如用户id,token等敏感字段) c.用户密码、其他用户隐私信息传输时都需要进行加密后传输 d.登录状态 或者说对于cookie和session的使用也是测试重点 e.接口是否存在防刷限制 burpsuite工具 f.xss攻击/sql注入 4.性能测试 压力测试、稳定性测试(调用10次、错误5次) 5.测试难度小、运行稳定、覆盖率直观(功能测试的覆盖率不直观)
在三层金字塔结构中,接口自动化测试优势:开发简单、运行稳定(误报率低)、测试效率高(速度高、bug优先级高)、利于监控、脚本维护量小
依据:API文档 a.类似于黑盒功能测试,区别在于:通过参数组合覆盖代码逻辑 理论上来说,对于单个接口要覆盖到所有正常和异常分支 等价类划分、边界值划分、错误推算 b. 性能测试:压力测试、稳定性测试 c.接口安全测试: 加密规则、策略性限制、 xss攻击/sql注入
a.验证接口响应状态码 200 b.响应报文是否包含关键信息 比如userid=10 c.响应报文关键字段是否存在 d.响应报文关键字段值是否正确?调用其余接口查询、查询数据库
1.新项目、新功能:做完整的接口测试用例 2.已有功能:基本功能做到尽量覆盖
浏览器插件: poster、 postman 典型商业工具 : loadrunner、soapui 典型开源工具: jmeter、 RobotFramework、httprunner 开发辅助类库: httpclient(okhttp)、 requests
1.postman+newman+jenkins 2.jmeter+maven+jenkins 3.RobotFramework+jenkins或httprunner 4.利用httpclient或requests自研发工具
俺叫小枫,一个成天想着一夜暴富的测试员
(1140267353)一起成长一起加油的伙伴群!软件测试,与你同行! 群内可领取最新软件测试大厂面试资料和Python自动化、接口、框架搭建学习资料!
点赞关注不迷路!!!【三连ღ】,有问题也可私聊哟~(*╹▽╹*)