1. 程式人生 > >自動化測試實戰技巧:「用例失敗重試機制」實現方案分享

自動化測試實戰技巧:「用例失敗重試機制」實現方案分享

![](https://tva1.sinaimg.cn/large/007S8ZIlgy1gfyokxzffsj30x80j0n63.jpg) # 1. 背景說明 在開展自動化測試工作時,經常會由於一些外在原因(如網路中斷、返回超時)導致自動化測試用例執行失敗,而這些失敗並不是用例本身驗證或被測程式存在Bug而引起的,更可氣的是這些失敗場景有可能還是偶發的,為了保證**測試用例執行的穩定性**和**驗證有效性**,我們需要一種針對失敗用例重試的執行機制。 今天給大家分享的主題:**自動化測試工作中,用例指令碼失敗重試機制的實現方式。** 結合自動化測試框架來講,用例執行失敗重試機制,通常有三種形式來實現: - 藉助依賴框架自身是否有用例失敗重試執行機制。 - 從用例指令碼自身邏輯處入手,實現失敗執行重試。(適用於被特殊處理過的用例邏輯) - 從擴充套件框架原始碼,自定義失敗重試執行機制。(通常適合於所有失敗用例) 接下來,我們以`Robot Framework`框架為例,以具體的實戰示例專案介紹如何實現用例失敗重試機制。 # 2. 示例專案環境搭建 為了便於演示,重新建立一套新的虛擬隔離環境,用於搭建`Robot Framework`框架,操作步驟如下。 1、建立虛擬環境`robotframework_env` ```shell python3 -m venv robotframework_env ``` 2、啟用虛擬環境 ```shell cd robotframework_env source bin/activate ``` 3、在虛擬環境中,安裝robotframework、robotframework-ride庫(安裝最新即可)。 ```shell pip install robotframework pip install robotframework-ride ``` 如下圖所示: ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1gfyufh8meij31820iotp0.jpg) 4、 輸入命令:`bin ./ride.py`啟動RIDE,如下圖所示。 ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1gfymcsk0vlj314d0u04np.jpg) > PS: 其它三方庫演示專案中,暫不需要,讀者可根據實際需求,自行安裝。 # 3. 建立實戰示例專案 1、 建立`trainning`演示專案,並在專案下,建立`失敗重試機制實戰目錄`,並依次建立測試套件、測試用例,示例結構如下: ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1gfymly9gnsj30la08qdhc.jpg) 2、 編寫測試用例,測試用例邏輯如下: ```python *** Settings *** Library Collections *** Test Cases *** Class_01_隨機取數,模擬隨機出現失敗場景 @{list}= create list 1 2 3 ${random_num}= Evaluate random.choice(${list}) random log ${random_num} should be true ${random_num}==2 ``` - 在測試用例中,先通過`create list`關鍵字建立了一個名稱為${list}的列表變數,並依次存入1、2、3三個元素。 - 再通過`Evaluate`萬能關鍵字,結合`random.chocie`方法,從${list}列表中隨機取出一個整型元素,儲存到名稱為${random_num}變數中。 - 最後,通過`should be true`關鍵字,斷言${random_num}變數等於2,由於第二步的隨機取值,會讓${random_num}變數值具有隨機性(可能等於2,也可能是1或3),從而實現模擬一條隨機失敗的用例場景。 執行成功結果: ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1gfyofg7lr6j31mx0u0gww.jpg) 執行失敗結果: ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1gfyofza3scj31lc0u0k2q.jpg) # 4. 用例失敗重試機制實現 Robot Framework 官方並沒有提供類似retry等引數來配置失敗用例重執行。僅僅提供了`--rerunfailed`引數對基於結果檔案output.xml來選擇重新執行失敗的用例。 ### 4.1 基於RF框架自身的重試機制 1、 以第3節中新建的示例專案為例,為了便於演示,以命令列來操作,在命令列中輸入執行用例命令,並且將輸出檔案儲存到`original.xml`檔案中。 ```shell robot --output original.xml . ``` ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1gfypntkaazj31740no797.jpg) 2、 重新執行測試用例,並將第二次執行的結果檔案輸出儲存到`rerun.xml`檔案中。 ``` robot --output rerun.xml --rerunfailed original.xml . ``` ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1gfyppej4muj316e0m4aet.jpg) 3、合併兩次執行的結果輸出檔案。 ``` rebot --merge original.xml rerun.xml ``` ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1gfypr7gxx4j31mo0l8wjv.jpg) 在Robot Framework中除了有`--rerunfailed`引數針對失敗的測試用例外,也有針對測試套件的`--rerunfailedsuites`,引數詳細說明如下: ```shell -R --rerunfailed output Select failed tests from an earlier output file to be re-executed. Equivalent to selecting same tests individually using --test option. ------------------------------------------------ -S --rerunfailedsuites output Select failed suite from an earlier output file to be re-executed. New in RF 3.0.1. ``` - `-R`或`--rerunfailed`引數非常有用,它的作用是從output file中選擇失敗的用例重跑。但是有個問題,如果上一次執行時用例全部成功,此時加上-R引數再去執行用例時會報錯: failed: All tests passed ,這導致我沒辦法在jenkins job中使用這個引數。 - `-S`或`--rerunfailedsuites`引數和-R引數的作用類似,它的作用是從output file中選擇失敗的用例套件重跑。 ### 4.2 基於用例指令碼邏輯重試機制 第二種方法,我們介紹,如何基於用例指令碼邏輯特殊改造,實現用例失敗後的重試機制。 基於用例邏輯增加重試機制,核心實現思路:**基於RF內建變數`${TEST_STATUS}`獲取用例執行結果,再結合`Teardown`執行改造後的關鍵字邏輯即可。** 操作如下: 1、對示例1中的`Class_01 `測試用例進行改造,抽取用例邏輯部分,存放到單獨的關鍵字下,名稱如`測試用例關鍵字`。 ```python *** Keywords *** 測試用例關鍵字 @{list}= create list 1 2 2 ${random_num}= Evaluate random.choice(${list}) random log ${random_num} should be true ${random_num}==2 ``` 2、 新增關鍵字`用例重試機制`,增加用例重試機制的處理邏輯: ```python *** Keywords *** 用例重試機制 [Arguments] ${times} ${status}= set variable ${TEST STATUS} FOR ${index} IN RANGE ${times} log 第${index+1}執行結果: ${status} Exit For loop if '${status}'=='PASS' or '${status}'=='True' log 第${index+1}次重試執行 ${status}= Run keyword And Return Status 測試用例關鍵字 END ``` 在`用例重試機制`關鍵字中,先通過`${TEST STATUS}`內建變數,獲取用例執行結果,並且接收變數${times}用於控制重試次數,如果用例執行狀態等於`PASS`則直接退出重試,否則呼叫`Run keyword And Return Status`關鍵字繼續執行測試用例。 3、為了便於演示,增加一條名稱為`Class_02`測試用例,內容如下: ```python Class_02_隨機取數,模擬隨機出現失敗場景 測試用例關鍵字 [Teardown] run keyword 用例重試機制 5 ``` 到此, 我們已經在用例邏輯層面實現了用例失敗重試機制了。 > PS: 針對用例邏輯層面實現重試機制,也可以採用關鍵字: Wait Until Keyword Succeeds,讀者可根據自身需求進行改造,本文的用例重試機制並不是唯一的方法。 ### 4.3 基於框架原始碼實現重試機制 除了上述兩種方法,最後一種方法是基於框架層面進行改造,增加全域性重試機制, 通過改寫`Robot Framework`原始碼增加`--retry`選項,實現test級別的失敗用例自動再執行,比如用例失敗後,會重新執行N次,直至成功or 耗盡重試次數,生成的日誌和報告檔案中只會體現最後一次執行的結果。 類似如下命令格式: ``` robot --retry 3 trainning ``` **具體實現:** 1、修改檔案 : `robotframework_env/lib/python3.7/site-packages/robot/run.py`,在USAGE變數裡新增`retry`引數。 ```powershell -F --extension value Parse only files with this extension when executing a directory. Has no effect when running individual files or when using resource files. If more than one extension is needed, separate them with a colon. Examples: `--extension txt`, `--extension robot:txt` New in RF 3.0.1. Starting from RF 3.2 only `*.robot` files are parsed by default. -N --name name Set the name of the top level suite. By default the name is created based on the executed file or directory. -H --retry retry   Set the retry times if test failed. ``` 2、在run.py檔案,`RobotFramework`類增加`make`方法,並在開始之前匯入庫`from xml.dom import minidom`。 ```python def make(self, outxml): xmldoc = minidom.parse(outxml) suiteElementList = xmldoc.getElementsByTagName('suite') mySuite = [] for suiteElement in suiteElementList: if suiteElement.childNodes is not None: for element in suiteElement.childNodes: if element.nodeName == 'test': mySuite.append(suiteElement) break for suite in mySuite: testElements = {} for element in suite.childNodes: if element.nodeName == 'test': name = element.getAttribute('name') if testElements.get(name) == None: testElements.update({name: [element]}) else: testElements.get(name).append(element) for n, el in testElements.items(): for i in el[0:-1]: textElement = i.nextSibling suite.removeChild(i) suite.removeChild(textElement) savefile = open(outxml, 'w') root = xmldoc.documentElement root.writexml(savefile) savefile.close() ``` 3、`RobotFramework`類的`main`方法,加入紅色內容 `self.make(settings.output)` ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1gfytffxc70j312x0u0n9g.jpg) 4、 開啟robot/conf/setting.py檔案,修改_cli_opts字典,增加`'Retry': ('retry', 3),`,如下所示: ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1gfyth6qo7ej31ep0u07b6.jpg) 5、開啟`robot/model/itemlist.py`檔案,修改visit方法: ```python def visit(self, visitor): for item in self: if self.__module__ == 'robot.model.testcase' and hasattr(visitor, "_context"): testStatus = '' for i in range(0, int(visitor._settings._opts['Retry'])): if testStatus != 'PASS': if item.name in visitor._executed_tests: visitor._executed_tests.pop(item.name) item.visit(visitor) testStatus = visitor._context.variables['${PREV_TEST_STATUS}'] else: break else: item.visit(visitor) ``` 6、做完如上配置之後,我們來驗證一下引數是否配置成功了,輸入`robot —help`檢視一下配置引數項。 ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1gfytk187uoj31em0t2tgh.jpg) 7、 輸入如下命令,結合`Class_01`用例,驗證用例失敗重試機制: ```shell robot --test Class_01_隨機取數,模擬隨機出現失敗場景 --retry 3 . ``` ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1gfytseauz6j312i0u0tmo.jpg) 如果測試用例執行結果為PASS,執行一次即正常結束,如果用例執行失敗,則會重試3次執行。 # 5. 小結 本文以`Robot Framework`框架為例,介紹了在自動化測試過程中,如何實現用例指令碼失敗重試機制,並且分享了三類實現思路: - 藉助依賴框架自身是否有用例失敗重試執行機制。 - 從用例指令碼自身邏輯處入手,實現失敗執行重試。(適用於被特殊處理過的用例邏輯) - 從擴充套件框架原始碼,自定義失敗重試執行機制。(通常適合於所有失敗用例) 認真品味本文的讀者,會發現,雖然本文內容是以`Robot Framework`框架為例,但其實任何自動化測試框架,要實現測試用例指令碼重試機制,都繞不開本文所提到的三類實現方式思路。**`學會變通、靈活運用才是王道`**。 希望對大家在實施自動化測試工作當中有所幫助或啟發!如果覺得有用,`不用以身相許,關注一下就行`。 原文傳送門: [原文閱讀](https://mp.weixin.qq.com/s/NycW75Ef1NDPRlmo