你工作中如果有类似的陌生协议(既可以是第一次接触的协议,也可以是企业私有协议),你是如何解决的呢?
那在面对一个陌生的新协议时,测试工程师的首要任务是什么呢?
在我看来,就是要测试接口的正确逻辑、错误逻辑是否满足最初的需求,因此,我们需要快速地掌握验证手段。
面对一个陌生协议的接口测试任务时,无论如何,第一次你还是需要先拿到并了解开发工程师写的客户端代码,因为这样,你就可以对调用方式、参数等接口相关的一些内容有初步印象。在读完相关代码后,你就算是和这些接口完成了首次“会面”,下面你就要想办法敲开接口的大门,让自己能访问被测接口。
如fiddler,能否查看协议信息。
Python 提供了 WebSocket 的协议库,因此我只要用它完成客户端的撰写,就可以进行接口测试了。这里,我写下了第一个 WebSocket 的调用代码
#引入websocket的create_connection类
from websocket import create_connection
# 建立和WebSocket接口的链接
ws = create_connection("ws://echo.websocket.org")
# 打印日子
print("发送 'Hello, World'...")
# 发送Hello,World
ws.send("Hello, World")
# 将WebSocket的返回值存储result变量
result = ws.recv()
# 打印返回的result
print("返回"+result)
# 关闭WebSocket链接
ws.close()
WebSocket 是一个长连接,因此需要人为的建立连接,然后再关闭链接,而 HTTP 却并不需要进行这一操作。
封装了 Common 类,你可以在它的构造函数中,添加一个 API 类型的参数,以便于知道自己要做的是什么协议的接口,其中 http 代表 HTTP 协议接口,ws 代表 WebSocket 协议接口。由于 WebSocket 是一个长连接,我们在 Common 类析构函数中添加了关闭 ws 链接的代码,以释放 WebSocket 长连接。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# python代码中引入requests库,引入后才可以在你的代码中使用对应的类以及成员函数
import requests
from websocket import create_connection
# 定义一个common的类,它的父类是object
class Common(object):
# common的构造函数
def __init__(self,url_root,api_type):
'''
:param api_type:接口类似当前支持http、ws,http就是HTTP协议,ws是WebSocket协议
:param url_root: 被测系统的根路由
'''
if api_type=='ws':
self.ws = create_connection(url_root)
elif api_type=='http':
self.ws='null'
self.url_root = url_root
# ws协议的消息发送
def send(self,params):
'''
:param params: websocket接口的参数
:return: 访问接口的返回值
'''
self.ws.send(params)
res = self.ws.recv()
return res
# common类的析构函数,清理没有用的资源
def __del__(self):
'''
:return:
'''
if self.ws!='null":
self.ws.close()
def get(self, uri, params=None):
'''
封装你自己的get请求,uri是访问路由,params是get请求的参数,如果没有默认为空
:param uri: 访问路由
:param params: 传递参数,string类型,默认为None
:return: 此次访问的response
'''
# 拼凑访问地址
if params is not None:
url = self.url_root + uri + params
else:
url = self.url_root + uri
# 通过get请求访问对应地址
res = requests.get(url)
# 返回request的Response结果,类型为requests的Response类型
return res
def post(self, uri, params=None):
'''
封装你自己的post方法,uri是访问路由,params是post请求需要传递的参数,如果没有参数这里为空
:param uri: 访问路由
:param params: 传递参数,string类型,默认为None
:return: 此次访问的response
'''
# 拼凑访问地址
url = self.url_root + uri
if params is not None:
# 如果有参数,那么通过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
def put(self,uri,params=None):
'''
封装你自己的put方法,uri是访问路由,params是put请求需要传递的参数,如果没有参数这里为空
:param uri: 访问路由
:param params: 传递参数,string类型,默认为None
:return: 此次访问的response
'''
url = self.url_root+uri
if params is not None:
# 如果有参数,那么通过put方式访问对应的url,并将参数赋值给requests.put默认参数data
# 返回request的Response结果,类型为requests的Response类型
res = requests.put(url, data=params)
else:
# 如果无参数,访问方式如下
# 返回request的Response结果,类型为requests的Response类型
res = requests.put(url)
return res
def delete(self,uri,params=None):
'''
封装你自己的delete方法,uri是访问路由,params是delete请求需要传递的参数,如果没有参数这里为空
:param uri: 访问路由
:param params: 传递参数,string类型,默认为None
:return: 此次访问的response
'''
url = self.url_root + uri
if params is not None:
# 如果有参数,那么通过put方式访问对应的url,并将参数赋值给requests.put默认参数data
# 返回request的Response结果,类型为requests的Response类型
res = requests.delete(url, data=params)
else:
# 如果无参数,访问方式如下
# 返回request的Response结果,类型为requests的Response类型
res = requests.put(url)
return res
from common import Common
# 建立和WebSocket接口的链接
con = Common('ws://echo.websocket.org','ws')
# 获取返回结果
result = con.send('Hello, World...')
#打印日志
print(result)
#释放WebSocket的长连接
del con
我的尝试的一般顺序:现成工具,工具现成插件,测试框架+项目组封装或采用的api库(如:junit +对应的协议开源库)。 个人觉得遇到这种情况,要会点编程,孰练测试框架胜算才大ʘᴗʘ 工作中有突然遭遇xmpp和mqtt协议性能测试的经历,最终jmeter+开源插件+厂商client jar包+demo+api手册搞定了任务。
年前刚好公司年会,然后开发了个聊天小程序,就给我测。当时完全不知道怎么搞,就去看这个协议。然后就想先抓包,结果抓不到,捣鼓了修改fiddler抓到了包,然后也是看抓到的数据好像跟平时不一样,然后各种搜索,平时使用的jmeter,就在jmeter中按往常的来试试,正常取样器不行,最后看到jmeter中有个websocket取样器,开心完成压测。
像微服务接口,一般都是使用特殊协议如dubbo、protobuf进行通信的,这种情况应该怎么做测试呢?只能用自己擅长的编程语言写一个客户端模拟调用来进行测试?这种还需要连接配置中心什么的。而且会不会存在有些协议是不跨语言的,比如仅限Java语言,不支持python。
websocket协议也是我遇到的第一个陌生协议,那个时候测试工期短,用的是java技术栈,就用了netty框架来封装,后面有时间了就进行回顾,发现还有有个websocket.jar开源包,后面又相继遇到了amqp、mqtt等非http协议!
针对一个陌生协议的第一次接口测试,你要保持自己敏锐的测试嗅觉,依据自己的技术基础,尽快解决问题。总地来说,你可以通过三步快速完成测试任务:
1、借力开发工程师。你首先该借力就是开发工程师,但你不要进入开发工程师给你的那种,从技术基础和理论开始学起,再逐步应用的学习脉络。你要一击致命,直接把他的客户端代码拿来,尽最大可能挪为己用,将其变成自己的接口测试代码。
2、站在自己的技术栈之上,完成技术积累。如果开发工程师的代码并不能拿来使用,那么你就需要站在自己的技术栈上寻求解决方法,这其中既包含了你已经熟悉的测试工具、测试平台,也包含了自己的测试框架和编码基础。
3、归入框架。无论你使用哪一种方法,在完成测试工作后,你还是要掌握对应的理论基础,同时想办法将这个一开始陌生的接口,通过自己熟悉的方式合并到你自己的框架中,不断扩充自己框架的测试能力,不断丰富你自己的测试手段。