数据驱动思想:data driver testing
ddt是python的一个库
pip install ddt
ddt库是和unittest 搭配起来使用的,是unittest的一个插件
用法
import ddt
在类方法上加,注意这块没有括号
@ddt.ddt
在方法上加,注意这块是有括号的
@ddt.data()
@ddt.ddt
class TestDemo(unittest.TestCase):
@ddt.data()
def test_demo(self):
pass
代码举例:
test_login.py
# test_data = [
# {'url': 'http://localhost:5000/login',
# 'method': 'post',
# 'data': {"mobliephone": '13112341234', 'pwd': '123456'},
# 'headers': {'X-Media-Type': 'test.v2'},
# 'expected': 'hello world'},
#
# {'url': 'http://localhost:5000/login',
# 'method': 'post',
# 'data': {"mobliephone": '123456', 'pwd': '123'},
# 'headers': {'X-Media-Type': 'test.v2'},
# 'expected': 'hello world'}
# ]
# 从excel中读取数据
test_data = ExcelHandler(r'd:\cases.xlsx').read('Sheet1')
print(test_data)
# 继承unittest.TestCase
@ddt.ddt
class TestLogin(unittest.TestCase):
def setUp(self) -> None:
pass
@ddt.data(*test_data)
# 将*test_data当中的一组测试数据,赋值到data_info这个参数,相当for循环
def test_login_success(self, data_info):
res = RequestHandler().visit(method=data_info['method'],
url=data_info['url'],
json=data_info['data'],
header=data_info['headers'])
# 只对某一个字段进行断言
self.assertEqual(res['msg'], self.data['expected'])
# try:
# self.assertEqual(1, 3-2)
# except AssertionError as result:
# print('断言失败', result)
# raise AssertionError
def tearDown(self) -> None:
pass
if __name__ == '__main__':
unittest.main()
使用ddt.data(*test_data)这种方式相当,循环使用测试数据,并且分为多个测试用例,如果不用ddt,用for循环的化,相当于一个测试用例
修改ddt源码,使生成报告的用例名称自定义化,
进入ddt源码,可以看到wrapper这个方法,i 是索引的含义,v是每一行excel里的数据
增加如下代码,在wrapper这个方法里
if isinstance(v, list):
test_name = mk_test_name(name, v[2], i)
elif isinstance(v, dict):
test_name = mk_test_name(name, v['case_name'], i)
def wrapper(cls):
for name, func in list(cls.__dict__.items()):
if hasattr(func, DATA_ATTR):
index_len = getattr(func, INDEX_LEN)
for i, v in enumerate(getattr(func, DATA_ATTR)):
test_name = mk_test_name(
name,
getattr(v, "__name__", v),
i,
index_len,
fmt_test_name
)
if isinstance(v, list):
test_name = mk_test_name(name, v[2], i)
elif isinstance(v, dict):
test_name = mk_test_name(name, v['case_name'], i)
test_data_docstring = _get_test_data_docstring(func, v)
if hasattr(func, UNPACK_ATTR):
if isinstance(v, tuple) or isinstance(v, list):
add_test(
cls,
test_name,
test_data_docstring,
func,
*v
)
else:
# unpack dictionary
add_test(
cls,
test_name,
test_data_docstring,
func,
**v
)
else:
add_test(cls, test_name, test_data_docstring, func, v)
delattr(cls, name)
elif hasattr(func, FILE_ATTR):
file_attr = getattr(func, FILE_ATTR)
process_file_data(cls, name, func, file_attr)
delattr(cls, name)
return cls
然后在execl中新增一个case_name列名
然后生成报告,,诶个用例名字后,就会带上我们自定义的名字
注意:修改源码后,可以再次使用,可以看到ddt.py文件是在site包下面,这是python的第三方库
如果卸载了ddt,重新安装,那么就需要重新修改源码了
一般用的时候建议把ddt.py文件修改后复制到自己的框架中,然后导入自己的ddt.py文件,不要修改源码。