使用ddt作测试,获得的测试报告中,测试用例的名字默认以_01, _02, _03...递增的形式结尾,这时我但愿用例名可以以_api_name结尾,好比注册模块,但愿看到的形式是test_send_requests_01_register...html
这个问题如何解决呢
python
这个方法是从 python ddt 重写 看到的,ddt.mk_test_name重写前的方法为api
# Add zeros before index to keep order index = "{0:0{1}}".format(index + 1, index_len) if not is_trivial(value): return "{0}_{1}".format(name, index) try: value = str(value) except UnicodeEncodeError: # fallback for python2 value = value.encode('ascii', 'backslashreplace') test_name = "{0}_{1}_{2}".format(name, index, value) return re.sub(r'\W|^(?=\d)', '_', test_name)
重写后的方法为app
# Add zeros before index to keep order index = "{0:0{1}}".format(index + 1, index_len) if not is_trivial(value): if type(value) is dict and "api_name" in value.keys(): value = value["api_name"] else: return "{0}_{1}".format(name, index) try: value = str(value) except UnicodeEncodeError: # fallback for python2 value = value.encode('ascii', 'backslashreplace') test_name = "{0}_{1}_{2}".format(name, index, value) return re.sub(r'\W|^(?=\d)', '_', test_name)
本段主要参考《ddt源码修改:HtmlTestRunner报告依据接口名显示用例名字》框架
"查看了ddt源码以后,发现有个函数是用来生成测试用例名字的。这个函数叫:mk_test_nameide
它是如何来生成测试用例名字的呢?函数
它接受两个参数:name 和 value.单元测试
对value的值是有限制的:要么就是单值变量,要么就是元组或者列表而且要求元组和列表中的数据都是单值变量。如("name","port") 、["name","port"]测试
若是传进来的测试数据,不符合value的要求,那么测试用例名字为:name_indexspa
若是传进来的测试数据,符合value的要求,那么测试用例名字为:name_index_value。若是value为列表或者元组,那么将列表/元组的每一个数据依次追加在末尾
好比传进来的name值为test_login,value值为["name","port"]。那最终的测试用例名字是:test_login_01_name_port
若是传进来的name值为test_login,value值为{"name":"login","port":2204},那最终的测试用例名字为:test_login_01。由于它不支持对字典类型的数据处理
很不巧,个人接口自动化框架中,ddt处理的数据是一列表:列表当中每一个数据都为字典。ddt一遍历整个列表,那传给value的值恰好是字典。。
so。。。我获得的测试用例名称就是:test_api_01,test_api_02,test_api_03..........test_api_0N
def mk_test_name(name, value, index=0): """ Generate a new name for a test case. It will take the original test name and append an ordinal index and a string representation of the value, and convert the result into a valid python identifier by replacing extraneous characters with ``_``. We avoid doing str(value) if dealing with non-trivial values. The problem is possible different names with different runs, e.g. different order of dictionary keys (see PYTHONHASHSEED) or dealing with mock objects. Trivial scalar values are passed as is. A "trivial" value is a plain scalar, or a tuple or list consisting only of trivial values. """ # Add zeros before index to keep order index = "{0:0{1}}".format(index + 1, index_len) if not is_trivial(value): #若是不符合value的要求,则直接返回用例名称_下标做为最终测试用例名字。 return "{0}_{1}".format(name, index) try: value = str(value) except UnicodeEncodeError: # fallback for python2 value = value.encode('ascii', 'backslashreplace') test_name = "{0}_{1}_{2}".format(name, index, value) return re.sub(r'\W|^(?=\d)', '_', test_name)
为了让个人测试报告,呈现的更好。那就改改ddt源码,让它可以适应个人框架。
考虑两个问题:
一、不一样接口的测试用例名字如何来??
二、如何让ddt支持对字典的处理??
解决方法:
第一个问题:每个测试用例主动提供一个用例名字,说明你是什么接口的什么场景用例。好比:接口名_场景名。login_success、login_noPasswd、login_wrongPasswd等。在个人框架当中,每个测试用例是一个字典。那么我就在字典中添加一个键值对,case_name=用例名称
第二个问题:在ddt中添加对字典的处理,若是字典中有case_name字段,则将字典中键名为case_name的值做为测试用例名称中的value值
def mk_test_name(name, value, index=0): print("-------first value------------") print(value) # Add zeros before index to keep order index = "{0:0{1}}".format(index + 1, index_len) #添加了对字典数据的处理。 if not is_trivial(value) and type(value) is not dict: return "{0}_{1}".format(name, index) #若是数据是字典,则获取字典当中的api_name对应的值,加到测试用例名称中。 if type(value) is dict: try: value = value["case_name"] #case_name做为value值 except: return "{0}_{1}".format(name, index) try: value = str(value) except UnicodeEncodeError: # fallback for python2 value = value.encode('ascii', 'backslashreplace') test_name = "{0}_{1}_{2}".format(name, index, value) return re.sub(r'\W|^(?=\d)', '_', test_name)
"