unittest框架扩展(自动生成用例)自动化-上
一.思想:
基于数据驱动和代码驱动结合的自动化测试框架。
二.自动化测试框架步骤:
1.获取用例,用例格式:.ymal
2.调用接口
3.校验结果
4.发送测试报告
5.异常处理
6.日志模块
三.基于上一篇文章中,使用unittest模块框架,编写自动化调用接口测试,拷贝生成用例的python文件作为模板,在conf下新建base.txt,只需每次修改文件中类名:和文件名:
生成同样的python文件作为用例即可。
base.txt如下:
import unittest,requests
import ddt
from BeautifulReport import BeautifulReport as bf
from BeautifulReport import BeautifulReport as bf
from urllib import parse
from conf.setting import BASE_URL
@ddt.ddt
class %s(unittest.TestCase): #是百分号s指变量class_name
base_url = BASE_URL
@ddt.file_data(r'%s')#ddt帮你读文件,获取文件内容,循环调用函数 百分号s是指变量file_name
def test_request(self,**kwargs):
detail = kwargs.get('detail','没写用例描述')
self._testMethodDoc = detail #动态的用例描述
url = kwargs.get('url')#url
url = parse.urljoin(self.base_url,url)#拼接好url
method = kwargs.get('method','get')#请求方式
data = kwargs.get('data',{}) #请求参数
header = kwargs.get('header',{})#请求头
cookie = kwargs.get('cookie',{})#cookie
check = kwargs.get('check')
method = method.lower() #便于处理
try:
if method=='get':
res = requests.get(url,params=data,cookies=cookie,headers=header).text
#因为接口有异常的情况下, 可能返回的不是json串,会报错
else:
res = requests.post(url,data=data,cookies=cookie,headers=header).text
except Exception as e:
print('接口请求出错')
res = e
for c in check:
self.assertIn(c,res,msg='预计结果不符,预期结果:'+c + '实际结果:' +res)
四.自动化框架的文件布局:
五.写代码:
1.新建用例,举例:注册reg.yaml和注册login.yaml
reg.yaml:
2.配置setting文件,将所有文件中用到的变量定义在该文件,需要修改的时候,直接在该文件中修改即可。setting:
import os
BASE_PATH = os.path.dirname( #找到utp的目录
os.path.dirname(os.path.abspath(__file__))
)
MAIL_HOST='smtp.163.com'
MAIL_USER='lix.xxxx@163.com'
MAIL_PASSWRD = 'xxxxxxxxx1'
TO = [
'5472xxxxx@qq.com',
]
LEVEL = 'debug' #日志级别 LOG_PATH = os.path.join(BASE_PATH,'logs') #存放日志的路径
CASE_PATH = os.path.join(BASE_PATH,'cases') #存放用例的路径
YAML_PATH = os.path.join(BASE_PATH,'case_data') #存放yaml文件的路径
CASE_TEMPLATE = os.path.join(BASE_PATH,'conf','base.txt') #用例模板的路径
REPORT_PATH = os.path.join(BASE_PATH,'report') #存放报告的目录
BASE_URL = 'http://118.xx.xx.xx' #接口的地址
LOG_NAME='utp.log' #日志的文件名
3.在lib文件下新建tools.py:首先判断case_data下的.yaml文件个数,创建对应的python文件。具体:打开并读取base.txt文件,将文件中的类和文件名替换后,再创建python文件。生成用例-->运行所有用例:
import datetime
import yagmail
from lib.log import utp_log #要用到日志文件
from conf import setting #要用到配置文件中的变量
import os
import unittest
from BeautifulReport import BeautifulReport as bf #生成报告
def makeCase(): #生成用例
all_yaml = os.listdir(setting.YAML_PATH) #获取所有的ymal文件
base_case_str = open(setting.CASE_TEMPLATE,encoding='utf-8').read()#读取到base.txt文件里的内容,写在循环外面
for yaml in all_yaml: #判断读取的文件是否为.yaml或.yml
if yaml.endswith('.yaml') or yaml.endswith('.yml'):#判断是否是yml文件
class_name = yaml.replace('.yml','').replace('.yaml','').capitalize()#将文件名的后缀去掉获取类名,并首字母大写
file_name = os.path.join(setting.YAML_PATH,yaml)#拼接生成的ymal文件的绝对路径
content = base_case_str %(class_name,file_name)
py_file_name = os.path.join(setting.CASE_PATH,class_name)#拼好生成python文件的绝对路径
open('%s.py'%py_file_name,'w',encoding='utf-8').write(content) #以w格式打开,保证每次打开ymal文件都会清空重新写 def run_all_case(): #找到所有的python用例文件,并运行
suite = unittest.TestSuite() #调用unittest模块的TestSuite(),实例化
all_py = unittest.defaultTestLoader.discover(setting.CASE_PATH,'*.py') #在指定目录下找python文件:以.py结尾的python文件
#找到所有的python文件
[ suite.addTests(py) for py in all_py] #这里用addTests,是因为py文件里可能有多个函数,都要添加进来
#列表生成式,添加文件里面的case到测试集合里面
# for py in all_py: #等同于上面的列表生成式
# suite.addTests(py)
run=bf(suite)
today = datetime.datetime.today().strftime('%Y%m%d%H%M%S') #.strftime将时间格式化取到秒
title = '%s_接口测报告.html'%today
report_abs_path = os.path.join(setting.REPORT_PATH,title) #拼接报告的绝对路径
run.report(title,filename=title,log_path=setting.REPORT_PATH)
return run.success_count,run.failure_count,report_abs_path def sendmail(title,content,attrs=None):
try:
m = yagmail.SMTP(host=setting.MAIL_HOST,user=setting.MAIL_USER
,password=setting.MAIL_PASSWRD
)
m.send(to=setting.TO,subject=title,
contents=content,
attachments=attrs)
except Exception as e:
msg = '邮件发送失败,%s'%e
utp_log.error(msg)
4.在bin文件下新建run.py,按照逻辑运行文件。分别调用生成用例,运行用例,发报告的类。
import os,sys
import datetime BASE_PATH = os.path.dirname( #因为run.py是入口文件,还没有加载setting文件,所以不能找到环境变量,需在此定义BASE_PATH找到utp目录
os.path.dirname(os.path.abspath(__file__))
)
sys.path.insert(0,BASE_PATH)
from lib import tools def main():
tools.makeCase()#自动产生用例的python文件
pass_count,fail_count,abs_path = tools.run_all_case()#运行所有用例并获取其返回值
msg='''
各位好!
本次接口测试结果如下:
通过用例:%s条
失败用例:%s条
详细信息见附件【%s】。
'''%(pass_count,fail_count,os.path.basename(abs_path)) #os.path.basename()获取绝对路径的文件名
today = datetime.datetime.today().strftime('%Y%m%d%H%M%S')
title = '接口测试报告_%s'%today #邮件标题
tools.sendmail(title,msg,abs_path) #发送邮件,标题,提示信息,附件
main()
5.生成的python文件举例,Login.py:
import unittest,requests
import ddt
from BeautifulReport import BeautifulReport as bf
from BeautifulReport import BeautifulReport as bf
from urllib import parse
from conf.setting import BASE_URL
@ddt.ddt
class Login(unittest.TestCase): #是百分号s指变量class_name
base_url = BASE_URL
@ddt.file_data(r'C:\Users\Fancy\Desktop\学习笔记\day11\utp\case_data\login.yaml')#ddt帮你读文件,获取文件内容,循环调用函数 百分号s是指变量file_name
def test_request(self,**kwargs):
detail = kwargs.get('detail','没写用例描述')
self._testMethodDoc = detail #动态的用例描述
url = kwargs.get('url')#url
url = parse.urljoin(self.base_url,url)#拼接好url
method = kwargs.get('method','get')#请求方式
data = kwargs.get('data',{}) #请求参数
header = kwargs.get('header',{})#请求头
cookie = kwargs.get('cookie',{})#cookie
check = kwargs.get('check')
method = method.lower() #便于处理
try:
if method=='get':
res = requests.get(url,params=data,cookies=cookie,headers=header).text
#因为接口有异常的情况下, 可能返回的不是json串,会报错
else:
res = requests.post(url,data=data,cookies=cookie,headers=header).text
except Exception as e:
print('接口请求出错')
res = e
for c in check:
self.assertIn(c,res,msg='预计结果不符,预期结果:'+c + '实际结果:' +res)
6.log.py,生生日志的文件:
import logging,os
from logging import handlers
from conf import setting
class MyLogger():
def __init__(self,file_name,level='info',backCount=5,when='D'):
logger = logging.getLogger() # 先实例化一个logger对象,先创建一个办公室
logger.setLevel(self.get_level(level)) # 设置日志的级别的人
cl = logging.StreamHandler() # 负责往控制台输出的人
bl = handlers.TimedRotatingFileHandler(filename=file_name, when=when, interval=1, backupCount=backCount, encoding='utf-8')
fmt = logging.Formatter('%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s')
cl.setFormatter(fmt) # 设置控制台输出的日志格式
bl.setFormatter(fmt) # 设置文件里面写入的日志格式
logger.addHandler(cl)
logger.addHandler(bl)
self.logger = logger def get_level(self,str):
level = {
'debug':logging.DEBUG,
'info':logging.INFO,
'warn':logging.WARNING,
'error':logging.ERROR
}
str = str.lower()
return level.get(str) path = os.path.join(setting.LOG_PATH,setting.LOG_NAME) #拼好日志的绝对路径
utp_log = MyLogger(path,setting.LEVEL).logger #日志级别
#直接在这里实例化,用的时候就不用再实例化了
总结:
该自动化框架是基于unittest重新封装的,也是基于数据驱动进行的,只是数据的格式不是excel而是yaml格式的。与第一篇自动化框架相比,不需要自己写框架。
unittest框架扩展(自动生成用例)自动化-上的更多相关文章
- 用 Python 为接口测试自动生成用例
用Python为接口自动生成测试用例 基于属性的测试会产生大量的.随机的参数,特别适合为单元测试和接口测试生成测试用例 尽管早在2006年haskell语言就有了QuickCheck来进行" ...
- tep集成mitmproxy录制流量自动生成用例
使用 操作过程非常简单,流程如下: ①配置过滤域名 必须配置,不然会有很多无效流量造成数据冗余. ②启动代理 「示例」使用了反向代理,tep自带FastApi启动Mock服务: 「实际」使用正向代理, ...
- unittest框架(一)用例管理
在unittest框架的自动化接口测试中,可以用yaml文件来管理用例,这样一方面,不会像excel管理用例那么死板:另一方面,数据读取出来就是一个字典,便于取值,用起来更灵活. 首先,需要安装一个模 ...
- Makeflie自动生成依赖,自动化编译
在netbeans里开发,有一个重要文件makefile,是用来编译所有的文件. 项目的目录结构如下,扁平的目录结构,如何实现自动化编译,写makefile呢? 第一版 基础版: CC = g++ C ...
- Python3 完美解决unittest框架下不生成测试报告
前提: 1.运行测试用例一切正常,只是没有测试报告显示 2.使用命令行pyhon 脚本名字.py 却可以生成测试报告 3.pycharm 在运行测试用例的时候 默认是以unittest 框架来运行的, ...
- 根据表结构自动生成JavaBean,史上最强最专业的表结构转JavaBean的工具(第2版)
目录: 第1版:http://blog.csdn.net/vipbooks/article/details/51912143 ...
- unittest框架扩展(基于代码驱动)自动化-下
一.数据驱动/代码驱动优缺点: 使用数据驱动的好处:- 代码复用率高.同一测试逻辑编写一次,可以被多条测试数据复用,提高了测试代码的复用率,同时可以提高测试脚本的编写效率.- 异常排查效率高.测试框架 ...
- appium_python 怎样实现参数化自动生成用例
1.对于一种对同一个页面同一点 要用不同数据测试形成多条测试用例,如果复制的话 会让代码很冗长,并且并不好维护,现在用封装的方法把 不变的代码 和 变化的参数 分别封装,形成动态 生成测试用例 ,主要 ...
- Yii2框架---GII自动生成
本地环境配置完成后.访问路径直接加上/gii 例如 localhost/gii 即可生成YII活动记录类 即可生成模块
随机推荐
- 剑指offer-二叉树的镜像-python
题目描述 操作给定的二叉树,将其变换为源二叉树的镜像. 输入描述: 二叉树的镜像定义:源二叉树 8 / \ 6 10 / \ / \ 5 7 9 11 镜像二叉树 8 / \ 10 6 / \ / \ ...
- “百度杯”CTF比赛 十一月场--CrackMe01
测试文件:https://static2.ichunqiu.com/icq/resources/fileupload/CTF/BSRC/BSRC-11-3/CrackMe01_97D2BF0DBD2E ...
- js/nodejs导入Excel相关
导入示例如下: Excel可设置单元格的数字显示格式,特别的,常规格式下,会根据列宽缩进显示. 实际中,有时需要导入实际值,有时需要导入显示值. 而B2的显示值,由于跟列宽相关,目前未找到任何软件,可 ...
- Solr知识点摘录
1.Solr和Lucene区别: 2.Solr的下载与安装 3. 4. 5. 6.Solr基础 7. 8.Solr索引操作 9. 10.
- Thinkphp5 手册
thinkphp5 手册 https://www.kancloud.cn/manual/thinkphp5/118003
- UVa11806 Cheerleaders(容斥原理)
11806 - Cheerleaders Time limit: 2.000 seconds C Cheerleaders In most professional sporting events, ...
- noip2017简要题解。
重新写了一下去年的题来看看自己到底是有多傻逼. 小凯的疑惑 打表. 时间复杂度 搞了一大坨题面,但是真正有用的信息只有几个: 判断他给你的复杂度是多少. 判断当前循环进不进的去. 判断当前循环产生的贡 ...
- Django【第3篇】:Django之模板语法
Django框架之第三篇模板语法(重要!!!) 一.什么是模板? 只要是在html里面有模板语法就不是html文件了,这样的文件就叫做模板. 二.模板语法分类 一.模板语法之变量:语法为 {{ }}: ...
- AI人工智能对医疗行业有哪些巨大贡献?
人工智能(AI)有可能显着改变医生的角色并彻底改变医学实践.这篇定性评价文章总结了过去12个月的人工智能健康研究,涉及不同的医学专业,并讨论了与这一新兴技术相关的当前优势和挑战. 医生,特别是担任领导 ...
- [原创]PHP代码修正之CodeSniffer
目录 参考链接 介绍 安装 使用 命令行模式 PHPStorm 让编辑器使用PSR-2标准 集成phpcbf 参考链接 PHP开发规范之使用phpcbf脚本自动修正代码格式 在PhpStorm中使用P ...