ठीक है, मुझे पता है कि आप शायद कुछ आसान संपत्ति चाहते हैं जो आप अपने @BeforeClass या उस तरह से निर्दिष्ट कर सकते हैं, लेकिन हमें इसे लागू करने के लिए प्रतीक्षा करने की आवश्यकता हो सकती है। कम से कम मुझे यह नहीं मिला।
निम्नलिखित नरक के रूप में बदसूरत है, लेकिन मुझे लगता है कि यह काम करता है, कम से कम एक छोटे पैमाने पर, यह देखना बाकी है कि यह अधिक जटिल परिदृश्यों में कैसे व्यवहार करता है। शायद अधिक समय के साथ, यह कुछ बेहतर में सुधार किया जा सकता है।
ठीक है, इसलिए मैंने आपके समान एक टेस्ट क्लास बनाई:
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.");
}
}
Listener
सुपर क्लास में मेरे पास सिर्फ उस मामले में है जो मैं इसे अन्य कक्षाओं में विस्तारित करना चाहता हूं, लेकिन आप श्रोता को अपने परीक्षण वर्ग में भी सेट कर सकते हैं।
@Listeners(TestListener.class)
public class TestConfig {
protected static boolean retrySuccessful = false;
protected static boolean fail = true;
}
उपरोक्त 4 विधियों में से तीन में ए है RetryAnalyzer
। मैंने testStep_4
यह सुनिश्चित करने के लिए इसके बिना छोड़ दिया कि मैं जो कर रहा हूं वह बाकी निष्पादन के साथ खिलवाड़ नहीं है। कहा RetryAnalyzer
, वास्तव में पुन: प्रयास नहीं किया जाएगा (ध्यान दें कि विधि लौटती है false
), लेकिन यह निम्नलिखित कार्य करेगा:
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;
}
}
यह आपके निष्पादन के अंदर एक निष्पादन पैदा करेगा। यह रिपोर्ट के साथ खिलवाड़ नहीं करेगा और जैसे ही यह खत्म होगा, यह आपके मुख्य निष्पादन के साथ जारी रहेगा। लेकिन यह उस समूह के भीतर के तरीकों को "पुनः प्रयास" करेगा।
हां, मुझे पता है, मुझे पता है। इसका मतलब है कि आप अपने परीक्षण सूट को हमेशा के लिए अनन्त लूप में निष्पादित करने जा रहे हैं। इसीलिए द RetryAnnotationTransformer
। इसमें, हम उन परीक्षणों के दूसरे निष्पादन से RetryAnalyzer को हटा देंगे:
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);
}
}
अब हमारे पास हमारी समस्याएं हैं। हमारे मूल परीक्षण सूट को उस "पुन: प्रयास" निष्पादन के बारे में कुछ भी नहीं पता है। यह वह जगह है जहाँ यह वास्तव में बदसूरत हो जाता है। हमें अपने रिपोर्टर को बताना होगा कि बस क्या हुआ। और यह वह हिस्सा है जिसे मैं आपको सुधारने के लिए प्रोत्साहित करता हूं। मुझे कुछ अच्छे करने के लिए समय की कमी है, लेकिन अगर मैं कर सकता हूं, तो मैं इसे किसी बिंदु पर संपादित करूंगा।
सबसे पहले, हमें यह जानना होगा कि क्या रिट्रीटेस्टएनजी निष्पादन सफल रहा। इसे बेहतर करने के लिए शायद एक मिलियन तरीके हैं, लेकिन अब यह काम करता है। मैंने केवल एक श्रोता को पुन: प्रयास के लिए स्थापित किया। आप इसे TestRetry
ऊपर देख सकते हैं , और इसमें निम्न शामिल हैं:
public class TestListenerRetry extends TestConfig implements ITestListener {
(...)
@Override
public void onFinish(ITestContext context) {
if (context.getFailedTests().size()==0 && context.getSkippedTests().size()==0) {
successful = true;
}
}
}
अब मुख्य सुइट की श्रोता, जिसे आपने सुपर क्लास में ऊपर देखा था, TestConfig
यह देखेगा कि क्या यह रन हुआ और यदि यह अच्छी तरह से चला गया और रिपोर्ट को अपडेट करेगा:
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());
}
}
}
}
}
}
रिपोर्ट में दिखाया गया है कि अब 3 परीक्षण पास हो गए (क्योंकि वे वापस ले लिए गए थे) और एक असफल रहा क्योंकि यह अन्य 3 परीक्षणों का हिस्सा नहीं था:
मुझे पता है कि यह वह नहीं है जिसकी आप तलाश कर रहे हैं, लेकिन मैं आपकी सेवा करने में मदद करता हूं जब तक कि वे TestNG में कार्यक्षमता नहीं जोड़ते।