前提条件:数据已经存放在excel表格中,数据表名data.xlsx,表单名login_data
test_http_request.py(unittest)测试http_request.py
http_request.py
# -*-coding: utf8 -*-
import requests
class HttpRequest(object):
def http_request(self, url, data, method, expected=None, cookie=None):
if method.lower() == 'get':
res = requests.get(url, data=None, cookies=cookie, verify=False)
else:
res = requests.post(url, data, cookies=cookie, verify=False)
return res
一、test_http_request
(1)初始化参数方法,但要超继承
import unittest
#继承unittest中的类TestCase,用来编写用例
class TestHttpRequest(unittest.TestCase):
#保留继承unittest原来的方法,拓展需要的参数
#初始化函数
def __init__(self, methodName, url, data, method, expected):#通过初始化函数传参
super(TestHttpRequest, self).__init__(methodName)#保留父类的方法
self.url = url
self.data = data
self.method = method
self.expected = expected
def setUp(self):
pass
#测试用例参数化
def test_api(self):
res = HttpRequest().http_request(
self.url,
self.data,
self.method,
self.expected,
getattr(GetData, 'Cookie')
)
if res.cookies: # 如果cookie有的话,那就更新COOKIE
setattr(GetData, 'Cookie', res.cookies)
try:
self.assertEqual(self.expected, res.json()['info'])
except AssertionError as e:
print('test_api的错误是:{}'.format(e))
raise e
print(res.json())
(2)ddt方式传数据
test_data = DoExcel('data_3.xlsx', 'login_data').get_data()
@ddt
class TestHttpRequest(unittest.TestCase):
def setUp(self):
pass
@data(*test_data)
def test_api(self, item):
res = HttpRequest().http_request(
item['url'],
eval(item['data']),
item['method'],
item['expected'],
getattr(GetData, 'Cookie')
)
if res.cookies: # 如果cookie有的话,那就更新COOKIE
setattr(GetData, 'Cookie', res.cookies)
try:
self.assertEqual(item['expected'], res.json()['info'])
except AssertionError as e:
print('test_api的错误是:{}'.format(e))
raise e
print(res.json())
二、test_suite控制测试用例执行
(1)取数据方法一:全都取出来
test_data = DoExcel1('data.xlsx', 'login_data').get_data()
suite = unittest.TestSuite()#加载用例到用例的方法名
for item in test_data:#从test_data中取数据
suite.addTest(
TestHttpRequest(
'test_api',
item['url'],
eval(item['data']),#把字符串转换成原来的格式字典
item['method'],
item['expected']
)
)
(2)取数据方法二:用哪个取哪个
t = DoExcel2('data.xlsx', 'login_data')
suite = unittest.TestSuite()
for i in range(1, t.max_row + 1):
suite.addTest(
TestHttpRequest(
'test_api',
t.get_data(i, 1),
eval(t.get_data(i, 2)),
t.get_data(i, 3),
t.get_data(i, 4)
)
)
注意:上述两种方法选择一种使用,不是同时使用,推荐使用第一种
执行用例
with open('test_login_report.html', 'w', encoding='utf8') as file:
runner = HTMLTestRunner(
output="./reports/",
stream=file,
verbosity=2,
descriptions=True
)
runner.run(suite)
三、do_excel
do_excel读数据的目的是为了把返回的数据以列表嵌套字典的形式输出
(1)方法一:读出全部数据
# -*-coding: utf8 -*-
from openpyxl import load_workbook
class DoExcel1(object):
def __init__(self, file_name, sheet_name):
self.file_name = file_name
self.sheet_name = sheet_name
def get_data(self):
wb = load_workbook(self.file_name)
sheet = wb[self.sheet_name]
max_row = sheet.max_row
test_data = []
for row in range(1, max_row + 1):
sub_data = {}
sub_data['url'] = sheet.cell(row, 1).value
sub_data['data'] = sheet.cell(row, 2).value
sub_data['expected'] = sheet.cell(row, 3).value
sub_data['method'] = sheet.cell(row, 4).value
test_data.append(sub_data)
return test_data
#def write_back(self, file_name, sheet_name, row, value):#把结果写回到表中
#wb = load_workbook(file_name)
#sheet_name = wb[sheet_name]
#sheet.cell(row, 5).value = value
#wb.save(file_name)
(2)方法二:根据坐标取出用到的单元格的值
class DoExcel2(object):
def __init__(self, file_name, sheet_name):
self.file_name = file_name
self.sheet_name = sheet_name
self.sheet_obj = load_workbook(self.file_name)[self.sheet_name]
#获取一个表单对象
self.max_row = self.sheet_obj.max_row
def get_data(self, i, j):
return self.sheet_obj.cell(i, j).value
#根据传入的坐标来传值
(3)方法三:表数据中加了标题,通过标题来定位数据(和方法一相同,加了标题)
class DoExcel3(object):
def __init__(self, file_name, sheet_name):
self.file_name = file_name
self.sheet_name = sheet_name
def get_header(self):
wb = load_workbook(self.file_name)
sheet = wb[self.sheet_name]
'''获取第一行标题'''
header = []
for column in range(1, sheet.max_column + 1):
header.append(sheet.cell(1, column).value)
return header
def get_data(self):
#从配置文件读取mode
mode = ReadConfig().read_config('case.config', 'MODE', 'mode')
wb = load_workbook(self.file_name)
sheet = wb[self.sheet_name]
max_row = sheet.max_row
header = self.get_header() #拿到header
test_data = []
for row in range(2, max_row + 1):
sub_data = {}
for column in range(1, sheet.max_column + 1):
sub_data[header[column - 1]] = sheet.cell(row, column).value
test_data.append(sub_data)
#根据mode值去判断
if mode == 'all':#默认执行所有用例
final_data = test_data
else:#[1, 2, 3, 4]
final_data = []
for item in test_data:#对test_data所有的测试数据进行遍历
if item['case_id'] in eval(mode):
final_data.append(item)
return final_data#返回获取到的数据
if __name__ == '__main__':
print(DoExcel('data.xlsx', 'login_data').get_data())
补充:上述通过配置文件读取执行用例的条件
#case.config文件举例
[MODE]
mode = all
[PYTHON]
num = 66
name = ['aaa','bbb']
import configparser
#section(中括号[]) option value #(key:value)
cf = configparser.ConfigParser()
cf.read('case.config', encoding='utf-8')
#读取配置文件的数据
#读取方法一
# res_1 = cf.get('MODE', 'mode')
# print(res_1)
#
# #读取方法二
# res_2 = cf['MODE']['mode']
# print(res_2)
# print(cf.sections())
# print(cf.items('MODE'))#每一组元素都存在一个元组里面,然后嵌套在一个列表里面
#数据类型讨论问题----都是字符串---->eval()转换字符串
print(type(cf.get('PYTHON', 'num')))
print(type(cf.get('PYTHON', 'name')))#配置文件里的内容输出都是字符串
补充:ddt
import unittest
from ddt import ddt, data, unpack
test_data = [[1, 4], [2, 3]]
@ddt#装饰测试类
class TestMath(unittest.TestCase):
# @data(test_data)#装饰测试方法 拿到几个数据 就执行几条用例 一条数据执行1次
# #@data(*test_data) #拆分开来 执行2次,一个*只能托一层外套
# #unpack 根据逗号进行拆分,不止一个参数
@data(test_data)
@unpack#如果unpack后的参数 少于5个 推荐用unpack
#要注意参数不对等的情况,提供对应个数的参数来接收变量
#如果你要对字典进行unpack的 参数名与你的字典key对应
def test_print_data(self, item):
print('item', item)
# def test_print_data(self, a, b):
# print('a', a)
# print('b', b)
网友评论