重试次数配置_TestNG实践——2.用例失败重试
@Test
用例失敗重跑,retry最終一定是針對測試用例得,一個方法只有被@Test標注了才是測試用例,那么我們看下,@Test注解有沒有相關屬性呢?
retryAnalyzer,就是用于指定失敗重跑得方案得,那么對應TestNG體系里提供了:
1.接口:IRetryAnalyzer
2.實現了接口得抽象類:
public abstract class RetryAnalyzerCount implements IRetryAnalyzer
所以,我們想實現失敗自動重跑得方案就有了:
1.實現IRetryAnalyzer 接口
2.指定@Test得retryAnalyzer為我們得實現類
實現IRetryAnalyzer
我們已經知道IRetryAnalyzer接口有個抽象類RetryAnalyzerCount,那么我們可以自己重新實現IRetryAnalyzer,當然也可以直接繼承RetryAnalyzerCount,這里我們選擇直接繼承RetryAnalyzerCount。
我們的RetryAnalyzer類,設置了重試計數為3,實現retryMethod,始終返回true。
我們看下RetryAnalyzerCount抽象類,它的關鍵是實現了retry方法,count就是重試計數值,獲取count后減一,只要count大于0,看retryMethod方法的返回決定是否重試,只要retry的最后返回是true,就重新運行。
使用RetryAnalyzer
我們的RetryAnalyzer實現了,那么怎么使用呢?
@Test注解中有一個屬性:retryAnalyzer,只要指定我們的重跑類,當case失敗時,就可以觸發重跑了。
我們看到case一共跑了4次,第一次跑完之后,case失敗,于是重試3次,共4次,然后均失敗,那么case最后failure,系統認為重試的case為Skip的,這里的統計這么顯示是有一定道理,當然,測試報告也可以定制,我們后面也會講到,(在早期版本的testng中,測試結果是有問題的,重試的用例不會認為是skip,而被算到failure中)。
雖然我們成功使用了自己的重跑類,但是每個@Test都去指定retryAnalyzer顯得特別麻煩,怎么辦呢?我們可以使用IAnnotationTransformer監聽器,我們前面介紹過的,它是用來操作@Test注解的,我們實現這個監聽器。
這個監聽只有一個方法transform,我們通過annotation獲取到屬性retryanalyzer的值,如果沒有設置,就設置其為我們自定義的重試類。這樣只要指定使用AnnotationListener這個監聽器,就可以默認我們的重試策略了。
我習慣通過ServiceLoader的方法使用監聽器,創建一個配置文件:srcmainresourcesMETA-INFservicesorg.testng.ITestNGListener,并輸入此自定義監聽器。當然你也可以使用別的方法,請參考上一篇。
DataProvider
對于使用DataProvider數據驅動的case,我們發現,運行的時候就會出現問題,假設我們設置重試次數為2。
然后,我們看到結果:
第一組數據正常重試了兩次,并置用例為失敗,那么第二組數據,用例是失敗的,可是卻失敗了2次?
我們先來確認,使用了DataProvider的用例失敗重跑時,重跑次數不對的原因,是因為多組數據共用一個重試count,第一組數據跑完后,這個count就變成0了,后面的數據再想去重跑時,進入一次retry方法,count減一,其實此時count已經是負數了,所以就不能正常運行了,那么解決方法就比較有針對性了,只要保證每組數據的count都重置為初始設置就可以了。
我們知道,會改變count值的,只有失敗的用例,成功用例不會進入重試策略,所以,需要在每個fail用例結尾,對count復位。我們想到方法:onTestFailure,這是ITestListener接口定義的方法,我們可以繼承TestListenerAdapter,它是一個綜合多個監聽器接口的實現類。
對于失敗重試類,我們增加一個復位方法reSetCount。
將這個監聽器配置使用后,再來運行下看:
看到失敗的用例都有重試2次了。
好了,那我們再回頭看下,為什么一開始,第二組數據,用例失敗了2次呢?我們通過debug模式追蹤運行到Invoker類中的方法invokeTestMethods中,看到下面這段try...finally...代碼。
首先我們明確,@Test方法被調用是在invokeMethod方法中,而下面的兩個紅框中的方法都調用了這個方法,finally的代碼是一定會執行的,而且,由于前面進行了重試,failure.instances被add了值,不會是empty的(見下圖willRetry的邏輯,failure.instances在要重試的時候被add,后面也不會被remove,始終非空了),一定會進入retryFailed方法,所以執行到這里測試方法就被掉用了2次,那么為什么count做了復位或者不用retry策略后,就正常了呢?
1.如果count做了復位,那么就屬于正常進入retryFailed,因為失敗用例會在做willRetry的時候算到skip中。
2.而不用retry策略,或者設置retrycount為0,那么failure.instance就是空的,因為我們看到failure.instance是在willRetry為true時被設置的,所以invokeTestMethods方法中finally的代碼不會運行到retryFailed了。
測試報告
前面,我們已經提到過一次測試報告的數據展示了,再來看下:
我們發現,失敗和成功的用例結果,數據是正確的,但是重試的測試用例,被劃入skip數據中,同時,在run的總數據里也會體現,那么我們的理想狀態應該是這樣的,有幾個case就認為run幾次,重試的結果要么pass,要么failure,不算到skip中,當然也不算在總運行次數里。
怎么實現呢?
1.正常應該進入skip統計的用例,不去動,比如由于上級依賴case失敗,而skip的部分
2.針對沒有DataProvider的case,只要是重試skip的,最終一定是成功,或失敗,所以在用例結果中,這個方法應該是有多個結果
3.而使用了數據驅動的,一個測試方法有多組數據在跑,不存在單組數據沒有結果的skip,所以可以和2的情況一樣考慮
那么我們的設計就是,在用例跑完的時候,將所有skip的用例結果取出,然后看看這些skip的用例方法有沒有pass或者failure的結果,如果有,認為skip為重試導致的,將它去掉。
然后我們再來看下結果,最后輸出結果正確了:
總結
以上是生活随笔為你收集整理的重试次数配置_TestNG实践——2.用例失败重试的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: autowired 静态方法使用_关于s
- 下一篇: 微信外卖小程序 怎么计算与客户的距离_微