14

セットアップ: IRetryAnalyzer を拡張するクラスがあり、次のメソッドをオーバーライドする単純な再試行ロジックを実装しました: public boolean retry(ITestResult result) {

クラス TestListenerAdapter を拡張する別のクラスがあり、テストが成功するか失敗を報告するまで、失敗したテストを再試行します。次のメソッドをオーバーライドするロジックを実装しました: public void onTestFailure(ITestResult result) {

シナリオ: 合計 10 個のテストがあります。10 回のテストのうち 1 回は 2 回失敗し、再試行ロジックでは 3 回目の試行で成功しました。テスト結果は次のとおりです: 合計テスト: 12、失敗: 2、スキップ: 0

私が望むのは、正しい数のテスト実行を出力することです。また、テストが最後に合格したため、2 つの失敗も無視します。したがって、結果は次のようになります: 合計テスト: 10、失敗:0、スキップ: 0

ここで何が欠けていますか?ITestResult オブジェクトを変更する必要がありますか? はいの場合、どのように?

参考までに: JUnit (TestRule インターフェイスの実装) を使用してこれを達成できました。

前もって感謝します。

4

5 に答える 5

2

私は試して、試して、試しました。しかし、ついにそれが機能しました

MyRetryAnalyzer.java

import org.testng.IRetryAnalyzer;
import org.testng.ITestResult;

import java.util.concurrent.atomic.AtomicInteger;


public class MyRetryAnalyzer implements IRetryAnalyzer {
private static int MAX_RETRY_COUNT = 3;

AtomicInteger count = new AtomicInteger(MAX_RETRY_COUNT);

public boolean isRetryAvailable() {
    return (count.intValue() > 0);
}

@Override
public boolean retry(ITestResult result) {
    boolean retry = false;
    if (isRetryAvailable()) {
        System.out.println("Going to retry test case: " + result.getMethod() + ", " + (MAX_RETRY_COUNT - count.intValue() + 1) + " out of " + MAX_RETRY_COUNT);
        retry = true;
        count.decrementAndGet();
    }
    return retry;
}
}

MyTestListenerAdapter.java

import org.testng.*;

import java.util.*;


public class MyTestListenerAdapter extends TestListenerAdapter {
    @Override
    public void onTestFailure(ITestResult result) {
        if (result.getMethod().getRetryAnalyzer() != null) {
            MyRetryAnalyzer retryAnalyzer = (MyRetryAnalyzer)result.getMethod().getRetryAnalyzer();

            if(retryAnalyzer.isRetryAvailable()) {
            } else {
                result.setStatus(ITestResult.FAILURE);
            }
            Reporter.setCurrentTestResult(result);
        }
    }

@Override
    public void onFinish(ITestContext context) {
        Iterator<ITestResult> failedTestCases =context.getFailedTests().getAllResults().iterator();
        while (failedTestCases.hasNext()) {
            System.out.println("failedTestCases");
            ITestResult failedTestCase = failedTestCases.next();
            ITestNGMethod method = failedTestCase.getMethod();
            if (context.getFailedTests().getResults(method).size() > 1) {
                System.out.println("failed test case remove as dup:" + failedTestCase.getTestClass().toString());
                failedTestCases.remove();
            } else {

                if (context.getPassedTests().getResults(method).size() > 0) {
                    System.out.println("failed test case remove as pass retry:" + failedTestCase.getTestClass().toString());
                    failedTestCases.remove();
                }
            }
        }
    }
}

あなたはクラスをテストします

@Listeners(value = MyTestListenerAdapter.class)

public class Test  {

//Your data provider
@DataProvider

@Test(retryAnalyzer = MyRetryAnalyzer.class)
public void testMethod () {
    //your code goes here
 }

}
于 2016-02-17T16:19:33.190 に答える
1

私のアプローチはMorvader の回答に基づいていますが、再試行後にメソッドが合格した場合でも実際にテストに失敗するという当初の意図に準拠する再試行アナライザーを定義する機能を追加します。

また、onFinish() メソッドでテストの数を気にする必要はありませんでした。maven-surefire-plugin バージョン 2.18では数は問題ないようでした。

RetryListenerAdapter

public class RetryListenerAdapter extends TestListenerAdapter {

    @Override
    public void onTestFailure(ITestResult tr) {
        IRetryAnalyzer retryAnalyzer = tr.getMethod().getRetryAnalyzer();
        if (retryAnalyzer == null || !(retryAnalyzer instanceof IRetryAnalyzerWithSkip)) {
            super.onTestFailure(tr);
        } else if (((IRetryAnalyzerWithSkip) retryAnalyzer).isRetryable()) {
            tr.setStatus(ITestResult.SKIP);
            super.onTestSkipped(tr);
        } else {
            super.onTestFailure(tr);
        }
    }
}

IRetryAnalyzerWithSkip

public interface IRetryAnalyzerWithSkip extends IRetryAnalyzer {
    boolean isRetryable();
}

リトライ

public class Retry implements IRetryAnalyzerWithSkip {
    private int retryCount = 0;
    private int maxRetryCount = 3;

    public boolean retry(ITestResult result) {

        if (retryCount < maxRetryCount) {
            retryCount++;
            return true;
        }
        return false;
    }

    @Override
    public boolean isRetryable() {
        return retryCount < maxRetryCount;
    }
}
于 2015-12-21T21:37:58.427 に答える