安装:
pip install ddt
1、ddt的原理:[Data driver test]
ddt其实是一个装饰器
ddt可以完成什么操作?
有了ddt它会根据你传递进来的数据来决定要生成几个测试用例
模块导入
from ddt import ddt, data
主要知识点:
ddt 装饰器测试类
data 装饰测试用例
#功能函数
users = [{'user': 'python18', 'password': '123456'}] def register(username, password1, password2): # 注册功能 for user in users: # 遍历出所有账号,判断账号是否存在 if username == user['user']: # 账号存在 return {"code": 0, "msg": "该账户已存在"} else: if password1 != password2: # 两次密码不一致 return {"code": 0, "msg": "两次密码不一致"} else: # 账号不存在 密码重复,判断账号密码长度是否在 6-18位之间 if 6 <= len(username) >= 6 and 6 <= len(password1) <= 18: # 注册账号 users.append({'user': username, 'password': password2}) return {"code": 1, "msg": "注册成功"} else: # 账号密码长度不对,注册失败 return {"code": 0, "msg": "账号和密码必须在6-18位之间"}
# 打开excle的方法
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 time import unittest from register import register from read_excle02 import ReadExcle from Day15_2020_03_06.test_project.ddt import ddt, data """ ddt:能够实现数据驱动:通过用例数据,自动生成测试用例 自动遍历用例数据,去生成测试用例, 没遍历出来一条用例的数据,会当成一个参数,传到生成的用例中去 """ @ddt class RegisterTestCase(unittest.TestCase): excle = ReadExcle("cases.xlsx", 'register') cases = excle.read_data_obj() @data(*cases) def test_register(self, case): # 第一步 准备用例数据 # 获取用例的行号 row = case.case_id + 1 # 获取预期结果,eval字符串换行为列表 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=5, value="未通过") raise e else: self.excle.write_data(row=row, column=5, value="通过")
# 执行测试用例
import unittest import test_cases from HTMLTestRunnerNew import HTMLTestRunner # 创建测试套件 suite = unittest.TestSuite() # 加载用例用例到套件 loader = unittest.TestLoader() suite.addTest(loader.loadTestsFromModule(test_cases)) with open('zy_report.html', 'wb') as fb: # 创建测试运行程序 runner = HTMLTestRunner(stream=fb, title='测试报告', description='第一份报告作业', tester='hc') # 执行测试套件中的用例 runner.run(suite)