使用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上部署在访问 ...
随机推荐
- spark调优篇-数据倾斜(汇总)
数据倾斜 为什么会数据倾斜 spark 中的数据倾斜并不是说原始数据存在倾斜,原始数据都是一个一个的 block,大小都一样,不存在数据倾斜: 而是指 shuffle 过程中产生的数据倾斜,由于不同的 ...
- .js文件中文乱码解决办法
描述:.js文件里的中文内容在网页中显示乱码 解决办法:把JS文件的编码改为utf-8 VS2013解决步骤:文件——高级保存选项——Unicode (UTF-8带签名) 代码页 65001
- SQLServer · 最佳实践 · 如何将SQL Server 2012降级到2008 R2-博客-云栖社区-阿里云
迁移须知 使用SQLSERVER 2012的特性在SQL 2008 R2不支持,比如新的分页方式 此迁移操作手册适用于MSSQL2012到MSSQL2008R2的迁移 迁移使用微软提供的脚本生成和导入 ...
- 远程连接windows2003桌面无法使用剪切板的有效解决方法
远程桌面控制服务器时,无法剪切.粘贴一些东西,上网搜了一下,原来是rdpclip.exe(remote desktop clipboard)不起作用了.此程序负责管理本地机与远程服务器之间共享剪切板, ...
- luogu2261余数求和题解--整除分块
题目链接 https://www.luogu.org/problemnew/show/P2261 分析 显然\(k\) \(mod\) \(i=k-\lfloor {k/i}\rfloor\) \(\ ...
- sql server 查看表中某一字段的排序规则
SELECT o.name,o.object_id,c.name,c.column_id,c.collation_name FROM sys.columns c JOIN sys.obj ...
- 如何部署struts开发环境
1 首先登陆http://archive.apache.org/dist/struts/source/页面,会看到struts的下载页面 2 下载struts的最新版本struts2-2.2.1-sr ...
- asp.net ListView控件的简单实用和配置
1 web窗体界面代码 ItemType:控件要绑定的实体模型 SelectMethod:控件获取实体集合的后台方法 DataKeyNames:实体的主键 UpdateProduct:设置跟新的方法 ...
- Java和操作系统交互(Java 代码是怎么执行)(转)
结合 CPU 理解一行 Java 代码是怎么执行的 根据冯·诺依曼思想,计算机采用二进制作为数制基础,必须包含:运算器.控制器.存储设备,以及输入输出设备,如下图所示. 我们先来分析 CPU 的工作原 ...
- 获取impala下所有的数据库建表语句
方法一: 现在的导出还是有缺陷的,导出的文件中还是存在其他不必要的信息 #!/bin/bash ##获取数据库 databases=$(hive -e "show databases; ex ...