python+request+unittest+ddt
一、接口自动化测试框架(python+request+unittest+ddtj 7个包)讲解
首先我们新建一个新项目:名称zdh
二、在一个项目中:新建7个包
第一个包conf包用来填写配置参数、地址等
第二个包data 包用来存放测试用例的表格
第三个包report 包用来存放测试报告
第四个包case 用例包 用来编写测试用例
第五个包run包 运行包 用来运行所有的用例或邮件等
第六个包utils 包 工具类包 存放所有自己封装的语句和外包导入的工具函数
第7个包library包 外包导入的工具函数 如邮件模板,报告模板
1.新建一个项目
2、新建7个包
3、在utils中新建:handle_path .py 文件 (组建项目中所有路径)
import os #导入os模块
#项目路径
base_path=os.path.dirname(os.path.dirname(__file__))
print(base_path)
data_path=os.path.join(base_path,'data')
print(data_path) #定义data路径
conf_path=os.path.join(base_path,'conf')
print(conf_path)#定义conf路径
report_path=os.path.join(base_path,'report')
print(report_path)#定义report路径
testcase_path=os.path.join(base_path,'testcase')
print(testcase_path)#定义testcase路径
utils_path=os.path.join(base_path,'utils')
print(utils_path)#定义utils路径
run_path=os.path.join(base_path,'run')
print(run_path)#定义run路径
4、在conf文件中新建一个:ini文件 (命名:conf.ini)
ini文件格式(节点 下面 :键=值 ) 节点:section 键值:option
[env] #section #节点
url =http://cms.e70w.com ##section url就是键 http://cms.e70w.com 是值
headers = {"Content-Type":"application/x-www-form-urlencoded"}
[test_data]
username = admin
pwd = 123456
[db]
[email]
新建完ini文件以后,我们要读取ini文件中的数据,我们在utils下封装一个读取方法:
5、在utils下新建py文件:命名 handle_conf
我们要读取ini文件先导入configparser 这个模块:pip install configparser
'''
此模块是用来处理conf.ini文件的
'''
from configparser import ConfigParser
from utils.handle_path import *
import os
class Handle_conf(ConfigParser):
'''
当前这个类是用来处理conf.ini文件的工具类
'''
def __init__(self,filename):
super(Handle_conf,self).__init__() #继承父类的构造方法
self.filename = filename #把传进来的形式参数赋值给到实例变量self.filename
self.read(self.filename) #打开ini文件进行读取
def get_value(self,section,option):
'''
获取ini文件中的section下面对应的option的value值
'''
value = self.get(section,option)
return value
path = os.path.join(conf_path,'conf.ini')
conf =Handle_conf(path)
=================================
6、在data包中新建一个xlsx文件(接口用例):
以上是将接口文档写好,写好之后就要读取文档中的数据
7、在utils 中新建一个读取xlsx文档的py文件:命名为(handle_excel.py)
因为读取和写入都要用到openpyxl这个库;下载openpyxl:
pip install openpyxl
import openpyxl
from utils.handle_path import *
class Handle_Excel(object):
def __init__(self ,filename,sheet_name):
self.filename=filename
self.sheet_name=sheet_name
def open(self):
self.wb=openpyxl.load_workbook(self.filename)
self.sh=self.wb[self.sheet_name]
def read_data(self):
self.open()
datas=list(self.sh.rows)
# print(datas)
title=[ i.value for i in datas[0]]
print(title) #
cases=[]
for j in datas[1:]:
values=[k.value for k in j]
# print(values)
case=dict(zip(title,values))
# print(case)
cases.append(case)
return cases
def write_excel(self,row,colume,value):
self.open()
self.sh.cell(row,colume,value)
self.wb.save(self.filename)
if __name__ == '__main__':
path=os.path.join(data_path,'apicase.xlsx')
read_excel=Handle_Excel(path,'login')
# read_excel.read_data()
read_excel.write_excel(2,8,'通过')
以上能够读取xlsx 中的表格数据
==========================
8、数据准备好,接下来我们调用方法:在utils中封住一个调用方法:handle_requests.py(命名)
开始要导入 impost requests 导入requests 请求
import requests
class Send_requests(object):
def __init__(self):
self.session=requests.Session()
def send(self,method,url,data=None,json=None,params=None,headers=None):
method=method.lower()
if method == 'get':
response=self.session.get(url,params)
elif method=='post':
response = self.session.post(url, data,headers)
elif method =='post_json':
response = self.session.post(url, json ,headers)
elif method =='delete':
response = self.session.delete(url,data)
return response
# if __name__ == '__main__':
# dx = Send_requests()
# method='post'
# url="http://cms.e70w.com/manage/loginJump.do"
# data={"userAccount":"admin","loginPwd":"123456"}
# headers = {"Content-Type": "application/x-www-form-urlencoded"}
# s=dx.send(method=method,url=url,data=data,headers=headers)
# print(s.text)
以上是封装好的调用方法,接下来我们开始写用例
=============================================
9、写用例就在testcase 包中: 新建一个用例模块,命名(test_login)
import unittest
from ddt import ddt ,data
from utils.handle_conf import *
from utils.handle_excel import *
from utils.handle_path import *
from utils.handle_requests import Send_requests
case_file=os.path.join(data_path,'apicase.xlsx')
@ddt
class Test_Login(unittest.TestCase):
excel=Handle_Excel(case_file,'login')
cases=excel.read_data()
request=Send_requests()
@data(*cases)
def test_01_login(self,case):
url=conf.get_value('env','url')+case['url']
# print(url)
# eval 函数是用来执行一个字符串表达式,并返回表达式值
headers=eval(conf.get_value('env','headers'))
# print(headers)
method=case['method']
# print(method)
data=eval(case['data'])
# print(data)
excepted=eval(case['excepted'])
# print(excepted)
case_id=case['case_id']
case_id=case_id+1
response=self.request.send(method=method,url=url,data=data,headers=headers,)
result=response.json()
print(result)
try:
self.assertEqual(excepted['msg'],result['msg'])
self.assertEqual(excepted['code'], result['code'])
except Exception as e:
self.excel.write_excel(case_id,8,'未通过')
else:
self.excel.write_excel(case_id,8,'通过')
# if __name__ == '__main__':
# # dx=Test_Login()
# # dx.test_01_login()
# if __name__ == '__main__':
# unittest.main()
以上是将准备的数据和封装好的调用方法都导入,在调用所有的数据组建好,并进行断言回写,写好登录以后,要进行run运行
==================================================
10、在run包中新建一个包:run_allcase包,
import time
from library.HTMLTestRunnerNew import HTMLTestRunner
from utils.handle_path import *
import unittest
from library.mail import SendMail
now=time.strftime('%y-%m-%d %H-%M-%S')
filename=report_path+'/'+str(now)+'__api_report.html'
def fs():
d=unittest.TestLoader().discover(start_dir=testcase_path,pattern='test_*.py')
f=open(filename,'bw')
r=HTMLTestRunner(stream=f,title='cms平台接口自动自动化测试报告',description="用例执行情况",
tester='dcs')
r.run(d)
f.close()
def syj():
sm=SendMail(send_msg=filename,attachment=filename)
sm.send_mail()
if __name__ == '__main__':
fs()
# syj()
以上是通过html 模板,邮件模板进行运行的;我们要在library中导入模板
11、library中导入两个模板:HTMLTestRunnerNew.py ,mail.py
以上就整个框架就完成了整体结构:
==================================================
12、但是新增接口需要保持登录状态,
所以我们就要封装一个公共登录方法:
在utils中:handle_login.py文件 ,封装一个登录方法如下
from utils.handle_conf import conf
from utils.handle_requests import Send_requests
class Cms_login():
def login(self):
request=Send_requests()
url=conf.get_value('env','url')+'/manage/loginJump.do'
data={"userAccount":"admin","loginPwd":"123456"}
headers=conf.get_value('env','headers')
response=request.send(method='post',url=url,data=data,headers=headers)
print(response.json())
return request
# if __name__ == '__main__':
# dx=Cms_login()
# dx.login()
==================================================
13、然后添加用例就在testcase中新增test_updateloginpwd.py 文件,可以将登录中的方法复制过来;修改一下三个地方
import unittest
from ddt import ddt ,data
from utils.handle_conf import *
from utils.handle_excel import *
from utils.handle_path import *
from utils.handle_requests import Send_requests
from utils.handle_login import Cms_login #第一地方:导入登录方法
case_file=os.path.join(data_path,'apicase.xlsx')
@ddt
class Test_Login(unittest.TestCase):
excel=Handle_Excel(case_file,'updateLoginPwd') #第二个地方修改 sheetname页面名称
cases=excel.read_data()
request=Send_requests()
@classmethod #第三个地方 通过类方法 调用登录
def setUpClass(cls) -> None:
cls.request=Cms_login().login() #调用公共登录方法
@data(*cases)
def test_01_login(self,case):
url=conf.get_value('env','url')+case['url']
# print(url)
# eval 函数是用来执行一个字符串表达式,并返回表达式值
headers=eval(conf.get_value('env','headers'))
# print(headers)
method=case['method']
# print(method)
data=eval(case['data'])
# print(data)
excepted=eval(case['excepted'])
# print(excepted)
case_id=case['case_id']
case_id=case_id+1
response=self.request.send(method=method,url=url,data=data,headers=headers,)
result=response.json()
print(result)
try:
self.assertEqual(excepted['msg'],result['msg'])
self.assertEqual(excepted['code'], result['code'])
except Exception as e:
self.excel.write_excel(case_id,8,'未通过')
else:
self.excel.write_excel(case_id,8,'通过')
# if __name__ == '__main__':
# # dx=Test_Login()
# # dx.test_01_login()
if __name__ == '__main__':
unittest.main()
==================================================
14、还要添加用例就在testcase中新增test_delete.py 文件,将修改密码内容复制过来,在修改下如下sheetname页面名就可以
import unittest
from ddt import ddt ,data
from utils.handle_conf import *
from utils.handle_excel import *
from utils.handle_path import *
from utils.handle_requests import Send_requests
from utils.handle_login import Cms_login
case_file=os.path.join(data_path,'apicase.xlsx')
@ddt
class Test_Login(unittest.TestCase):
excel=Handle_Excel(case_file,'delete') # 修改的地方"delete"
cases=excel.read_data()
request=Send_requests()
@classmethod
def setUpClass(cls) -> None:
cls.request=Cms_login().login()
@data(*cases)
def test_01_login(self,case):
url=conf.get_value('env','url')+case['url']
# print(url)
# eval 函数是用来执行一个字符串表达式,并返回表达式值
headers=eval(conf.get_value('env','headers'))
# print(headers)
method=case['method']
# print(method)
data=eval(case['data'])
# print(data)
excepted=eval(case['excepted'])
# print(excepted)
case_id=case['case_id']
case_id=case_id+1
response=self.request.send(method=method,url=url,data=data,headers=headers,)
result=response.json()
print(result)
try:
self.assertEqual(excepted['msg'],result['msg'])
self.assertEqual(excepted['code'], result['code'])
except Exception as e:
self.excel.write_excel(case_id,8,'未通过')
else:
self.excel.write_excel(case_id,8,'通过')
# if __name__ == '__main__':
# # dx=Test_Login()
# # dx.test_01_login()
if __name__ == '__main__':
unittest.main()
然后在到run包去点击运行,查看report中的报告模板,查看结果如下
以上就是框架的一个流程。
================================================================
二、python+request+unittest+ddt 整理成word文档讲解稿(参考)
案例1:
我讲下我做的接口自动化是python+request+unittest+ddt 实现的,下面我介绍整个框架的结构有7层以及每个包中的内容:
第1层的话是config配置层,这个里面主要是封装了一些我们测试环境的url地址和一些连接数据库的IP地址,用户名密码等等
第2层是data数据层,这个里面主要放的是接口的用例,把接口的入参,接口的路径,接口的编号,请求方法都放在这个里面了,一个接口放在一个sheet页面里面,然后一个sheet页面里面有多个接口测试用例,有正常场景的也有多个异常场景的
第3层是一个library第三方的公共库层,里面主要是放了发邮件的工具类,生成测试报告的工具类还有做数据驱动的ddt模块
第4层就是utils工具类层,主要封装了读取Excel表格,读取ini配置文件和发送接口请求的工具类
第5层就是testcase用例层,这个里面首先会创建一个类,然后在里面创建以test开头的方法,然后定义一个data装饰器主要是用来接受Excel表格里面的接口入参,第一步先做数据的处理,然后第二步再通过封装好的发接口请求的工具类发送接口请求得到response返回值,第三步再对接口进行断言,一般会对接口返回的状态码和返回的比较具有唯一性的文本信息进行断言
第6层就是run运行层,首先会通过把所有的用例加载到一个suite套件里面,然后再通过调用run方法运行这个套件,并且通过HTMLtestrunner模块生成测试报告放到
第7层报告层里面,然后最后通过Jenkins做可持续集成,在回归测试阶段,每天晚上都会运行一下我们的接口自动化用例,大致的一个框架结构就是这样的。