搭建的初衷
现状
目前,基于我们组所需要测试的点,很大一部分都是跟接口相关的,不管是我们系统内部的接口还是第三方(外部系统)的接口。部分接口还涉及到对传输数据的加密解密处理,那么,在日常的测试工作中,难免需要开发为我们提供加解密的工具或者我们自己编写小工具进行测试。随着接口数量的增多,我们为每一个项目开发的小工具也越来越多,每个小工具的使用方法也不太相同,隐性的增加了一些维护成本和使用成本。其实很多方法都是可以复用的,WEB接口测试的方法也都大致相同,那我们是否可以考虑整合一下,做一个统一的测试平台呢?
常规接口测试工具
WEB接口测试的方法,通常都是模拟客户端向服务器发送请求,服务器处理后返回请求结果,然后在检查返回的结果是否符合预期,检查返回的数据格式、字段以及异常请求时服务器是否返回异常等等,尤其涉及第三方接口时,需要考虑接口的安全性,是否可以随意获取等等。
那常规的接口我们可以使用像Loadrunner、Jmeter、Postman、Fiddler这类性能测试工具或抓包工具来模拟请求,当然熟悉Python或其他开发语言的话,也可以使用类似httpclient、httplib之类的库自行编写脚本模拟客户的请求。
需要解决的痛点
基于我们所测试的接口特点、不涉及加密加签的接口都可以使用已有的测试工具来模拟客户端请求来测试、那么涉及到加密加签的接口我们就需要自行编写小工具来进行测试了。
不能使用现成的工具是因为基于我们所测试的接口特点不能满足我们的测试需求:
1. 数据的加密解密算法不同
2. 数据的加签验签算法不同
3. 签名的位置,一些要求放在Headers中传输,一些要求当做Body参数传输
4. 接口请求有时效限制
如果用现成的工具来测试,我们需要单独生成这些数据后再拼成完整的请求数据,过程会异常麻烦。所以我们需要为不同的项目编写测试小工具来测试,为了我们编写的小工具更具备通用性,降低使用和维护成本,让没有编码基础的测试人员也能轻松完成这类接口的测试工作,方便回归测试,就有了搭建这么一个接口测试平台的想法。
平台框架图
平台预览
登录、注册
个人信息管理
设置
单接口测试
多接口测试配置
任务管理
测试报告
扩展功能
部署说明(Linux)
环境准备
测试平台是基于Python 3.5开发的,所以需要Python 3以上版本,推荐安装Python 3.5
使用了tornado web开发框架,了解tornado。
安装需要的模块
- pip install tornado sqlalchemy apscheduler pymysql pycrypto
如果在安装模块的过程中还缺少其他模块,请自行根据提示进行安装。
另外还使用了前端框架Bootstrap
tornado: web开发框架
sqlalchemy: Python对象关系映射器及强大的数据库工具,官网
apscheduler: 定时任务框架
pymysql: 纯Python实现的Mysql客户端,Mysqldb的替代品
pycrypto: Python加密工具包
代码部署
将源码上传到服务器的任意位置、基于规范,建议上传到存放web应用的统一目录中。
Nginx配置
- upstream tornadoes {
- server 127.0.0.1:19090;
- server 127.0.0.1:19091;
- server 127.0.0.1:19092;
- server 127.0.0.1:19093;
- server 127.0.0.1:19094;
- server 127.0.0.1:19095;
- server 127.0.0.1:19096;
- server 127.0.0.1:19097;
- server 127.0.0.1:19098;
- server 127.0.0.1:19099;
- }
- server {
- listen 9999;
- server_name 172.20.20.86;
- access_log off;
- index index.html index.htm index.py;
- root /opt/APITest_platform;
- location / {
- proxy_pass http://tornadoes;
- include public_config/proxy.conf;
- }
- location /static/ {
- root /opt/APITest_platform/static;
- if ($query_string) {
- expires max;
- }
- }
- location ~ .*\.(gif|jpg|[email protected]!medium|bmp|swf|flv|ico|eot|ttf|svg|woff|woff2)$ {
- expires 30d;
- access_log off;
- }
- location ~ .*\.(js|css)?$ {
- expires 7d;
- access_log off;
- }
- }
启停脚本
- #!/bin/bash
- # tornado服务启停脚本
- function startservice(){
- for i in 19090 19091 19092 19093 19094 19095 19096 19097 19098 19099
- do
- if [ $i -eq 19090 ];then
- nohup python3 /opt/APITest_platform/app.py --port=$i --monitor=on --log_file_prefix=/opt/APITest_platform/log/apitest-$i.log > /dev/null 2> &1 &
- else
- nohup python3 /opt/APITest_platform/app.py --port=$i --log_file_prefix=/opt/APITest_platform/log/apitest-$i.log > /dev/null 2> &1 &
- fi
- echo"started port $i‘s service"
- done
- }
- function stopservice(){
- for i in 19090 19091 19092 19093 19094 19095 19096 19097 19098 19099
- do
- kill -9`ps aux | grep "port=$i" | grep -v "grep" | awk ‘NR==1 {printf $2}‘`
- echo"stoped port $i‘s service"
- done
- }
- if [ "$1" = "start" ];then
- startservice
- elif [ "$1" = "stop" ];then
- stopservice
- elif [ "$1" = "restart" ];then
- stopservice
- startservice
- else
- echo"Please input like this:\"$0 start [stop | restart]\""
- fi
启动命令说明
app.py是系统入口文件,启动参数有三个
–port=9999 启动端口
–monitor=on 启动时同时启动定时任务监控
–log_file_prefix=log_file_path 系统日志输出到指定文件
如:
- $python app.py --port=9999 --monitor=off
使用说明
注册、登录
建议使用公司邮箱注册,密码在数据库中已加密存储。
使用注册的邮箱登录
个人信息管理
修改用户名后,可以使用邮箱或用户名登录
设置
项目管理
新增项目
禁用项目
禁用项目后,在所有跟项目相关联的配置中,该项目不可选
删除项目
在删除项目之前,需要删除跟该项目所有相关联的配置
成员管理
配置可访问该项目的普通用户,管理员可见所有的项目,测试报告的邮件发送将基于项目成员用户发送。
配置自定义参数
项目参数配置,主要配置项目中有特殊需求的情况,比如需要加签、需要添加、验证特殊字段、从数据库获取特定值等情况
配置自定义方法
在配置自定义参数时,Function类型的参数,需要根据项目需求配置自定义方法,具体步骤如下:
1. 进入源码中的encryption目录
2. 打开customfunc.py文件
3. 在customfunc.py文件末尾添加新增的方法
自定义方法必须有三个固定的参数,body、params和encrypt
body:请求Body,以字典格式传入,如果转成字典失败会原样传入,使用前最好进行类型判断。
params:已配置的项目自定义参数,以元素为字典的列表格式传入。
encrypt:项目相关的加密配置信息,以字典格式传入,没有传入值为None。
4. 打开config.py文件
5. 找到自定义方法配置所在位置,新增一行配置
自定义方法配置是元素为字典的列表
新增一个列表元素,格式为:{‘name’: ‘sign_test’, ‘function’: sign_test, ‘comment’: ”}
name:选择时显示的方法名
function:该方法的处理函数名,即在customfunc.py文件中新增的方法名(不带括号引用)
comment:备注,在配置中选择自定义方法时,会给出提示方便识别。
6. 重启服务
Host配置
Host配置用于通过切换域名指向不同的ip地址来达到测试不同测试环境的目的。
新增HOST
选择应用于所有项目,添加时将为所有项目配置Host
选择单个项目,添加时只为该项目配置Host
删除HOST
删除host配置后,将使用系统所部署服务器的host配置,如果没有则使用DNS解析结果。
禁用 / 启用HOST
禁用host配置后,将使用系统所部署服务器的host配置,如果没有则使用DNS解析结果。
按钮为红色,显示为禁用时,该配置是已生效状态
接口配置
新增接口
删除接口
接口完整性检查配置
接口完整性检查配置,用于检查接口返回值参数是否符合需求,比如字段是否完整,字段值是否为空等等
1. 只能检查返回值是json格式的接口
2. 目前只检查了字段是否完整和字段值是否为空,后续增加对字段类型的检查
** 配置格式说明: **
检查第一层Key值,一行配置一个,需要检查子层时,在第一层的基础上用 .[] 连接子层需要检查的Key值,如果某个字段的值为列表,用.N取列表值,key=0[非必填] | key=1[必填],如:
id=1
code.[code=1,id=1,msg=0]
rows.[0].[code=1,id=1,msg=0]
result.rows.[code=1,id=1,msg=0]
接口默认请求HEADERS配置
在配置接口测试参数时,选择该接口将默认为headers字段填充配置的值
接口默认请求BODY配置
在配置接口测试参数时,选择该接口将默认为body字段填充配置的值
加解密配置
新增配置
- 加解密算法配置必须选择一个项目进行关联
- 加密算法和解密算法是成对配置的
- 目前已经配置了三类加密算法,分别是AES、DES、DES3。
- 三类加密算法分别有ECB和CBC模式,经过base64、urlencode编码之后,组合了14中方法,如果没有所需的,可以另外配置
删除配置
新增加解密处理方法
新增加解密方法的步骤跟新增自定义方法的过程类似
1. 进入encryption目录
2. 如果需要添加的加解密方法不在系统预设的AES、DES、DES3三大类中,可以在encryption目录中新建一个加密类文件
3. 打开function.py文件,参考该文件中的方法在文件末尾新增处理方法。
方法必须包含四个传入参数:
string:待加密或解密的字符串
key:加密或解密KEY
iv:加密或解密IV
mode:加密或解密模式
返回处理后的结果
4. 打开config.py文件,配置加解密方法
找到加解密配置所在位置
加解密配置是元素为字典的列表
新增一个列表元素,格式为:{‘name’: ‘DES3(CBC)_TO_base64_URLEncode’, ‘function’: des3_encode_to_b64_url_encode, ‘mode’: ‘CBC’, ‘comment’: ‘DES3加密并进行base64编码后再URLEncode, CBC模式’}
name:选择时显示的方法名
function:该加解密方法的处理函数名,即在function.py文件中新增的方法名
mode:加密或解密模式
comment:备注,在配置中选择加解密方法时,会给出提示方便识别。
加密和解密的配置格式相同,可参考已有的配置
5. 保存配置后重启服务
单接口测试
Headers配置格式为 key: value 形式,也可以是字典格式{“key”: “value”},字典格式必须在一行,不能换行。
Body配置的格式可以为任何形式,取决于Headers中Content-Type的类型,如果Content-Type类型是application/json,Body必须是json格式字符串,如果Content-Type类型是application/x-www-form-urlencoded,Body可以是字典格式的字符串,或者以Key=value的形式配置,一组参数独占一行,当然,可以直接以URLEncode后的形式配置,比如:key1=value1&key2=value2&key3=value3
Body加密配置,能够加密的前提是Headers中Content-Type的类型为application/json或application/x-www-form-urlencoded。目前只能加密第一层数据,如果不指定加密的字段,将加密所有内容。
解密字段配置,接口返回数据必须是json格式字符串,只能解密第一层数据。
重定向跟随选项,如果接口返回301或者302,勾选将自动跟随请求重定向后的链接,不勾选将直接返回响应结果。
仅生成请求数据选项,勾选将只生成请求Body数据,不发起接口请求,需要手工测试时可辅助生成请求数据。
批量接口测试配置
新增测试接口
检查点配置,配置此项将搜索接口返回值中是否包含配置的关键词。
关联配置,配置此项用于获取接口返回值中的特定值,要求接口返回值必须是json格式字符串,配置格式跟接口完整性检查的配置类似,例如:
{page_id}=data.page_id 表示取返回值中key为data下的字典key为page_id的值
{page_id}=data.[1].page_id 表示取返回值中key为data,data的值是一个元素为字典的列表,取列表中第二个元素,字典key为page_id的值。
有两个系统关联参数
{cookie}=response_cookie 获取cookie值
{response_body}=response_body 获取完整响应body值
关联参数支持int和float类型转换
{id}=int(data.id) 表示将获取到的值转换为int类型
{total}=float(data.[0].total) 表示将获取到的值转换为float类型
备注,是对该接口测试的一些描述说明。
选择测试接口
配置完测试接口后,可以随意组合接口进行测试,勾选要测试的接口,测试时会按接口的排序先后进行测试,如果需要调整接口顺序,可点击【操作】列中的【上移】按钮进行调整。
立即执行任务
勾选完需要测试的接口后,点击【立即执行】按钮,将立即执行测试任务。在执行前,可给任务取一个任务名称。
预约执行任务
勾选完需要测试的接口后,配置好定时时间,执行周期,点击【预约执行】按钮,将会保存此任务,到预约的时间点后自动执行。在执行前,可给任务取一个任务名称。
扩展功能
加密调试
解密调试
附
系统预定义参数
{random_mobile} 随机手机号
{random_email} 随机email
{timestamp} 时间戳
{datetime} 当前时间, 格式: %Y-%m-%d %H:%M:%S
{datetime_int} 当前时间, 格式: %Y%m%d%H%M%S
{date} 当前日期, 格式: %Y-%m-%d
{date_int} 当前日期, 格式: %Y%m%d
系统关联参数
{cookie}=response_cookie 获取cookie
{response_body}=response_body 获取完整响应body