一、单个EXCEL执行
import unittest
from class_api_login_topup.demo import http_request
from class_api_login_topup.http_attr import Get_Attr # 反射的值
from ddt import ddt, data, unpack
from class_demo_login_topup.http_excel import HttpExcel # 读取excel的值
test_data = HttpExcel('test_api.xlsx', 'python').real_excel()
# test_data = [] 遍历 测试用例
# t = HttpExcel('test_api.xlsx', 'python').real_excel()
# for i in range(len(t)):
# if i % 2 == 0:
# test_data.append(t[i])
@ddt
class Login_Http(unittest.TestCase):
@data(*test_data)
def test_api(self, item): # 正常登录
res = http_request().request(item['url'], eval(item['data']), item['method'], getattr(Get_Attr, 'cookies'))
if res.cookies:
setattr(Get_Attr, 'cookies', res.cookies)
try:
self.assertEqual(str(item['expected']), res.json()['code'])
except AssertionError as e:
print("test_api's, error is {0}", format(e))
raise e
print(res.json())
执行文件:
import unittest
import HTMLTestRunner
suite = unittest.TestSuite()
loader = unittest.TestLoader()
from class_demo_login_topup import http_tools_1
suite.addTest(loader.loadTestsFromModule(http_tools_1)) # 对整个文件执行
with open('http_TestCase.txt', 'w+', encoding='UTF-8') as file:
runner = unittest.TextTestRunner(stream=file, verbosity=2)
runner.run(suite)
生产http_TestCase.txt的文件,后者生产:html格式
with open('Test_Case.html', 'wb') as file:
runner = HTMLTestRunner.HTMLTestRunner(stream=file, verbosity=0,
title=None, description=None)
runner.run(suite)
其中Excel中的数据是这样的:
# 实现第一种遍历 全部参数化
# 列表里面嵌套了字典
test_data = [{'url': 'http://test.lemonban.com/futureloan/mvc/api/member/login',
'data': {'mobilephone': '13972136808', 'pwd': '123456'}, 'expected': '10001', 'method': 'get'},
{'url': 'http://test.lemonban.com/futureloan/mvc/api/member/login',
'data': {'mobilephone': '13972136808', 'pwd': '12345678'}, 'expected': '20111', 'method': 'get'},
{'url': 'http://test.lemonban.com/futureloan/mvc/api/member/recharge',
'data': {'mobilephone': '13972136808', 'amount': '1000'}, 'expected': '10001', 'method': 'post'},
{'url': 'http://test.lemonban.com/futureloan/mvc/api/member/recharge',
'data': {'mobilephone': '13972136808', 'amount': '-100'}, 'expected': '20117', 'method': 'post'}]
# 利用excel去遍历
from openpyxl import load_workbook
class HttpExcel:
def __init__(self, excel_name, sheet_name):
self.excel_name = excel_name
self.sheet_name = sheet_name
def real_excel(self): # real_excel(self, mode='all'):
mode = FileConfig().config('do_config', 'MODE', 'mode') # 遍历 1 3 登录和充值两条用例
wb = load_workbook(self.excel_name)
sheet = wb[self.sheet_name]
test_data = []
for i in range(1, sheet.max_row + 1): # 遍历 1 2 3 4 sheet.max_row EXCEL中的最大行
sub_test = {}
sub_test['mode'] = sheet.cell(i, 1).value
sub_test['url'] = sheet.cell(i, 2).value
sub_test['data'] = sheet.cell(i, 3).value
sub_test['method'] = sheet.cell(i, 4).value
sub_test['expected'] = sheet.cell(i, 5).value
test_data.append(sub_test)
if mode == 'all':
final_data = test_data
else:
final_data = []
for item in test_data:
if item['mode'] in eval(mode):
final_data.append(item)
return final_data
def write_back(self, i, value): # 把测试结果写入到EXCEL文件中 I 行数 V 结果值保存
wb = openpyxl.load_workbook(self.file_name)
sheet = wb[self.sheet_name]
sheet.cell(i, 7).value = value
wb.save(self.file_name)
if __name__ == '__main__':
test_data = HttpExcel('test_api.xlsx', 'python').real_excel()
print(test_data) # 遍历的就是我们上面 test_data 的数据
二、多个EXCEL执行用例
如果是:注册、登录、充值分别都在不同的表单里面:去遍历这些个用例,结果写回返回值。
register:
login:
recharge:
执行ddt:
import unittest
from class_api_login_topup.demo import http_request
from class_api_login_topup.http_attr import Get_Attr
from test_tools.common.pubilc.real_excel import Excel
from ddt import ddt, data, unpack
from test_tools.common.conf.path_class import * # 读取路径
test_data = Excel.read_excel(test_xlsx)
# test_xlsx 执行xlsx文件的路径
@ddt
class Http_Api(unittest.TestCase):
def setUp(self) -> None:
pass
@data(*test_data)
def test_api(self, item): # 列表嵌套字典的数据格式进来
print("正在测试的是:{0}".format(item['meg']))
res = http_request().request(item['url'], eval(item['data']), item['method'], getattr(Get_Attr, 'cookies'))
if res.cookies:
setattr(Get_Attr, 'cookies', res.cookies)
try:
self.assertEqual(str(item['expected']), res.json()['code'])
TestResult = 'PASS' # 成功的
except AssertionError as e:
print('执行用例出错:{}'.format(e))
TestResult = 'Failed' # 失败的
raise e
finally:
Excel.write_back(test_xlsx, item['sheet_name'], item['mode']+1, str(res.json()), str(TestResult))
#item['sheet_name'] 执行的文件
print("请求的结果是:{0}".format(res.json()))
def tearDown(self) -> None:
pass
二、config文件里面配置
[MODE]
mode={"login":"all",
"register":[1,2],
"recharge":[1,2]}
执行的就是:登录的全部用例还有和注册的第一条和第二条用例
三、读取config的类
import configparser
from test_tools.common.conf.path_class import *
class ReadConfig():
@staticmethod
def get_cinfig(file_name, section, option):
cf = configparser.ConfigParser()
cf.read(file_name, encoding='utf-8')
return cf.get(section, option)
# return cf[section][option]
if __name__ == '__main__':
cf = ReadConfig.get_cinfig(case_config_data, 'MODE', 'mode')
print(cf)
四、读取和写入excel的类
import openpyxl
from test_tools.common.conf.path_class import *
from test_tools.common.pubilc.real_config import ReadConfig
class Excel:
@staticmethod
def read_excel(file_name):
wb = openpyxl.load_workbook(file_name)
mode = eval(ReadConfig.get_cinfig(case_config_data, 'MODE', 'mode')) # 获取config文件里面的数据 eval 还原的字典类型
test_data = []
for key in mode: # 遍历存在配置文件的字典 login 登录,register 注册 ,recharge 充值
sheet = wb[key] # 表单名
if mode[key] == 'all':
for i in range(2, sheet.max_row+1):
sub_test = {}
sub_test['mode'] = sheet.cell(i, 1).value
sub_test['url'] = sheet.cell(i, 2).value
sub_test['data'] = sheet.cell(i, 3).value
sub_test['method'] = sheet.cell(i, 4).value
sub_test['expected'] = sheet.cell(i, 5).value
sub_test['meg'] = sheet.cell(i, 6).value
sub_test['sheet_name'] = key # 方便执行不同的文件
test_data.append(sub_test)
else:
for case_id in mode[key]:
sub_test = {}
sub_test['mode'] = sheet.cell(case_id+1, 1).value
sub_test['url'] = sheet.cell(case_id+1, 2).value
sub_test['data'] = sheet.cell(case_id+1, 3).value
sub_test['method'] = sheet.cell(case_id+1, 4).value
sub_test['expected'] = sheet.cell(case_id+1, 5).value
sub_test['meg'] = sheet.cell(case_id+1, 6).value
sub_test['sheet_name'] = key # 方便执行不同的文件
test_data.append(sub_test)
return test_data
@staticmethod
def write_back(file_name, sheet_name, i, result, TestResult): # 把测试结果写入到EXCEL文件中 I 行数, result 返回结果值保存, TestResult PASS或Failed
wb = openpyxl.load_workbook(file_name)
sheet = wb[sheet_name]
sheet.cell(i, 7).value = result
sheet.cell(i, 8).value = TestResult
wb.save(file_name)
if __name__ == '__main__':
data = Excel.read_excel(test_xlsx)
print(data)
五、执行unittest
from test_tools.common.pubilc.requests_class import Http_Api
from test_tools.common.conf.path_class import *
import unittest
import HTMLTestRunner
suite = unittest.TestSuite()
loder = unittest.TestLoader()
suite.addTest(loder.loadTestsFromTestCase(Http_Api))
with open(test_run, 'wb') as file:
runner = HTMLTestRunner.HTMLTestRunner(stream=file, verbosity=2)
runner.run(suite)
执行结果:
六、实现EXCEL的可配置化、数据的参数化。
1,利用config的类,定义一个可控的配置 :
首先遍历注册接口,其他接口不处理
[MODE]
test={'login':[],'register':'all','recharge':[]}
2,EXCEL的修改,注册的接口中的手机号${tel_1}替换为sheet中tel的手机号,tel替换为sheet中的手机号+1,再存到sheet中去作为下一次的调用
代码如下:EXCEL类,利用字符串函数查找数据
import openpyxl
from class_api_tow.config_class import read_config
from class_api_tow.Tel import DataTel
import pandas as pd
class DoExcel():
@classmethod
def doexcel(cls, fine_name):
# tel = getattr(DataTel, 'data')
tel = pd.read_excel('test_data.xlsx', sheet_name='sheet').loc[0, ['tel']].values[0]
wb = openpyxl.load_workbook(fine_name)
test_data = []
res = eval(read_config('excel_config', 'MODE', 'test'))
for key in res:
sheet = wb[key]
if res[key] == 'all': # 遍历全部
for i in range(2, sheet.max_row + 1):
row_data={}
row_data['mode'] = sheet.cell(i, 1).value
row_data['url'] = sheet.cell(i, 2).value
# row_data['data'] = sheet.cell(i, 3).value
if sheet.cell(i, 3).value.find('${tel_1}') != -1:
row_data['data'] = sheet.cell(i, 3).value.replace('${tel_1}', str(tel))
elif sheet.cell(i, 3).value.find('${tel}') != -1:
row_data['data'] = sheet.cell(i, 3).value.replace('${tel}', str(tel+1))
else:
row_data['data'] = sheet.cell(i, 3).value
row_data['method'] = sheet.cell(i, 4).value
row_data['expected'] = sheet.cell(i, 5).value
row_data['sheet_name'] = key
test_data.append(row_data)
# DoExcel.write_tel(fine_name, tel+1)
cls.write_tel(fine_name, tel+1) # 调用类方法
else:
for mode in res[key]: # 按照case_id的取值来遍历用例
row_data = {}
row_data['mode'] = sheet.cell(mode+1, 1).value
row_data['url'] = sheet.cell(mode+1, 2).value
if sheet.cell(mode, 3).value.find('${tel}') != -1:
row_data['data'] = sheet.cell(mode, 3).value.replace('${tel}', str(tel))
elif sheet.cell(mode, 3).value.find('${tel_1}') != -1:
row_data['data'] = sheet.cell(mode, 3).value.replace('${tel}', str(tel+1))
else:
row_data['data'] = sheet.cell(mode, 3).value
row_data['method'] = sheet.cell(mode+1, 4).value
row_data['expected'] = sheet.cell(mode+1, 5).value
row_data['sheet_name'] = key
test_data.append(row_data)
DoExcel.write_tel(fine_name, tel+1)
return test_data
@staticmethod
def write_back(fine_name, sheet_name, i, value, TestResult):
wb = openpyxl.load_workbook(fine_name)
sheet = wb[sheet_name]
sheet.cell(i, 7).value = value
sheet.cell(i, 8).value = TestResult
wb.save(fine_name)
@classmethod # 写回手机号的新数据
def write_tel(cls, fine_name, value):
wb = openpyxl.load_workbook(fine_name)
sheet = wb['sheet']
sheet.cell(2, 1).value = value
wb.save(fine_name)
@staticmethod
def readopxl(fine_name):
wb = openpyxl.load_workbook(fine_name)
sheet = wb['register']
res = sheet.cell(2, 3).value
return res
if __name__ == '__main__':
test_data = DoExcel.doexcel(r'E:\wk\project\class_api_tow\test_data.xlsx')
print(test_data)
3,ddt代码和运行代码
from class_api.class_chushi import Http_Ruests
import unittest
from class_api.class_demo_fanshe import GetData # 方案二
from ddt import ddt, data, unpack
from class_api_tow.doexcel import DoExcel
from learning_wk.login_class.login_wk import My_log
my_logger = My_log()
test_data = DoExcel.doexcel('test_data.xlsx')
@ddt
class Http_Requests(unittest.TestCase):
@data(*test_data)
def test_login_True(self, item):
res = Http_Ruests().login_requests(item['url'], eval(item['data']), item['method'], getattr(GetData, 'cookies'))
if res.cookies:
setattr(GetData, 'cookies', res.cookies) # 方案二
try:
self.assertEqual(str(item['expected']), res.json()['code'])
test_result = 'PASS'
except AssertionError as e:
test_result = 'failed'
my_logger.info("执行用例出错 {}".format(e))
# print("执行用例出错 {}".format(e))
raise e
finally:
DoExcel.write_back('test_data.xlsx', item['sheet_name'], item['mode'] + 1, str(res.json()), test_result)
my_logger.error("获取到的结果是:{}".format(res.json()))
print(res.json())
suite:
import unittest
import HTMLTestRunner
suite = unittest.TestSuite()
loader = unittest.TestLoader()
from class_api_tow.class_demo_1 import Http_Requests
suite.addTest(loader.loadTestsFromTestCase(Http_Requests))
with open('data.html', 'wb') as file:
runner = HTMLTestRunner.HTMLTestRunner(stream=file, verbosity=2, title=None, description=None)
runner.run(suite)
一行代码搞定unittest运行机制:
替换unittest的三行代码:
case_lib 为模块名字!
例如:from interface_auto_lib import case_lib
suite = unittest.TestSuite()
loader = unittest.TestLoader()
suite.addTest(loader.loadTestsFromModule(case_lib))
suite = unittest.defaultTestLoader.discover(r'路径模块名,不需要.py')