Flask测试小工具平台

Posted zongsuan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flask测试小工具平台相关的知识,希望对你有一定的参考价值。

1.首先安装flask    pip install flask,或者在setting里边去搜flask去安装

2.写一个简单的接口,输出hello

接口是一个函数,接口要绑定一个接口地址,以确定那个接口去走这个函数,绑定到路由也就是接口地址

from flask import Flask

app = Flask(\'tools\')

@app.route(\'/\')
def home():
return \'hello\'

if __name__==\'__main__\':
app.run()

运行结果就是在网页上输出一个hello

3.接口也可以返回网页

 

from flask import Flask

app = Flask(\'tools\')

@app.route(\'/\')
def home():
return """<html> ---return里可以写一个网页,返回
<head><title>第一个网页啊</title></head>
<body>
<h1>你好</h1>
<h2>Lily</h2>
<h3>哈哈</h3>
</body>
</html>
"""
if __name__==\'__main__\':
app.run()

4.接口也可以返回一个json格式,需要引入jsonify,通过jsonify来传一个josn对
from flask import Flask,jsonify

app = Flask(\'tools\')

@app.route(\'/\')
def home():
return jsonify(\'name\':\'Kiven\',\'age\':16)
if __name__==\'__main__\':
app.run()

返回结果是json格式对
--------------------------------------------------------------------------------------------------------
但是这样在一个文件里写很麻烦,可以单独写一个html模板,返回一个html文件
在根目录下新建一个模板文件夹templates,存放html模板
写出来一个静态模板home.html,要传给接口,怎么传呢。需要导入render_template,导入以后可以通过
render_template把网页传给接口
from flask import Flask,jsonify,render_template

app = Flask(\'tools\')

@app.route(\'/\')
def home():
return render_template(\'./home.html\') ---把网页传给接口
if __name__==\'__main__\':
app.run()
也可以在网页设置一个变量,通过render_template渲染网页的时候,传值给设置的变量

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>小工具主页</title>
</head>
<body>
<div id="content">
<h2>你好,user</h2> --user就是设置的变量,通过render_template传值给这个变量
<h3>测试小工具</h3>
<url>
<li>Xmind转excel</li>
<li>HAR转接口代码</li>
<li>MD5加密</li>
</url>

<h3>运维小工具</h3>
<url>
<li>Xmind转excel</li>
<li>HAR转接口代码</li>
<li>MD5加密</li>
</url>
</div>
</body>
</html>


from flask import Flask,jsonify,render_template

app = Flask(\'tools\')

@app.route(\'/\')
def home():
return render_template(\'./home.html\',user=\'Keivn\') ----这里的user赋值,传给网页里设置的变量
if __name__==\'__main__\':
app.run()

-------------------------======================----------------------------------------------==============================----------------------------------
一些动态数据,可以从后端传到前端,前端埋一个变量,进行遍历,加for循环
from flask import Flask,jsonify,render_template

app = Flask(\'tools\')

@app.route(\'/\')
def home():
#date就是动态数据,可以随时改变
date =[
\'name\':\'Xmind转excel\',\'url\':\'\',
\'name\':\'HAR转接口代码\',\'url\':\'\',
\'name\':\'md5加密\',\'url\':\'\'
]
return render_template(\'./home.html\',user=\'Keivn\',tools=date) ----tools就是html里边的变量名称,把date传给tools
if __name__==\'__main__\':
app.run()


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>小工具主页</title>
</head>
<body>
<div id="content">
<h2>你好,user</h2>
<h3>测试小工具</h3>
<url>
% for tool in tools% --------tools是变量,for循环,遍历整个tools
<li>tool.name</li> --------取每个变量的name
% endfor %
</url>

<h3>运维小工具</h3>
<url>
<li>Xmind转excel</li>
<li>HAR转接口代码</li>
<li>MD5加密</li>
</url>
</div>
</body>
</html>
---------------------------------------------------------------------------------------------
还可以在小工具里加链接,可以点击跳转,单独一个小工具新建一个页面xmind2excel.html
跳转到小工具页面,需要加链接,需要新增一个接口,即一个新的函数
from flask import Flask,jsonify,render_template

app = Flask(\'tools\')

@app.route(\'/\')
def home():
date =[
\'name\':\'Xmind转excel\',\'url\':\'/xmind2excel\',
\'name\':\'HAR转接口代码\',\'url\':\'\',
\'name\':\'md5加密\',\'url\':\'\'
]
return render_template(\'./home.html\',user=\'Keivn\',tools=date)

@app.route(\'/xmind2excel\') #括号里的是接口地址 --新加的接口
def xmind2excel():
return render_template(\'./xmind2excel.html\')

新写的页面,点击主页上的文字的链接,跳转到这个页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>XMind转Excel</title>
</head>
<body>
<h2>XMind转Excel</h2>
</body>
</html>

在新页面加一些功能
加一个做加法的功能


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>XMind转Excel</title>
</head>
<body>
<h2>XMind转Excel</h2>
<form> #表单两个关键点:1 传给哪个接口 2 每个输入框要提供一个变量名
<div><span>变量a </span><input type="text"></div>
<div><span>变量b </span><input type="text"></div>
<button type="submit">确定</button>
</form>


</body>
</html>
在主页写一个接口 新引入一个request
from flask import Flask,jsonify,render_template,request

app = Flask(\'tools\')

@app.route(\'/\')
def home():
date =[
\'name\':\'Xmind转excel\',\'url\':\'/xmind2excel\',
\'name\':\'HAR转接口代码\',\'url\':\'\',
\'name\':\'md5加密\',\'url\':\'\'
]
return render_template(\'./home.html\',user=\'Keivn\',tools=date)

@app.route(\'/xmind2excel\') #括号里的是接口地址
def xmind2excel():
return render_template(\'./xmind2excel.html\')

@app.route(\'/add\',methods=[\'POST\']) --新写的加法接口,加了限制那种请求方式,可以是一个可以是多个
def add():
a = request.form.get(\'a\')
b = request.form.get(\'b\')
c = int(a) + int(b) --html里拿到的变量值都是字符串,需要转换成整形的才能进行加法计算
return str(c) --做完加法计算c是整形的,需要转换成字符串形式才能传

if __name__==\'__main__\':
app.run()
新写的页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>XMind转Excel</title>
</head>
<body>
<h2>XMind转Excel</h2>
#表单两个关键点:1 传给哪个接口 2 每个输入框要提供一个变量名
<form action="/add" method="post"> #通过post方式传给add这个接口
<div><span>变量a </span><input name="a" type="text"></div> #变量名是a 输入的值以变量a传给接口
<div><span>变量b </span><input name="b" type="text"></div> #变量名是b
<button type="submit">确定</button>
</form>


</body>
</html>
 




































 

接口测试的另一种方式 – 接口测试平台

接口测试的另一种方式 – 接口测试平台

文章目录[显示]

搭建的初衷

现状

目前,基于我们组所需要测试的点,很大一部分都是跟接口相关的,不管是我们系统内部的接口还是第三方(外部系统)的接口。部分接口还涉及到对传输数据的加密解密处理,那么,在日常的测试工作中,难免需要开发为我们提供加解密的工具或者我们自己编写小工具进行测试。随着接口数量的增多,我们为每一个项目开发的小工具也越来越多,每个小工具的使用方法也不太相同,隐性的增加了一些维护成本和使用成本。其实很多方法都是可以复用的,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

安装需要的模块

  1. pip install tornado sqlalchemy apscheduler pymysql pycrypto

如果在安装模块的过程中还缺少其他模块,请自行根据提示进行安装。
另外还使用了前端框架Bootstrap

tornado: web开发框架
sqlalchemy: Python对象关系映射器及强大的数据库工具,官网
apscheduler: 定时任务框架
pymysql: 纯Python实现的Mysql客户端,Mysqldb的替代品
pycrypto: Python加密工具包

代码部署

将源码上传到服务器的任意位置、基于规范,建议上传到存放web应用的统一目录中。

Nginx配置

  1. upstream tornadoes {
  2. server 127.0.0.1:19090;
  3. server 127.0.0.1:19091;
  4. server 127.0.0.1:19092;
  5. server 127.0.0.1:19093;
  6. server 127.0.0.1:19094;
  7. server 127.0.0.1:19095;
  8. server 127.0.0.1:19096;
  9. server 127.0.0.1:19097;
  10. server 127.0.0.1:19098;
  11. server 127.0.0.1:19099;
  12. }
  13. server {
  14. listen 9999;
  15. server_name 172.20.20.86;
  16. access_log off;
  17. index index.html index.htm index.py;
  18. root /opt/APITest_platform;
  19. location / {
  20. proxy_pass http://tornadoes;
  21. include public_config/proxy.conf;
  22. }
  23. location /static/ {
  24. root /opt/APITest_platform/static;
  25. if ($query_string) {
  26. expires max;
  27. }
  28. }
  29. location ~ .*\.(gif|jpg|[email protected]!medium|bmp|swf|flv|ico|eot|ttf|svg|woff|woff2)$ {
  30. expires 30d;
  31. access_log off;
  32. }
  33. location ~ .*\.(js|css)?$ {
  34. expires 7d;
  35. access_log off;
  36. }
  37. }

启停脚本

  1. #!/bin/bash
  2. # tornado服务启停脚本
  3. function startservice(){
  4. for i in 19090 19091 19092 19093 19094 19095 19096 19097 19098 19099
  5. do
  6. if [ $i -eq 19090 ];then
  7. 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 &
  8. else
  9. nohup python3 /opt/APITest_platform/app.py --port=$i --log_file_prefix=/opt/APITest_platform/log/apitest-$i.log > /dev/null 2> &1 &
  10. fi
  11. echo"started port $i‘s service"
  12. done
  13. }
  14. function stopservice(){
  15. for i in 19090 19091 19092 19093 19094 19095 19096 19097 19098 19099
  16. do
  17. kill -9`ps aux | grep "port=$i" | grep -v "grep" | awk ‘NR==1 {printf $2}‘`
  18. echo"stoped port $i‘s service"
  19. done
  20. }
  21. if [ "$1" = "start" ];then
  22. startservice
  23. elif [ "$1" = "stop" ];then
  24. stopservice
  25. elif [ "$1" = "restart" ];then
  26. stopservice
  27. startservice
  28. else
  29. echo"Please input like this:\"$0 start [stop | restart]\""
  30. fi

启动命令说明

app.py是系统入口文件,启动参数有三个
–port=9999 启动端口
–monitor=on 启动时同时启动定时任务监控
–log_file_prefix=log_file_path 系统日志输出到指定文件
如:

  1. $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字段填充配置的值

加解密配置

新增配置

技术分享

  1. 加解密算法配置必须选择一个项目进行关联
  2. 加密算法和解密算法是成对配置的
  3. 目前已经配置了三类加密算法,分别是AES、DES、DES3。
  4. 三类加密算法分别有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



































































































以上是关于Flask测试小工具平台的主要内容,如果未能解决你的问题,请参考以下文章

python自动化自动化测试平台开发:3.flask技术讲解上

python自动化自动化测试平台开发:2.flask技术讲解上

不需要web服务器,如何构建一个可以内部跨域的http服务(Vue+Flask)

接口测试的另一种方式 – 接口测试平台

接口测试的另一种方式 – 接口测试平台

Web前端性能测试平台开发(Flask)