Tamam, muhtemelen @BeforeClass'ınızda veya bunun gibi bir şeyde belirtebileceğiniz kolay bir özellik istediğinizi biliyorum, ancak bunun uygulanmasını beklememiz gerekebilir. En azından ben de bulamadım.
Aşağıdaki cehennem kadar çirkin ama bence bu işi yapıyor, en azından küçük bir ölçekte, daha karmaşık senaryolarda nasıl davrandığını görmek için bırakılıyor. Belki daha fazla zamanla, bu daha iyi bir şeye dönüştürülebilir.
Tamam, ben de sizinkine benzer bir Test Sınıfı oluşturdum:
public class RetryTest extends TestConfig {
public class RetryTest extends TestConfig {
Assertion assertion = new Assertion();
@Test( enabled = true,
groups = { "retryTest" },
retryAnalyzer = TestRetry.class,
ignoreMissingDependencies = false)
public void testStep_1() {
}
@Test( enabled = true,
groups = { "retryTest" },
retryAnalyzer = TestRetry.class,
dependsOnMethods = "testStep_1",
ignoreMissingDependencies = false)
public void testStep_2() {
if (fail) assertion.fail("This will fail the first time and not the second.");
}
@Test( enabled = true,
groups = { "retryTest" },
retryAnalyzer = TestRetry.class,
dependsOnMethods = "testStep_2",
ignoreMissingDependencies = false)
public void testStep_3() {
}
@Test( enabled = true)
public void testStep_4() {
assertion.fail("This should leave a failure in the end.");
}
}
Ben Listener
sadece ben diğer sınıflara bu uzatmak istedikleri takdirde süper sınıfta ama siz de test sınıfında dinleyici ayarlayabilirsiniz.
@Listeners(TestListener.class)
public class TestConfig {
protected static boolean retrySuccessful = false;
protected static boolean fail = true;
}
Yukarıdaki 4 yöntemden üçü a RetryAnalyzer
. Bundan sonra yaptığım testStep_4
şeyin yürütmenin geri kalanıyla uğraşmadığından emin olmak için onsuz bıraktım . Said RetryAnalyzer
aslında yeniden denemeyecektir (yöntemin döndüğünü unutmayın false
), ancak aşağıdakileri yapacaktır:
public class TestRetry implements IRetryAnalyzer {
public static TestNG retryTestNG = null;
@Override
public boolean retry(ITestResult result) {
Class[] classes = {CreateBookingTest.class};
TestNG retryTestNG = new TestNG();
retryTestNG.setDefaultTestName("RETRY TEST");
retryTestNG.setTestClasses(classes);
retryTestNG.setGroups("retryTest");
retryTestNG.addListener(new RetryAnnotationTransformer());
retryTestNG.addListener(new TestListenerRetry());
retryTestNG.run();
return false;
}
}
Bu, yürütmeniz içinde bir yürütme oluşturur. Raporla uğraşmayacak ve biter bitmez, ana uygulamanıza devam edecektir. Ancak o gruptaki yöntemleri "yeniden deneyecek".
Evet, biliyorum, biliyorum. Bu, test paketinizi sonsuza kadar sonsuz bir döngüde yürüteceğiniz anlamına gelir. Bu yüzden RetryAnnotationTransformer
. İçinde, RetryAnalyzer'ı bu testlerin ikinci uygulamasından kaldıracağız:
public class RetryAnnotationTransformer extends TestConfig implements IAnnotationTransformer {
@SuppressWarnings("rawtypes")
@Override
public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) {
fail = false; // This is just for debugging. Will make testStep_2 pass in the second run.
annotation.setRetryAnalyzer(null);
}
}
Şimdi son sorunumuz var. Orijinal test paketimiz oradaki "tekrar dene" uygulaması hakkında hiçbir şey bilmiyor. Burası gerçekten çirkinleşiyor. Muhabirimize ne olduğunu anlatmalıyız. Ve bu sizi geliştirmeye teşvik ettiğim kısım. Güzel bir şey yapmak için zamanım yok, ama yapabilirsem, bir noktada düzenleyeceğim.
İlk olarak, retryTestNG yürütmesinin başarılı olup olmadığını bilmemiz gerekir. Muhtemelen bunu daha iyi yapmanın bir milyon yolu var, ama şimdilik bu işe yarıyor. Sadece yeniden denemek için bir dinleyici ayarladım. TestRetry
Yukarıda görebilirsiniz ve aşağıdakilerden oluşur:
public class TestListenerRetry extends TestConfig implements ITestListener {
(...)
@Override
public void onFinish(ITestContext context) {
if (context.getFailedTests().size()==0 && context.getSkippedTests().size()==0) {
successful = true;
}
}
}
Şimdi ana süitin Dinleyicisi, süper sınıfta yukarıda TestConfig
gördüğünüz, çalışmanın olup olmadığını ve iyi gittiğini görecek ve raporu güncelleyecek:
public class TestListener extends TestConfig implements ITestListener , ISuiteListener {
(...)
@Override
public void onFinish(ISuite suite) {
if (TestRetry.retryTestNG != null) {
for (ITestNGMethod iTestNGMethod : suite.getMethodsByGroups().get("retryTest")) {
Collection<ISuiteResult> iSuiteResultList = suite.getResults().values();
for (ISuiteResult iSuiteResult : iSuiteResultList) {
ITestContext iTestContext = iSuiteResult.getTestContext();
List<ITestResult> unsuccessfulMethods = new ArrayList<ITestResult>();
for (ITestResult iTestResult : iTestContext.getFailedTests().getAllResults()) {
if (iTestResult.getMethod().equals(iTestNGMethod)) {
iTestContext.getFailedTests().removeResult(iTestResult);
unsuccessfulMethods.add(iTestResult);
}
}
for (ITestResult iTestResult : iTestContext.getSkippedTests().getAllResults()) {
if (iTestResult.getMethod().equals(iTestNGMethod)) {
iTestContext.getSkippedTests().removeResult(iTestResult);
unsuccessfulMethods.add(iTestResult);
}
}
for (ITestResult iTestResult : unsuccessfulMethods) {
iTestResult.setStatus(1);
iTestContext.getPassedTests().addResult(iTestResult, iTestResult.getMethod());
}
}
}
}
}
}
Rapor şimdi 3 testin (tekrar denendikleri gibi) ve diğer 3 testin parçası olmadığı için başarısız olduğunu gösteren bir test göstermelidir:
Aradığın şey olmadığını biliyorum, ancak TestNG'ye işlevsellik katana kadar size hizmet etmesine yardımcı oluyorum.