請考慮以下測試結果與最大。 2次重試:
- 通過=>總的來說還可以!
- 失敗,已通過=>總體可以!
- 失敗,失敗,通過=>總體OK!
- 失敗,失敗,失敗=>總體失敗!
我所做的是創建一個TestNg偵聽器,它擴展了默認行爲,並在所有測試完成後執行一些魔術。
public class FixRetryListener extends TestListenerAdapter {
@Override
public void onFinish(ITestContext testContext) {
super.onFinish(testContext);
// List of test results which we will delete later
List<ITestResult> testsToBeRemoved = new ArrayList<>();
// collect all id's from passed test
Set <Integer> passedTestIds = new HashSet<>();
for (ITestResult passedTest : testContext.getPassedTests().getAllResults()) {
passedTestIds.add(TestUtil.getId(passedTest));
}
Set <Integer> failedTestIds = new HashSet<>();
for (ITestResult failedTest : testContext.getFailedTests().getAllResults()) {
// id = class + method + dataprovider
int failedTestId = TestUtil.getId(failedTest);
// if we saw this test as a failed test before we mark as to be deleted
// or delete this failed test if there is at least one passed version
if (failedTestIds.contains(failedTestId) || passedTestIds.contains(failedTestId)) {
testsToBeRemoved.add(failedTest);
} else {
failedTestIds.add(failedTestId);
}
}
// finally delete all tests that are marked
for (Iterator<ITestResult> iterator = testContext.getFailedTests().getAllResults().iterator(); iterator.hasNext();) {
ITestResult testResult = iterator.next();
if (testsToBeRemoved.contains(testResult)) {
iterator.remove();
}
}
}
}
基本上我做兩件事情:
- 收集全部通過測試。如果我遇到至少有一個通過測試失敗的測試,我將刪除失敗的測試(這將覆蓋上面的情況2和3)
- 迭代所有失敗的測試。如果我遇到以前失敗的失敗測試,請刪除當前失敗的結果。 (這實際上將包括案例3和4)。這也意味着如果有幾個失敗的結果,我將只保留第一個失敗的結果。
要確定一個TestResult我用下面簡單的哈希函數:
public class TestUtil {
public static int getId(ITestResult result) {
int id = result.getTestClass().getName().hashCode();
id = 31 * id + result.getMethod().getMethodName().hashCode();
id = 31 * id + (result.getParameters() != null ? Arrays.hashCode(result.getParameters()) : 0);
return id;
}
}
這種方法並用的dataProvider工作很好,但有一個小的限制!如果您使用的dataProvider使用隨機值你會碰到的問題:
@DataProvider(name = "dataprovider")
public Object[][] getData() {
return new Object[][]{{System.currentTimeMillis()}};
}
對於失敗的測試的dataProvider是重新評估。因此,您將得到一個新的時間戳,同一個mehod的result1和result2將導致不同的散列值。解決方法是將參數指數包含在getId()方法中而不是參數中,但似乎這樣的值不包含在ITestResult中。
看到這個簡單的例子作爲概念驗證:
@Listeners(value = FixRetryListener.class)
public class SimpleTest {
private int count = 0;
@DataProvider(name = "dataprovider")
public Object[][] getData() {
return new Object[][]{{"Run1"},{"Run2"}};
}
@Test(retryAnalyzer = RetryAnalyzer.class, dataProvider = "dataprovider")
public void teste(String testName) {
count++;
System.out.println("---------------------------------------");
System.out.println(testName + " " + count);
if (count % 3 != 0) {
Assert.fail();
}
count = 0;
}
}
將產生在:
Total tests run: 2, Failures: 0, Skips: 0
你找到一個解決的辦法了嗎?謝謝。 – derrdji
不幸的不是。現在就解決問題。 –