您好,登錄后才能下訂單哦!
這篇文章主要講解了“TestNG測試用例重跑分析”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“TestNG測試用例重跑分析”吧!
測試用例運行穩定性是自動化質量的一個重要指標,在運行中需要盡可能的剔除非bug造成的測試用例執行失敗,對于失敗用例進行重跑是常用策略之一。一種重跑策略是所有用例運行結束后對失敗用例重跑,另一種重跑策略是在運行時監控用例運行狀態,失敗后實時重跑。
下面,詳細介紹TestNG如何對失敗測試用例實時重跑并解決重跑過程中所遇到問題的實踐和解決方案。對失敗測試用例進行實時重跑,有以下幾個方面需求:
測試用例運行失敗,監聽到失敗后立即進行重跑
測試用例通過dependsOnMethods/dependsOnGroups
標記依賴其他測試用例,在被依賴的測試用例重跑運行成功后,該測試用例可以繼續運行
對于重跑多次的測試用例,只記錄最后一次運行成功或失敗結果
對于希望測試用例中的少量易失敗,不穩定的測試用例進行重跑,可采用這種方式。
以下是TestNG處理測試用例運行結果的部分代碼。
IRetryAnalyzer retryAnalyzer = testMethod.getRetryAnalyzer(); boolean willRetry = retryAnalyzer != null && status == ITestResult.FAILURE && failure.instances != null && retryAnalyzer.retry(testResult); if (willRetry) { resultsToRetry.add(testResult); failure.count++; failure.instances.add(testResult.getInstance()); testResult.setStatus(ITestResult.SKIP); } else { testResult.setStatus(status); if (status == ITestResult.FAILURE && !handled) { handleException(ite, testMethod, testResult, failure.count++); }
分析以上代碼,其中,接口IretryAnalyzer
的方法retry()
的返回值作為是否對失敗測試用例進行重跑的一個條件。如果retry()
結果為true
,則該失敗測試用例會重跑,同時將本次失敗結果修改為Skip
;如果結果為false
,則失敗的測試用例保持失敗結果,運行結束。因此,如果你希望失敗測試用例重跑的話,需要把IretryAnalyzer的retry()
方法重寫,插入自己定義的邏輯,設置返回值為true
。
創建類RetryImpl
,重寫retry()
方法,設置失敗測試用例的重跑次數,代碼如下,:
public class RetryImpl implements IRetryAnalyzer { private int count = 1; private int max_count = 3; // Failed test cases could be run 3 times at most @Override public boolean retry(ITestResult result) { System.out.println("Test case :"+result.getName()+",retry time: "+count+""); if (count < max_count) { count++; return true; } return false; } }
public class TestNGReRunDemo { @Test(retryAnalyzer=RetryImpl.class) public void test01(){ Assert.assertEquals("success","fail"); System.out.println("test01"); } }
以上測試用例test01可重復運行3次。
如果希望所有失敗的測試用例都進行重跑,采用retryAnalyzer
注解方式對每個測試用例進行注解就比較麻煩。通過實現IAnnotationTransformer
接口的方式,可以對全量測試用例的重試類進行設置。 該接口是一個監聽器接口,用來修改TestNG注解。IAnnotationTransformer
監聽器接口只有一個方法:transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod)
. 上文中,我們自定義了類RetryImpl
實現接口IRetryAnalyzer
。TestNG通過transfrom()
方法修改retryAnalyzer
注解。以下代碼對retryAnalyzer
注解進行修改設置。
創建類RetryListener
,代碼如下。
public class RetryListener implements IAnnotationTransformer { public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) { IRetryAnalyzer retry = annotation.getRetryAnalyzer(); if (retry == null) { annotation.setRetryAnalyzer(RetryImpl.class); } } }
TestNG可以在配置文件或者測試類中對Listener
類進行配置。
方法一:在TestNG的配置XML中進行以下配置
<listeners> <listener class-name="PackageName.RetryListener"></listener> </listeners>
方法二:在測試類中通過@Listeners配置
@Listeners({RetryListener.class}) public class TestNGReRunDemo { @Test public void test01(){ Assert.assertEquals("success","fail"); System.out.println("test01"); } }
配置完成后,運行測試用例test01,運行結果顯示test01將重跑次數3次。
進一步分析TestNG的運行代碼,其在對失敗運行用例重跑時,邏輯如下圖。對于通過dependsOnMethods
或dependsOnGroups
注解依賴于其他測試用例的測試用例來講,測試用例執行分為兩種情況:
alwaysRun=true,則無論所依賴的測試用例執行情況如何,該測試用例都會執行,即所依賴的測試用例重跑不會影響該測試用例的執行。
alwaysRun=false,或者保持缺省值(false),依賴于其他測試用例或測試用例組的測試結果,在運行時TestNG獲取所依賴的測試用例的運行結果,檢查依賴的測試用例是否全部執行成功,如果不全部成功,則把該測試用例結果設置為Skipped。
被依賴的測試用例失敗后進行了重跑,并重跑成功。(注:在RetryImpl
類中,已設置最大重跑次數max_count = 3)
public static int number =0; @Test public void test01(){ number++; System.out.println(String.valueOf(number)); Assert.assertEquals(number,2); System.out.println("test01"); } @Test(dependsOnMethods = "test01") // alwaysRun = false by default public void test02(){ System.out.println("test02 is running only if test01 is passed."); }
測試用例 | 運行次數 | 運行情況 | 測試報告 |
---|---|---|---|
Test01 | 2 | 第一次:skipped ; 第二次:passed | 在Skipped 和Passed的統計數量中,test01被分別記錄一次 |
Test02 | 0 | Skipped | 記錄一次Skipped |
測試報告:test01運行結果全部被記錄,而用例重跑,只希望記錄最后的結果。
運行情況:測試用例test02依賴于測試用例test01運行結果,在test01重跑成功后,測試用例test02沒有執行,不符合需求預期。
被依賴的測試用例失敗后進行了重跑,并且重跑沒有成功。(注:在RetryImpl類中,已設置最大重跑次數max_count = 3)
public static int number =0; @Test public void test01(){ number++; System.out.println(String.valueOf(number)); Assert.assertEquals(number,10); System.out.println("test01"); } @Test(dependsOnMethods = "test01") // alwaysRun = false by default public void test02(){ System.out.println("test02 is running only if test01 is passed."); }
測試用例 | 運行次數 | 運行結果 | 測試報告 |
---|---|---|---|
Test01 | 3 | 第一次:skipped;第二次:skipped;第三次:failed | 在Skipped統計數量中,test01被被記錄兩次在failed統計中,test01被記錄一次 |
Test02 | 0 | Skipped | 記錄一次Skipped |
運行情況:測試用例test02依賴于測試用例test01運行結果,在test01重跑失敗后,測試用例test02沒有執行,這種情況符合需求預期。
測試報告:同場景一,test01重跑失敗,運行結果全部被記錄,而用例重跑,只希望記錄最后的結果。
以下方案解決重跑測試用例成功后后繼測試用例無法繼續運行的問題,并對測試報告進行優化。
TestListenerAdapter
方法重寫根據上面分析的TestNG邏輯,在對依賴測試用例的結果進行檢查時,如果忽略重跑的中間結果只檢查最后一次的運行結果,可以達到需求的目的。對于測試報告,同樣的處理方式,忽略所有中間的測試用例運行結果,只記錄最后結果。 測試用例的中間運行結果為Skipped
,下面的代碼通過重寫TestListenerAdapter
的onTestSuccess()
和onTestFailure()
方法,對測試用例的中間結果skipped
進行了刪除。代碼如下:
public class ResultListener extends TestListenerAdapter { @Override public void onTestFailure(ITestResult tr) { if(tr.getMethod().getCurrentInvocationCount()==1) { super.onTestFailure(tr); return; } processSkipResult(tr); super.onTestFailure(tr); } @Override public void onTestSuccess(ITestResult tr) { if(tr.getMethod().getCurrentInvocationCount()==1) { super.onTestSuccess(tr); return; } processSkipResult(tr); super.onTestSuccess(tr); } // Remove all the dup Skipped results public void processSkipResult(ITestResult tr) { ITestContext iTestContext = tr.getTestContext(); Iterator<ITestResult> processResults = iTestContext.getSkippedTests().getAllResults().iterator(); while (processResults.hasNext()) { ITestResult skippedTest = (ITestResult) processResults.next(); if (skippedTest.getMethod().getMethodName().equalsIgnoreCase(tr.getMethod().getMethodName()) ) { processResults.remove(); } } } }
在配置文件進行全局設置或者在測試類中標記。
方法一:在TestNG的配置XML中進行以下配置
<listeners> <listener class-name="PackageName.ResultListener"></listener> </listeners>
方法二:在測試類中通過@Listeners配置
@Listeners({ResultListener.class}) public class TestNGReRunDemo { @Test public void test01(){ Assert.assertEquals("success","fail"); System.out.println("test01"); } }
測試用例 | 運行次數 | 運行結果 | 測試報告 |
---|---|---|---|
Test01 | 2 | 第一次:skipped;第二次:passed | 只在Passed的統計數量中test01被記錄一次 |
Test02 | 1 | Passed | 記錄一次passed |
測試用例 | 運行次數 | 運行結果 | 測試報告 |
---|---|---|---|
Test01 | 3 | 第一次:skipped;第二次:skipped;第三次:failed | test01只在failed統計中被記錄一次 |
Test02 | 1 | Skipped | 依賴用例執行失敗,test02結果為Skipped,只記錄一次結果Skipped |
感謝各位的閱讀,以上就是“TestNG測試用例重跑分析”的內容了,經過本文的學習后,相信大家對TestNG測試用例重跑分析這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。