使用Flask搭建基于unittest的简单用例挑选及执行平台
在用例组织上,unittest的Test Suite的拥有非常好的灵活性,然而Test Suite一般要提前编制好,添加和组织用例必须使用代码,不方便使用。
本文使用 Flask + unittest.TestSuite + pickle搭建一个简单的unittest用例挑选和执行平台。
思路:
添加Test Suite: 使用discover()发现所有测试用例 -> 挑选用例 并生成Test Suite对象 -> 使用pickle.dump()序列化成文件 保存
执行Test Suite: 使用os.listdir()得到Test Suite列表 -> 使用pickle.load()反序列化成TestSuite对象 -> 执行TestSuite并生成报告
需要安装 Flask, pip install flask
在你的测试框架或用例同级目录下建立dashboard目录,结构如下
- dashboard
- suites 序列化的Test Suite文件目录
- templates 页面模板
- app.py
- test
- case 用例目录
新建app.py作为我们的接口服务文件
这里我们只实现3个页面:
- 添加用例 suite_add
- 用例列表(可以选择suite执行)suite_list
- 报告页面 report
使用Flask写接口(页面)的大致套路
# 1. 导入包
from flask import Flask # Flask类,使用flask框架的基本类
from flask import request # 请求对象,用于获取请求参数
from flask import render_template # 用于渲染模板,并返回客户端一个html页面
from flask import redirect # 用于跳转到其他url
# 2. 实例化Flask类
app = Flask(__name__) # 使用当前模块实例化一个Flask对象,app是自定义的变量(后面使用要一致)
# 3. 编写接口(页面)并挂载访问地址,指定允许的请求方法
@app.route("/suite_add", methods=["GET", "POST"] # 接口(页面)地址为/suite_add, 支持GET和POST
def suite_add():
if request.method == 'POST': # POST方法用来处理添加
.....
return redirect("/") # 添加后跳转到 首页
return render_template("suite_add.html") # 如果是GET方法,渲染返回suite_add页面
# 4. 运行调试
if __name__ == '__main__':
app.run()
suite_add这个接口的实现逻辑为:
- 使用unittest的discover遍历并抽取所有用例返回给客户端(GET请求)
- 获取到客户端挑选的用例并生成unittest的TestSuite对象
- 根据客户端传的TestSuite名称,序列化成指定名称的文件并保存
代码如下:
from flask import Flask # Flask类,使用flask框架的基本类
from flask import request # 请求对象,用于获取请求参数
from flask import render_template # 用于渲染模板,并返回客户端一个html页面
from flask import redirect # 用于跳转到其他url
import os # 用于组装绝对路径
import unittest
import pickle # 序列化方法
# 一些要使用到的目录绝对路径
app_dir = os.path.dirname(os.path.abspath(__file__)) # dashborad目录
case_dir = os.path.join(os.path.dirname(app_dir), 'test', 'case') # 测试用例目录
suite_dir = os.path.join(app_dir, 'suites') # 测试套件目录
def collect(): # 收集用例并组成Test Suite
suite = unittest.TestSuite() # 新建Test Suite
def _collect(tests): # 由于unittest discover得到的TestSuite中包含了目录及子目录的路径,这里只把所有的用例抽取出来
if isinstance(tests, unittest.TestSuite):
if tests.countTestCases() != 0:
for i in tests:
_collect(i)
else:
suite.addTest(tests)
_collect(unittest.defaultTestLoader.discover(case_dir))
return suite
app = Flask(__name__) # 使用当前模块实例化一个Flask对象,app是自定义的变量(后面使用要一致)
@app.route("/suite_add", methods=["GET", "POST"] # 接口(页面)地址为/suite_add, 支持GET和POST
def suite_add():
tests = [] # 用例集合
for case in collect():
tests.append(case.id()) # 遍历testsuite中的用例,通过case.id()拿到用例名
if request.method == 'POST': # POST方法用来处理添加
suite_name = request.form.get("suite_name") # 从前端获取需要新建的testsuite名称
cases = request.form.getlist("cases") # 获取到前端选择的用例列表
suite = unittest.defaultTestLoader.loadTestsFromNames(cases) # 通过用例名列表生成TestSuite
with open(os.path.join(suite_dir, suite_name+".testsuite"), 'wb') as f: # 序列化并保存TestSuite
pickle.dump(suite, f)
return redirect("/") # 添加后跳转到 首页
return render_template("suite_add.html") # 如果是GET方法,渲染返回suite_add页面
if __name__ == '__main__': # 运行接口方法
app.run()
templates/suite_add.html代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>新增Test Suite</title>
</head>
<body>
<h1>新增Test Suite</h1>
<form action="#" method="post">
标题:<input type="text" name="suite_name">
<h4>选择用例</h4>
{% for test in tests%}
<div><input type="checkbox" id="cases" name="cases" value="{{test}}">{{test}}</div>
{% endfor %}
<div><input type="submit" value="保存"></div>
</form>
</body>
</html>
执行后访问 http://127.0.0.1:5000/suite_add

标题输入suite1,选择用例,点击添加会在dashboard/suites下生成suite1.testsuite文件

由于添加后跳转到"/",这个接口(页面)还没实现,所以会报错,我们现在来实现suite列表, 思路:
- 使用os.listdir()遍历suites目录下的.testsuite文件并渲染到页面上
在app.py中添加
from HTMLTestReportCN import HTMLTestRunner # 这个是生成html报告的文件,放在app.py同级即可
@app.route("/", methods=['GET', 'POST'])
def suite_list():
suite_list = [suite.split(".")[0] for suite in os.listdir('suites') if suite.endswith(".testsuite")] # 遍历并去掉.testsuite扩展名
if request.method == 'POST': # 执行testsuite方法
suite_name = request.form.get("suite")
import sys;sys.path.append(case_dir) # 反序列化必须将 用例目录添加到sys.path中
with open(os.path.join(suite_dir, suite_name+".testsuite"), 'rb') as f: # 反序列化并得到TestSuite对象
suite = pickle.load(f)
with open(report_file, 'wb') as f: # 执行TestSuite并在templates目录中生成html文件
result = HTMLTestRunner(stream=f, title="Api Test", description="测试描述", tester="卡卡").run(suite)
return redirect("/report") # 显示报告
return render_template('suite_list.html', suite_list=suite_list) # GET方法返回suite列表页面
suite_list页面代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Test Suite列表</h1>
<a href="/suite_add">添加Test Suite</a>
<br>
<form action="#" method="post">
{% for suite in suite_list %}
<input type="radio" name="suite" value="{{suite}}">{{ suite }}
<br>
{% endfor %}
<input type="submit" value="执行">
</form>
</body>
</html>

显示报告方法(报告必须生成在templates目录下)
@app.route("/report", methods=['GET'])
def report():
return render_template('report.html')
执行某个testsuite后会跳转到报告页面

完整代码:api_test_framework
更多学习资料请加添加作者微信:lockingfree获取
使用Flask搭建基于unittest的简单用例挑选及执行平台的更多相关文章
- 基于Spring-SpringMVC-Mybatis的简单样例
复习下 好久没搞过撸过代码了! 这个样例包括一个完整的增删改查! 源代码地址http://download.csdn.net/detail/wangdianyong/8909903
- 树莓派搭建基于flask的web服务器-通过移动端控制LED
1.概述 在局域网内,基于flask搭建web服务,从而可以使用移动客户端访问该web服务.由于是flask新手,所以本次实现的web服务功能较为简单,即控制LED灯的开/关及闪烁. 2.准备工作 2 ...
- 从零开始用 Flask 搭建一个网站(一)
前言 笔者之前未接触过 Python,只是略懂一点前端,所以说从零开始也相差无几吧.Flask 是一个轻量级的基于 Python 的框架,但是扩展性非常良好(Github 上 22000 多个 sta ...
- 用pymysql和Flask搭建后端,响应前端POST和GET请求
前言 这次作业不仅需要我建立一个数据库(详情请点击这里),还需要我基于这个数据库写后端接口(注册和登录)供前端访问,接收前端的POST和GET请求,并将登录.注册是否成功传给前端. 本文介绍如何用Fl ...
- 面向服务体系架构(SOA)和数据仓库(DW)的思考基于 IBM 产品体系搭建基于 SOA 和 DW 的企业基础架构平台
面向服务体系架构(SOA)和数据仓库(DW)的思考 基于 IBM 产品体系搭建基于 SOA 和 DW 的企业基础架构平台 当前业界对面向服务体系架构(SOA)和数据仓库(Data Warehouse, ...
- 象写程序一样写博客:搭建基于github的博客
象写程序一样写博客:搭建基于github的博客 前言 github 真是无所不能.其 Pages 功能 支持上传 html,并且在页面中显示.于是有好事者做了一个基于 github 的博客管理工具 ...
- Windows 7下 搭建 基于 ssh 的sftp 服务器
Windows xp 下 搭建 基于 ssh 的sftp 服务器,服务器端可以用 freesshd,F-secure server等,filezilla server不可用,之前傻乎乎的用file ...
- 从零开始用 Flask 搭建一个网站(三)
从零开始用 Flask 搭建一个网站(二) 介绍了有关于数据库的运用,接下来我们在完善一下数据在前端以及前端到后端之间的交互.本节涉及到前端,因此也会讲解一下 jinja2 模板.jQuery.aja ...
- .net项目架构改造之搭建基于java环境配置一览【上】
最近公司做了一个项目,需要嵌套在千牛的客户端上,项目代码必须上阿里的聚石塔,全程采用基于docker的自动化部署,我们的项目是基于.net架构.很遗憾 的是基于windows的docker上部署在访问 ...
随机推荐
- vim 插件 入门
vim 手册 vimtutor 精简版本 help user-manual 详细手册 一些vim自带设置 set nu "显示行号 set cursorline "高亮显示当前行 ...
- 以太坊再爆高危漏洞!黑客增发ATN 1100万枚token事件始末
事情发生在5月中旬,ATN技术人员发现Token合约由于存在漏洞受到攻击.不过ATN基金会随后透露,将销毁1100万个ATN,并恢复ATN总量,同时将在主链上线映射时对黑客地址内的资产予以剔除,确保原 ...
- MySQL SQL Training
源于知乎:50道SQL练习题 一.表数据 1.学生表——Student ),Sname ),Sage )); ' , '赵雷' , '1990-01-01' , '男'); ' , '钱电' , '1 ...
- Angular7如何动态刷新Echarts图表
1 概述 echarts是百度的开源图表插件 Angular中引入echarts网上教程很多 Angular引入echarts,并使用动态刷新 2 安装 请参考大神的博客:https://blog.c ...
- php对象转换为数组的部分代码
function object_array($array){ if(is_object($array)){ $array = (array)$array; } if(is_array($array)) ...
- linux pthread多线程编程模板
pthread_create() 创建线程,pthread_join()让线程一直运行下去. 链接时要加上-lpthread选项. pthread_create中, 第三个参数为线程函数,定义如下: ...
- Oracle---PL/SQL的学习
PL/SQL程序 一.定义 declare 说明部分 begin 语句序列(DML语句) exception 例外处理语句 end; 二. 变量和常量说明 a) 说明变量(char,varchar2, ...
- IEAD工具教你创建maven项目
之前一直用的是其他的开发工具,maven到目前为止也就用了3个月,今天又时间整理一些初期的使用方法,仅供参照. 为什么要用maven 原因很简单,因为使用maven,会使得项目非常容易管理. 举个例子 ...
- 【Day2】4.第三方模块的安装与使用
课程目标 1. 使用模块 2. 安装第三方模块 使用模块 • 一个.Py文件称之为一个模块(Module) • 好处: 1. 便于代码维护,把很多函数放到不同文件,一个.py文件 的 代码数量少 2. ...
- Linux rpm和yum软件管理
rpm是管理程序的一个小工具,rpm常来用作查询 什么源码包:大多数都是tar.gz,bz.bz2结尾的包 zip结尾的包 压缩格式为 zip –r 命名.zip ./* 解压格式为 unzip 命名 ...