python+API接口测试框架设计(unittest)
1.测试框架简介
整个接口测试框架的设计图如下:

basepage:存放的是公共的方法
common:存放的是自定义工具
data:存放的是公共动态数据,如BB.xls/ Id.md
log:存放的是Log日志信息
report:存放的是接口测试报告
testcase:存放的是接口测试案例
runallcases.py 文件:项目运行的主程序文件
2、重构Requests请求,查看Blogbase.py文件代码
from TestCase.Api_Po.common.helper import Helper
import requests
class BlogBase(object):
def __init__(self):
self.helper = Helper()
self.s = requests.Session()
# self.blog = TestBlog()
def getMethod(self,nrow):
if self.helper.readUrl(nrow):
r = self.s.get(
url=self.helper.readUrl(nrow=nrow),
headers=self.helper.readHeaders(),
verify=False,
timeout=6)
# print(r.cookies)
self.s.cookies.update(self.helper.addcookie())
# print(self.s.cookies)
return r
else:
try:
print('接口地址有误')
except Exception as msg:
print('请求发生未知错误,错误原因是%s'%msg)
def postMethod(self,nrow):
if self.helper.readUrl(nrow):
r = self.s.post(
url=self.helper.readUrl(nrow=nrow),
data=self.helper.getRequestsData(nrow),
headers=self.helper.readHeaders1(),
verify=False,
timeout=6)
# print(r.cookies)
return r
else:
try:
print('接口地址有误')
except Exception as msg:
print('请求发生未知错误,错误原因是%s'%msg)
def deleteMethod(self,nrow):
if self.helper.readUrl(nrow):
r = self.s.delete(
url=self.helper.readUrl(nrow=nrow)+'%s'%self.helper.getID(),
headers=self.helper.readHeaders1(),
verify=False,
timeout=6)
return r
else:
try:
print('接口地址有误')
except Exception as msg:
print('请求发生未知错误,错误原因是%s'%msg)
3、重构公共工具类方法,参考helper.py文件代码
import xlrd
import os
import json
import requests
import logging
class Helper(object):
def get_dirName(self,filepath=None,filename=None):
'''查找文件的路径'''
return os.path.join(os.path.dirname(os.path.dirname(__file__)),filepath,filename)
def readExcels(self,nrow):
'''读取excel数据,nrow表示行数'''
# table = xlrd.open_workbook(r'D:\Project\TestCase\Api_Po\data\BB.xls')
table = xlrd.open_workbook(self.get_dirName('data','BB.xls'))
sheets = table.sheet_by_name('Sheet1')
return sheets.row_values(nrow)
def readCaseId(self,nrow):
'''获取测试用例编号'''
return self.readExcels(nrow)[0]
def readTitle(self,nrow):
'''获取测试用例标题'''
return self.readExcels(nrow)[1]
def readUrl(self,nrow):
'''获取测试用例url'''
return self.readExcels(nrow)[2]
def readMethod(self,nrow):
'''获取测试用例方法'''
return self.readExcels(nrow)[3]
def readData(self,nrow):
'''获取测试用例数据'''
return self.readExcels(nrow)[4]
def readHeaders(self):
'''获取测试用例头'''
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"
}
return headers
def readHeaders1(self):
'''获取测试用例头'''
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36",
"Content-Type":"application/json",
'Cookie':'__gads=ID=e10c3225dbe26fdd:T=1578924710:S=ALNI_MaaurX6gcz-ibwnmguYP6xQ82_iSQ; _ga=GA1.2.392048575.1578924638; _gid=GA1.2.1721164379.1581850417; UM_distinctid=1704dad947712d-0aee1dbade8bfb-39395704-100200-1704dad9478460; .Cnblogs.AspNetCore.Cookies=CfDJ8Nf-Z6tqUPlNrwu2nvfTJEhrC2s6fHXZQc4OzQdR6zEYKj27nYfGDX-6N55CXObuv5c7Z496hw_TbXnTgfB-1WA6clxBRaE9yUXK4zqrbS9hyCUhC_DRcsMNdpvOspxvsu2stUKfiqMvUdXPrilEdIrCyhj3jBvaBE2K91H2kfbXgq71wSYsKd0WZwapTXUgMcvWtKSt6qjIy9X5hHEmkMIT8KZPmD8ix5vDXIrmoPuPAMRzrMNZMI_kME0g41GF9EJb_0UHq1gtUMZQR41v78Eu3cE7Xqv7f4dbZXX6MB_p5S_ShpKCDajLmLr9EjfDnHdLLCYUhyxQQuoDakCXtG9FYkPScyXTZLQAuKeFs4XylA5v6XhmWZP087cw2Kum0clyUbXn2XeM5z5UUycmBbSmQhsIMkkPJX7ZrL9TLtpGewIq27EeKqKBuqYVTSt9oRYw130SJCNkBV2MJ2eQXhlCfT0eixXoCdZVrQXWhho9v8s9jLR-IwhQlDNLEDsB6WSqpPQK-VHpYsywVXa5cx6VrX-__mHfMmP2a8an9Sm9; .CNBlogsCookie=61D04946E80D3F55A595ABF64231EECEB662AFBF5F43EC3A11BB407816A434B13ABF8A286432AE9947C838B81D100FD8D20697AF56BDB291E7DA63C377C95760CF2483ACA8C4B24466E556FED4199F641ACF754F; _gat_gtag_UA_48445196_1=1; _gat=1',
"X-BLOG-ID":"456237"
}
return headers
def readJson(self):
'''获取json文件内容,使用到文件的反序列化'''
with open(self.get_dirName('data','requests.json'),encoding='utf-8') as fp:
return json.load(fp)
def getRequestsData(self,nrow):
'''引用BB.xls表格,提取参数'''
'''字典的序列化'''
return json.dumps(self.readJson()[self.readData(nrow)])
def addcookie(self):
'''添加cookie信息'''
c = requests.cookies.RequestsCookieJar()
c.set('.Cnblogs.AspNetCore.Cookies','CfDJ8Nf-Z6tqUPlNrwu2nvfTJEhrC2s6fHXZQc4OzQdR6zEYKj27nYfGDX-6N55CXObuv5c7Z496hw_TbXnTgfB-1WA6clxBRaE9yUXK4zqrbS9hyCUhC_DRcsMNdpvOspxvsu2stUKfiqMvUdXPrilEdIrCyhj3jBvaBE2K91H2kfbXgq71wSYsKd0WZwapTXUgMcvWtKSt6qjIy9X5hHEmkMIT8KZPmD8ix5vDXIrmoPuPAMRzrMNZMI_kME0g41GF9EJb_0UHq1gtUMZQR41v78Eu3cE7Xqv7f4dbZXX6MB_p5S_ShpKCDajLmLr9EjfDnHdLLCYUhyxQQuoDakCXtG9FYkPScyXTZLQAuKeFs4XylA5v6XhmWZP087cw2Kum0clyUbXn2XeM5z5UUycmBbSmQhsIMkkPJX7ZrL9TLtpGewIq27EeKqKBuqYVTSt9oRYw130SJCNkBV2MJ2eQXhlCfT0eixXoCdZVrQXWhho9v8s9jLR-IwhQlDNLEDsB6WSqpPQK-VHpYsywVXa5cx6VrX-__mHfMmP2a8an9Sm9')
c.set('.CNBlogsCookie','61D04946E80D3F55A595ABF64231EECEB662AFBF5F43EC3A11BB407816A434B13ABF8A286432AE9947C838B81D100FD8D20697AF56BDB291E7DA63C377C95760CF2483ACA8C4B24466E556FED4199F641ACF754F')
return c
def getID(self):
'''读取草稿箱ID'''
with open(self.get_dirName('data','Id.md'),) as fp:
return json.loads(fp.read())
def log(self,log_content):
'''日志定义级别'''
# 定义文件
logFile = logging.FileHandler(self.get_dirName('log','logInfo.md'), 'a',encoding='utf-8')
# log格式
fmt = logging.Formatter(fmt='%(asctime)s-%(name)s-%(levelname)s-%(module)s:%(message)s')
logFile.setFormatter(fmt)
# 定义日志
logger1 = logging.Logger('logTest', level=logging.DEBUG)
logger1.addHandler(logFile)
logger1.info(log_content)
logFile.close()
4、重构Mail方法,参考semdmail163.py文件代码
import smtplib
import os
from email.mime.multipart import MIMEMultipart #邮件附件类
from email.mime.text import MIMEText #邮件模板类
from email.header import Header #邮件头部模板
#发送带附件的函数
def semd_mail(file_new):
with open(file_new, "rb") as fp:
mail_body = fp.read()
#基本信息
smtpserver = "smtp.163.com"
port = 25
sender = "18797815816@163.com"
psw = "xxxxx" #163邮箱密码
receiver = "1512500241@qq.com"
#定义邮箱主题
msg = MIMEMultipart()
msg['subject'] = Header(u"自动化测试报告","utf-8")
msg['from'] = sender
msg["to"] = receiver
#不加msg['from'] msg["to"]会报错,是因为"收件人和发件人没有定义"
#HTML 邮件正文,直接发送附件的代码
body = MIMEText(mail_body,"html","utf-8")
msg.attach(body)
# 附件
att = MIMEText(mail_body,"base64","utf-8")
att["Content-Type"] = "application/octet-stream"
att["Content-Disposition"] = 'attachment; filename="test_report.html'
msg.attach(att)
#链接邮件服务器发送邮件
try:
smtp = smtplib.SMTP()
smtp.connect(smtpserver) # 连服务器
smtp.login(sender, psw)
except:
smtp = smtplib.SMTP_SSL(smtpserver, port)
smtp.login(sender, psw) # 登录
smtp.sendmail(sender, receiver, msg.as_string()) # 发送
print("邮件发送成功")
smtp.quit()
#查找最新的邮件
def new_file(report_path):
result_path = report_path
lists = os.listdir(result_path)
lists.sort() #从小到大排序
file = [x for x in lists if x.endswith(".html")]
file_new_name = os.path.join(result_path,file[-1])
return file_new_name
5、重构接口案例,参考testcase目录下的testblog.py文件代码
import unittest
import json
from TestCase.Api_Po.common.helper import Helper
from TestCase.Api_Po.basepage.Blogbase import BlogBase
class TestBlog(unittest.TestCase):
def setUp(self) -> None:
self.obj = BlogBase()
self.hepler = Helper()
def test_login(self):
'''测试登录'''
r1 = self.obj.getMethod(1)
# r1.cookies.update(self.hepler.addcookie())
self.assertEqual(r1.status_code,200)
self.hepler.log('测试登录成功')
# self.hepler.SaveImage('')
def test_aaa(self):
'''测试编辑保存'''
r2 = self.obj.postMethod(2)
with open(self.hepler.get_dirName('data','Id.md'),'w') as fp:
fp.write(json.dumps(r2.json()['id']))
self.assertEqual(r2.status_code,200)
# self.assertEqual(r2.json()['blogUrl'],'//www.cnblogs.com/Teachertao/')
self.hepler.log('测试编辑保存成功')
def test_delete_ID(self):
'''删除草稿箱'''
r3 = self.obj.deleteMethod(3)
print(r3.text)
self.assertEqual(r3.status_code,200)
self.hepler.log('测试删除草稿成功')
if __name__ == '__main__':
unittest.main(verbosity=2)
6、发送接口测试报告,参考runallcases.py文件代码
from TestCase.Api_Po.common.HTMLTestRunner import *
from TestCase.Api_Po.mail.sendmail163 import *
import HTMLTestRunnerCN
#实现的逻辑
#先生成测试报告
#查找最新的测试报告文件,通过new_file函数找到最新的测试报告,把返回的结果return file_new_name
#把new_file函数,file_new_name文件传入到send_mail 读取出来,然后以邮件的附件形式加载到邮件模板中,设置参数,链接服务器发送最新的测试报告#
if __name__ == '__main__':
report = os.path.dirname(__file__) #D:/Project/TestCase/Api_Po
test_path = os.path.join(report,"testcase") #测试用例文件夹
suite = unittest.defaultTestLoader.discover(
start_dir=test_path,pattern="test*.py",top_level_dir=None)
report_path = os.path.join(report,"report") #测试报告文件夹
if not os.path.exists(report_path):
os.mkdir(report_path)
else:
print('存在report报告文件夹')
now = time.strftime("%Y-%m-%d %H_%M_%S") #时间戳
file_name = report_path + '\\' + now + "report_test.html" #测试报告文件名
fp = open(file_name,"wb")
runner = HTMLTestRunnerCN.HTMLTestRunner(
stream = fp,
title = '博客园接口自动化测试报告',
description = 'u"系统环境:Windows7 浏览器:Chrome 用例执行情况:"'
)
runner.run(suite) #执行测试用例
fp.close()
new_report = new_file(report_path) #获取最新的报告文件
semd_mail(new_report) #发送最新的测试报告

python+API接口测试框架设计(unittest)的更多相关文章
- Python+API接口测试框架设计(pytest)
1.测试框架简介 整个接口测试框架的设计图如下: base:存放的是请求方法二次封装 common:存放的是自定义工具,操作excel,yaml文件等 data:存放的是公共动态数据,如data.xl ...
- 基于python的接口测试框架设计(三)接口测试的框架
基于python的接口测试框架设计(三)接口测试的框架 其实我这里用到的是unittest单元测试框架,,这个框架好就好在比较清楚,,setup terdown都可以处理一些初始化及完成后的工作 主要 ...
- 基于python的接口测试框架设计(二)配置一些参数及文件
基于python的接口测试框架设计(二)配置一些参数及文件 我这里需要基于我的项目配置的主要是登陆参数.以及baseURL ,把这些放在单独的文件里 毕竟导入的时候方便了一些 首先是url 图略 建 ...
- 基于python的接口测试框架设计(一)连接数据库
基于python的接口测试框架设计(一)连接数据库 首先是连接数据库的操作,最好是单独写在一个模块里, 然后便于方便的调用,基于把connection连接放在__init__()方法里 然后分别定义D ...
- 【转】基于Python的接口测试框架实例
下面小编就为大家带来一篇基于Python的接口测试框架实例.小编觉得挺不错的,现在就分享给大家,也给大家做个参考.一起跟随小编过来看看吧 背景 最近公司在做消息推送,那么自然就会产生很多接口,测试 ...
- 基于Python的接口测试框架实例
文章来源:http://www.jb51.net/article/96481.htm 下面小编就为大家带来一篇基于Python的接口测试框架实例.小编觉得挺不错的,现在就分享给大家,也给大家做个参考. ...
- python+selenium之框架设计
一.自动化测试框架 1.什么是自动化测试框架 简单来说,自动化测试框架就是由一些标准,协议,规则组成,提供脚本运行的环境.自动化测试框架能够提供很多便利给用户高效完成一些事情,例如,结构清晰开发脚本, ...
- 基于Python的接口测试框架
分析 接口是基于HTTP协议的,那么说白了,就是发起HTTP请求就行了,对于Python来说比较简单.直接使用requests就可以很轻松的完成任务. 架构 整个框架是比较小的,涉及的东西也比较少,只 ...
- [转]基于Python的接口测试框架
http://blog.csdn.net/wyb199026/article/details/51485322 背景 最近公司在做消息推送,那么自然就会产生很多接口,测试的过程中需要调用接口,我就突然 ...
随机推荐
- wrk(1)- 详细使用
介绍 wrk 是一个类似 ab(apache bench).jmeter 的压力测试工具,官方称它为:现代的 HTTP 基准测试工具 用 C 编写的 HTTP 协议压测工具 底层基于 epoll 和 ...
- Git操作_本地仓库第一次推送到远程仓库
实现目的: 本地已经安装好Git,pycham已经有一个项目,打算放到Git远程仓库 前提条件:本地配置好了公钥,且GIT 上关联好公钥,步骤如下: git本地仓库连接github操作步骤:windo ...
- 【Javascript + Vue】实现对任意迷宫图片的自动寻路
前言 可以直接体验最终效果:https://maze-vite.vercel.app/ 寻路前: 寻路后,自动在图片上生成红色路径,蓝色是探索过的区域: 这里我故意用手机斜着角度拍,就是为了展示程序完 ...
- 十、构建memcached服务
装包-------配置----起服务---验证 装包: [root@proxy ~]# yum -y install memcached //安装软件包memcached [root@ ...
- Spring Boot WebFlux-02——WebFlux Web CRUD 实践
第02课:WebFlux Web CRUD 实践 上一篇基于功能性端点去创建一个简单服务,实现了 Hello.这一篇用 Spring Boot WebFlux 的注解控制层技术创建一个 CRUD We ...
- Qt实现基于多线程的文件传输(服务端,客户端)
1. 效果 先看看效果图 这是传输文件完成的界面 客户端 服务端 2. 知识准备 其实文件传输和聊天室十分相似,只不过一个传输的是文字,一个传输的是文件,而这方面的知识,我已经在前面的博客写过了,不了 ...
- XML从入门到深入(超详细)
一:什么是XML XML (eXtensible Markup Language)指可扩展标记语言,标准通用标记语言的子集,简称XML.是一种用于标记电子文件使其具有结构性的标记语言. XML可以标记 ...
- win10下简单截图
win10 下面可以 win+shift+s 拖动截图,个人感觉是最简单的
- Bert模型实现垃圾邮件分类
近日,对近些年在NLP领域很火的BERT模型进行了学习,并进行实践.今天在这里做一下笔记. 本篇博客包含下列内容: BERT模型简介 概览 BERT模型结构 BERT项目学习及代码走读 项目基本特性介 ...
- 对ES6中类class以及实例对象、原型对象、原型链之间关系的详细总结
1. 类 ES6 中新增加了类的概念,可以使用 class 关键字声明一个类,之后用这个类来实例化对象.即类的用途:实例化对象. // 创建一个Person类 class Person { } // ...