使用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)
"