通过上一节的编写,可以发现,每个测试函数内接口重复调用,测试数据与测试方法没有分离,维护起来比较麻烦,这一节主要解决上一节存在的两个问题,上一节见python接口自动化之登录——基础版
问题一:接口重复调用:
解决:对于接口重复调用,可以对此进口进行封装,每次直接调用此封装即可,这里新建一个requests_handler.py,代码如下
import requests
class RequestsHandler:
def __init__(self):
"""session管理器"""
self.session = requests.session()
def visit(self, method, url, params=None, data=None, json=None, headers=None):
result = self.session.request(method, url, params=params, data=data, json=json, headers=headers)
try:
# 返回json结果
return result.json()
except Exception:
return 'not json'
def close_session(self):
self.session.close()
"""
以下为测试代码
if __name__ == '__main__':
login_url = 'http://XXXXXXX/sso/api/account/SignIn'
payload = {
"email": "XXXXXXX@huadaocart.com",
"password": "XXXXXXX"
}
headers = {"content-type": "application/json"}
req = RequestsHandler()
res = req.visit('post',url=login_url,json=payload,headers=headers)
print(res['message'])
"""
问题二:测试数据未与用例分离,维护成本大
解决:实现数据与用例分离,这里使用xlsx文件保存测试数据,ddt实现数据驱动,
对于xlsx文件的操作,这里引用openpyxl第三方库,具体的openpyxl的使用方法请另行百度。这里新建一个excel_handler.py用于对测试数据管理,代码如下:
import openpyxl
class ExcelHandler:
def __init__(self, file):
self.file = file
def open_excel(self, sheet_name):
"""打开Excel、获取sheet"""
wb = openpyxl.load_workbook(self.file)
# 获取sheet_name
sheet = wb[sheet_name]
return sheet
def get_header(self, sheet_name):
"""获取header(表头)"""
wb = self.open_excel(sheet_name)
header = []
# 遍历第一行
for i in wb[1]:
# 将遍历出来的表头字段加入列表
header.append(i.value)
return header
def read_excel(self, sheet_name):
"""读取所有数据"""
sheet = self.open_excel(sheet_name)
rows = list(sheet.rows)
data = []
# 遍历从第二行开始的每一行数据
for row in rows[1:]:
row_data = []
# 遍历每一行的每个单元格
for cell in row:
row_data.append(cell.value)
# 通过zip函数将两个列表合并成字典
data_dict = dict(zip(self.get_header(sheet_name), row_data))
data.append(data_dict)
return data
@staticmethod
def write_excel(file, sheet_name, row, cloumn, data):
"""Excel写入数据"""
wb = openpyxl.load_workbook(file)
sheet = wb[sheet_name]
sheet.cell(row, cloumn).value = data
wb.save(file)
wb.close()
"""
以下为测试代码
if __name__ == "__main__":
# 以下为测试代码
excel = ExcelHandler(r"C:\Users\huadao\PycharmProjects\test\data\cases.xlsx")
data = excel.read_excel('login')
print(data)
"""
最后使用ddt实现数据驱动,最终test_Login002.py中代码如下:
import unittest
from common.requests_handler import RequestsHandler
from common.excel_handler import ExcelHandler
import ddt
import json
@ddt.ddt
class TestLogin(unittest.TestCase):
# 读取excel中的数据
excel = ExcelHandler(r"C:\Users\huadao\PycharmProjects\test\data\cases.xlsx")
case_data = excel.read_excel('login')
print(case_data)
def setUp(self):
# 请求类实例化
self.req = RequestsHandler()
def tearDown(self):
# 关闭session管理器
self.req.close_session()
@ddt.data(*case_data)
def test_login_success(self, items):
# 请求接口
res = self.req.visit(method=items['method'], url=items['url'], json=json.loads(items['payload']),
headers=json.loads(items['headers']))
try:
# 断言:预期结果与实际结果对比
self.assertEqual(res["message"], items['expected_result'])
result = 'Pass'
except AssertionError as e:
result = 'Fail'
raise e
finally:
# 将响应的状态码,写到excel的第9列,即写入返回的状态码
TestLogin.excel.write_excel(r"C:\Users\huadao\PycharmProjects\test\data\cases.xlsx", 'login',
items['case_id'] + 1, 9, res["code"])
# 如果断言成功,则在第10行(测试结果)写入Pass,否则,写入Fail
TestLogin.excel.write_excel(r"C:\Users\huadao\PycharmProjects\test\data\cases.xlsx", 'login',
items['case_id'] + 1, 10, result)
if __name__ == '__main__':
unittest.main()
其中测试数据模板cases.xlsx内容如下:
最终的目录结构如下: