ddt源碼修改:HtmlTestRunner報告依據接口名顯示用例名字

背景是這樣的:python

  本身寫了一套接口自動化的框架,其中使用unittest + ddt + excel做爲數據驅動模式的應用,使用HtmlTetstRunner來生成測試用例。api

        一切看起來很完美。app

        可是,發現測試報告中,測試用例名稱都是:test_api_index.index表示用例的編號,從1開始,遞增。好比:test_api_0一、test_api_02......test_api_0N框架

        但願能在不一樣的用例名稱當中,顯示相應的接口用例名字。好比登錄接口的成功登錄用例:測試報告中用例名稱顯示爲test_login_success。密碼錯誤的用例名稱爲:test_login_wrongPasswdide

        這樣,我直接從報告中就能夠知道是哪一個接口的哪一個用例失敗了,一目瞭然。函數

       因而,就開始琢磨這事兒了。。。單元測試

 

======================================背景分割線==================================測試

 

        一琢磨就琢磨到ddt源碼上去了。心中有一個疑惑:spa

       一、爲何個人測試用例名稱是這樣的??scala

        查看了ddt源碼以後,發現有個函數是用來生成測試用例名字的。這個函數叫:mk_test_name

  它是如何來生成測試用例名字的呢?

        它接受兩個參數:name 和 value.

         name:爲單元測試中,測試用例的名字。即test_api.

         value:爲測試數據。ddt是處理一組測試數據。而這個value就是這一組數據中的每個測試數據。

                     對value的值是有限制的:要麼就是單值變量,要麼就是元組或者列表而且要求元組和列表中的數據都是單值變量。如("name","port") 、["name","port"]

         若是傳進來的測試數據,不符合value的要求,那麼測試用例名字爲:name_index。

         若是傳進來的測試數據,符合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

       ddt源碼以下(紅色粗體部分標識):

 1 def mk_test_name(name, value, index=0):
 2     """
 3     Generate a new name for a test case.
 4  
 5     It will take the original test name and append an ordinal index and a
 6     string representation of the value, and convert the result into a valid
 7     python identifier by replacing extraneous characters with ``_``.
 8  
 9  We avoid doing str(value) if dealing with non-trivial values. 10     The problem is possible different names with different runs, e.g.
11     different order of dictionary keys (see PYTHONHASHSEED) or dealing
12     with mock objects.
13     Trivial scalar values are passed as is.
14  
15  A "trivial" value is a plain scalar, or a tuple or list consisting 16 only of trivial values. 17     """
18     
19     # Add zeros before index to keep order
20     index = "{0:0{1}}".format(index + 1, index_len)
21 if not is_trivial(value): #若是不符合value的要求,則直接返回用例名稱_下標做爲最終測試用例名字。 22 return "{0}_{1}".format(name, index) 23     try:
24         value = str(value)
25     except UnicodeEncodeError:
26         # fallback for python2
27         value = value.encode('ascii', 'backslashreplace')
28     test_name = "{0}_{1}_{2}".format(name, index, value) 29     return re.sub(r'\W|^(?=\d)', '_', test_name)

 

        

       二、修改ddt源碼,顯示測試用例名字

       爲了讓個人測試報告,呈現的更好。那就改改ddt源碼,讓它可以適應個人框架。

       考慮兩個問題:

        一、不一樣接口的測試用例名字如何來??

        二、如何讓ddt支持對字典的處理??

        解決方法:

        第一個問題:每個測試用例主動提供一個用例名字,說明你是什麼接口的什麼場景用例。好比:接口名_場景名。login_success、login_noPasswd、login_wrongPasswd等。

        在個人框架當中,每個測試用例是一個字典。那麼我就在字典中添加一個鍵值對,case_name=用例名稱

  第二個問題:在ddt中添加對字典的處理,若是字典中有case_name字段,則將字典中鍵名爲case_name的值做爲測試用例名稱中的value值。

       修改後的ddt源碼爲(紅色粗體部分爲修改的內容):

 1 def mk_test_name(name, value, index=0):
 2 
 3     print("-------first value------------")
 4     print(value)
 5     # Add zeros before index to keep order
 6     index = "{0:0{1}}".format(index + 1, index_len)
 7 #添加了對字典數據的處理。 8 if not is_trivial(value) and type(value) is not dict: 9 return "{0}_{1}".format(name, index) 10 #若是數據是字典,則獲取字典當中的api_name對應的值,加到測試用例名稱中。 11 if type(value) is dict: 12 try: 13 value = value["case_name"] #case_name做爲value值 14 except: 15 return "{0}_{1}".format(name, index) 16     try:
17         value = str(value)
18     except UnicodeEncodeError:
19         # fallback for python2
20         value = value.encode('ascii', 'backslashreplace')
21     test_name = "{0}_{1}_{2}".format(name, index, value)
22 
23     return re.sub(r'\W|^(?=\d)', '_', test_name)

 

 修改完成以後,再次運行接口測試,就能夠在測試報告當中看到對應的用例名字啦。。

相關文章
相關標籤/搜索