在運行測試用例時,有時候希望本次運行結束後自動運行失敗的測試用例,以排除結果由於網絡或其他連接原因導致的偶發抖動。通過參考查閱資料,有以下幾種方法可以達到目的:
***1、maven的surefire 插件,有rerun功能
參考官方文檔:http://maven.apache.org/components/surefire/maven-surefire-plugin/examples/rerun-failing-tests.html
***2、junit自定義註解,針對單個case做重試
參考:http://stackoverflow.com/questions/8295100/how-to-re-run-failed-junit-tests-immediately
***3、junit添加testRule規則,針對單個case做重試
***4、junit多線程,掃描測試日誌,查找失敗的case,記錄到Map文件,運行失敗的測試用例後將日誌寫回到原日誌中
參考:http://blog.csdn.net/neven7/article/details/43529569
由於項目需要,本篇文章主要介紹第一種方法!
一、maven surefire plugin
1、我這裏用的是Version: 2.18.1,該版本支持Re-run Failing Tests,要求Junit 4.X版本
運行命令如下,rerunFailingTestsCount爲重試tests次數,設爲0或小於0時,參數會被忽略
mvn -Dsurefire.rerunFailingTestsCount=2 test
2、控制檯輸出結果:
1)如果測試在第一次就成功,則rerun設置將被忽略
3)如果測試在某次rerun成功,則停止rerun,並在最後一次rerun輸出PASS, 如:
Run 1: ... Run 2: PASS Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Flakes: 1 ------ Flakes表示有一次rerun
2)如果測試重試count次後仍失敗,則結果沒有Flake字段,且結果爲:
Run 1: ... Run 2: ... Run 3: ...
2、.xml測試報告結果:
1)Rerun後通過
<testcase name=".." classname=".." time="0.1">
<flakyFailure message="" type=""> flaky failure stack trace <system-out> flaky failure </system-out> </flakyFailure> <system-out> success </system-out> </testcase>
2)Rerun後仍未通過
<testcase name=".." classname=".." time="0.1">
<failure message="" type=""> first failure stack trace </failure> <system-out> first failure </system-out> <rerunFailure message="" type=""> rerun failure stack trace <system-out> rerun failure </system-out> </rerunFailure> </testcase>
二、一段簡單的代碼示例:
@Test public void unRerunTest() {
System.out.println("這是不需要重試機制測試case");
@Test
public void unRerunTest() {
System.out.println("這是不需要重試機制測試case");
boolean bool = false;
Assert.assertFalse("應該爲false", bool);
}
@Test
public void rerunTest1() {
boolean first = false;
long time = System.currentTimeMillis();
System.out.println("這是第一個需要重試機制測試case,time:" + time + ", first=" + first);
Assert.assertTrue("first應該爲true", first);
}
@Test
public void rerunTest2() {
boolean first = true;
long time = System.currentTimeMillis();
System.out.println("這是第二個需要重試機制測試case,time:" + time + ", first=" + first);
Assert.assertFalse("first應該爲false", first);
}
pom.xml配置:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>2.18.1</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
1、控制檯輸出結果:
這是不需要重試機制測試case
這是第一個需要重試機制測試case,time:1433940475436, first=false
這是第二個需要重試機制測試case,time:1433940475439, first=true
Tests run: 3, Failures: 2, Errors: 0, Skipped: 0, Time elapsed: 0.002 sec <<< FAILURE! - in com.xiaomi.testteam.rerun_test.MavenRerunTest
rerunTest1(com.xiaomi.testteam.rerun_test.MavenRerunTest) Time elapsed: 0 sec <<< FAILURE!
java.lang.AssertionError: first應該爲true
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.assertTrue(Assert.java:41)
at com.xiaomi.testteam.rerun_test.MavenRerunTest.rerunTest1(MavenRerunTest.java:30)
rerunTest2(com.xiaomi.testteam.rerun_test.MavenRerunTest) Time elapsed: 0.001 sec <<< FAILURE!
java.lang.AssertionError: first應該爲false
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.assertTrue(Assert.java:41)
at org.junit.Assert.assertFalse(Assert.java:64)
at com.xiaomi.testteam.rerun_test.MavenRerunTest.rerunTest2(MavenRerunTest.java:42)
這是第一個需要重試機制測試case,time:1433940475443, first=false
這是第二個需要重試機制測試case,time:1433940475444, first=true
Tests run: 2, Failures: 2, Errors: 0, Skipped: 0, Time elapsed: 0.014 sec <<< FAILURE! - in com.xiaomi.testteam.rerun_test.MavenRerunTest
rerunTest1(com.xiaomi.testteam.rerun_test.MavenRerunTest) Time elapsed: 0 sec <<< FAILURE!
java.lang.AssertionError: first應該爲true
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.assertTrue(Assert.java:41)
at com.xiaomi.testteam.rerun_test.MavenRerunTest.rerunTest1(MavenRerunTest.java:30)
rerunTest2(com.xiaomi.testteam.rerun_test.MavenRerunTest) Time elapsed: 0 sec <<< FAILURE!
java.lang.AssertionError: first應該爲false
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.assertTrue(Assert.java:41)
at org.junit.Assert.assertFalse(Assert.java:64)
at com.xiaomi.testteam.rerun_test.MavenRerunTest.rerunTest2(MavenRerunTest.java:42)
Results :
Failed tests:
com.xiaomi.testteam.rerun_test.MavenRerunTest.rerunTest1(com.xiaomi.testteam.rerun_test.MavenRerunTest)
Run 1: MavenRerunTest.rerunTest1:30 first應該爲true
Run 2: MavenRerunTest.rerunTest1:30 first應該爲true
com.xiaomi.testteam.rerun_test.MavenRerunTest.rerunTest2(com.xiaomi.testteam.rerun_test.MavenRerunTest)
Run 1: MavenRerunTest.rerunTest2:42 first應該爲false
Run 2: MavenRerunTest.rerunTest2:42 first應該爲false
Tests run: 3, Failures: 2, Errors: 0, Skipped: 0
可以看出,測試是在運行整個suite第一次結束之後,檢查fail的測試用例並再次運行,直到count次重試之後,測試Case依舊fail,則打印所有重試的結果!
如果把test增加時間設置,結果則變成:
@Test public void rerunTest1() { boolean first = false; long time = System.currentTimeMillis(); if (time % 2 == 0) {// 用於測試在count內rerun通過,打印結果對比 first = true; } System.out.println("這是第一個需要重試機制測試case,time:" + time + ", first=" + first); Assert.assertTrue("first應該爲true", first); } @Test public void rerunTest2() { boolean first = true; long time = System.currentTimeMillis(); if (time % 2 == 0) { first = false; } System.out.println("這是第二個需要重試機制測試case,time:" + time + ", first=" + first); Assert.assertFalse("first應該爲false", first); }
這是第一個需要重試機制測試case,time:1433928323102, first=true
這是第二個需要重試機制測試case,time:1433928323103, first=true
Tests run: 3, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.001 sec <<< FAILURE! - in com.xiaomi.testteam.rerun_test.MavenRerunTest
rerunTest2(com.xiaomi.testteam.rerun_test.MavenRerunTest) Time elapsed: 0 sec <<< FAILURE!
java.lang.AssertionError: first應該爲false
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.assertTrue(Assert.java:41)
at org.junit.Assert.assertFalse(Assert.java:64)
at com.xiaomi.testteam.rerun_test.MavenRerunTest.rerunTest2(MavenRerunTest.java:41)
這是第二個需要重試機制測試case,time:1433928323109, first=true
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.01 sec <<< FAILURE! - in com.xiaomi.testteam.rerun_test.MavenRerunTest
rerunTest2(com.xiaomi.testteam.rerun_test.MavenRerunTest) Time elapsed: 0 sec <<< FAILURE!
java.lang.AssertionError: first應該爲false
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.assertTrue(Assert.java:41)
at org.junit.Assert.assertFalse(Assert.java:64)
at com.xiaomi.testteam.rerun_test.MavenRerunTest.rerunTest2(MavenRerunTest.java:41)
這是第二個需要重試機制測試case,time:1433928323112, first=false
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.017 sec - in com.xiaomi.testteam.rerun_test.MavenRerunTest
Results :
Flaked tests:
com.xiaomi.testteam.rerun_test.MavenRerunTest.rerunTest2(com.xiaomi.testteam.rerun_test.MavenRerunTest)
Run 1: MavenRerunTest.rerunTest2:41 first應該爲false
Run 2: MavenRerunTest.rerunTest2:41 first應該爲false
Run 3: PASS