# config文件封装
# 对配置文件进行封装
# 导入配置文件模块
from configparser import ConfigParser
# 创建一个配置文件类
class HandleConfig:
"""
处理配置文件
"""
# 定义一个实例属性
def __init__(self,filename):
# 定义一个名称:filename实例属性
self.filename = filename
# 创建配置解释器config对象
self.config = ConfigParser()
# 指定读取的配置文件, 无需变量接收读取内容
self.config.read(self.filename,encoding="utf8")
# 定义一个获取配置文件数据的实例方法,获取配置文件中对应不同数据类型的值
# get方法和字典中的get有区别
# 第一个参数section为区域名,第二个参数option为选项名
# 从配置文件中,使用索引(方括号)或者使用get方法,读取出来的所有数据都是字符串类型
def get_value(self,section,option):
# 通过定义的实例属性self.config对象,调用ConfigParser类中的get方法,并将结果进行返回
return self.config.get(section,option)
# 可以使用getint(区域名,选项名)只能读取int类型的数据,否则会报错
def get_int(self,section,option):
return self.config.getint(section,option)
# 可以使用getfloat(区域名,选项名)只能读取int类型和浮点类型的数据,否则会报错
def get_float(self,section,option):
return self.config.getfloat(section,option)
# 可以使用getboolean(区域名,选项名)来读取布尔类似的数据
def get_boolean(self,section,option):
return self.config.getboolean(section,option)
# 通过eval函数对get获取的字符串进行转义,获取配置文件中不同的数据类型
def get_eval_data(self,section,option):
return eval(self.config.get(section, option))
# 定义写入配置文件的静态方法:
# 为什么不能定义在内属性,内属性是每个对象的公共资源,每个对象都可以访问
# 读配置和写配置都用相同的对象,读配置和写配置尽量不要用相同的对象
@staticmethod
# 定义write_config方法
# datas里面传入需要写入的数据,往往是一个嵌套字典的格式
# filename是文件名
def write_config(datas,filename):
# 创建一个config对象,可以用来调用ConfigParser类中的方法
config = ConfigParser()
# 在空配置config中写入配置
# config还没有读取数据时,可以类似一个空字典
# datas是需要写入的数据
for key in datas:
config[key] = datas[key]
with open(filename,"w",encoding="utf8") as file:
config.write(file)
# 定义do_config对象,用来调用HandleConfig类中的方法
# testcase.conf为对应的文件名称
do_config = HandleConfig("testcase.conf")
# 魔法变量
if __name__ == "__main__":
# 创建do_config类的对象
do_config = HandleConfig("testcase.conf")
# 需要写入到配置文件的数据
datas = {
"excel": {
"cases_path": "cases.xlsx"
},
"user": {
"username": "hc",
"password": "123456"
}
}
# 通过do_config对象调用write_config静态方法,将datas数据写入到write_cases.ini文件中
do_config.write_config(datas,"write_cases.ini")
pass
# 读取excel文件的封装
import openpyxl
class CaseData:
"""测试用例数据类,专门用来创建对象,存放用例数据"""
pass
class ReadExcle(object):
def __init__(self, filename, sheetname):
self.filename = filename
self.sheetname = sheetname
def open(self):
"""打开工作表和表单"""
self.wb = openpyxl.load_workbook(self.filename)
self.sh = self.wb[self.sheetname]
def read_data(self):
"""读取数据的方法"""
# 打开工作簿和表单
self.open()
# 将表单中的内容,按行获取所有的格子
rows = list(self.sh.rows)
# 创建一个空列表,用例存放所有的用例数据
cases = []
# 获取表头,放到一个列表中
title = [c.value for c in rows[0]]
# 获取除表头以外的其他行中的数据
for r in rows[1:]:
# 每遍历一行,创建一个列表,用例存放该行的数据
data = [c.value for c in r]
# 将表头和该行的数据进行聚合打包,转换字典
case_data = dict(zip(title, data))
# 将该行的用例数据加入到cases这个列表中
cases.append(case_data)
# 关闭工作簿对象
self.wb.close()
# 将读取好的数据返回出去
return cases
def read_data_obj(self):
"""读取数据的方法,数据返回的是列表嵌套对象的形式"""
# 打开工作簿和表单
self.open()
# 将表单中的内容,按行获取所有的格子
rows = list(self.sh.rows)
# 创建一个空列表,用例存放所有的用例数据
cases = []
# 通过列表推导式获取表头,放到一个列表中
title = [c.value for c in rows[0]]
# 获取除表头以外的其他行中的数据
for r in rows[1:]:
# 通过列表推导式,获取改行的数据,放到一个列表中
data = [c.value for c in r]
# 创建一个用例数据对象
case = CaseData()
# 将表头和该行的数据进行聚合打包,然后进行遍历
for i in zip(title, data):
# 通过反射机制,将表头设为对象属性,对应值设为对象的属性值
setattr(case, i[0], i[1])
# 将该行的用例数据加入到cases这个列表中
cases.append(case)
# 关闭工作薄
self.wb.close()
# 将读取好的数据返回出去
return cases
def write_data(self, row, column, value):
"""写入数据"""
# 打开工作簿和表单
self.open()
# 写入内容
self.sh.cell(row=row, column=column, value=value)
# 保存文件
self.wb.save(self.filename)
# 关闭工作簿
self.wb.close()
if __name__ == '__main__':
read = ReadExcle('cases.xlsx', 'register')
# 读取
# data = read.read_data_obj()
# print(data)
# read.write_data(2, 4, '通过')
# read.write_data(3, 4, '未通过')
# 获取日志封装
import logging
from Day17_2020_03_11.Python_1102_handle_config.handle_yaml import do_yaml
class MyLogger(object):
@classmethod
def create_logger(cls):
"""创建日志收集器"""
# 创建一个日志收集器
my_log = logging.getLogger(do_yaml.read("log", "log_name"))
# 设置日志收集器的收集等级
my_log.setLevel(do_yaml.read("log", "logger_level"))
# 设置日志输出的格式
formater = logging.Formatter(do_yaml.read("log", "formatter"))
# 创建一个输出导控制台的日志输出渠道
sh = logging.StreamHandler()
sh.setLevel(do_yaml.read("log", "stream_level"))
# 设置输出导控制台的格式
sh.setFormatter(formater)
# 将输出渠道添加到日志收集器中
my_log.addHandler(sh)
# 创建一个输出导文件的渠道
fh = logging.FileHandler(filename=do_yaml.read("log", "logfile_name"),
encoding='utf8')
fh.setLevel(do_yaml.read("log", "logfile_level"))
# 设置输出导文件的日志格式
fh.setFormatter(formater)
# 将输出渠道添加到日志收集器中
my_log.addHandler(fh)
return my_log
do_log = MyLogger.create_logger()
# yaml读取配置文件信息封装
import yaml
class HandleYaml:
def __init__(self, filename):
with open(filename, encoding="utf-8") as one_file:
self.datas = yaml.full_load(one_file)
def read(self, section, option):
"""
读数据
:param section: 区域名
:param option: 选项名
:return:
"""
return self.datas[section][option]
@staticmethod
def write(datas, filename):
"""
写数据
:param datas: 嵌套字典的字典
:param filename: yaml文件路径
:return:
"""
with open(filename, mode="w", encoding="utf-8") as one_file:
yaml.dump(datas, one_file, allow_unicode=True)
do_yaml = HandleYaml("testcase01.yaml")
if __name__ == '__main__':
do_yaml = HandleYaml("testcase01.yaml")
datas = {
"excel": {
"cases_path": "cases.xlsx",
"result_col": 5
},
"msg": {
"success_result": "通过",
"fail_result": "Fail"
}
}
do_yaml.write(datas, "write_datas.yaml")
pass
# 测试用例类:test_cases
import unittest
from Day17_2020_03_11.Python_1102_handle_config.register import register
from Day17_2020_03_11.Python_1102_handle_config.handle_excel import ReadExcle
from Day17_2020_03_11.Python_1102_handle_config.ddt import ddt, data
from Day17_2020_03_11.Python_1102_handle_config.handle_yaml import do_yaml
from Day17_2020_03_11.Python_1102_handle_config.handle_log import do_log
@ddt
class RegisterTestCase(unittest.TestCase):
# excle = ReadExcle("cases.xlsx", 'register')
excle = ReadExcle(do_yaml.read("excel", "cases_path"), 'register')
cases = excle.read_data_obj()
@data(*cases)
def test_register(self, case):
# 第一步 准备用例数据
# 获取用例的行号
row = case.case_id + 1
# 获取预期结果
excepted = eval(case.excepted)
# 获取用例入参
data = eval(case.data)
# 第二步: 调用功能函数,获取实际结果
res = register(*data)
# 第三步:比对预期结果和实际结果
try:
self.assertEqual(excepted, res)
except AssertionError as e:
self.excle.write_data(row=row,
column=do_yaml.read("excel", "result_col"),
value=do_yaml.read("msg", "fail_result"))
# do_log.error("断言异常: {}".format(e))
do_log.error(f"断言异常: {e}")
raise e
else:
self.excle.write_data(row=row,
column=do_yaml.read("excel", "result_col"),
value=do_yaml.read("msg", "success_result"))
# 测试运行程序:run_test
import unittest
# 导入模块的快捷键:alt + enter
from datetime import datetime
from Day17_2020_03_11.Python_1102_handle_config import test_cases
from Day17_2020_03_11.Python_1102_handle_config.HTMLTestRunnerNew import HTMLTestRunner
from Day17_2020_03_11.Python_1102_handle_config.handle_yaml import do_yaml
# 创建测试套件
suite = unittest.TestSuite()
# 加载用例用例到套件
loader = unittest.TestLoader()
suite.addTest(loader.loadTestsFromModule(test_cases))
result_full_path = do_yaml.read('report', 'name') + '_' +
datetime.strftime(datetime.now(), '%Y%m%d%H%M%S') + '.html'
with open(result_full_path, 'wb') as fb:
# 创建测试运行程序
runner = HTMLTestRunner(stream=fb,
title=do_yaml.read('report', 'title'),
description=do_yaml.read('report', 'description'),
tester=do_yaml.read('report', 'tester'))
# 执行测试套件中的用例
runner.run(suite)