ตกลงฉันรู้ว่าคุณอาจต้องการคุณสมบัติที่ง่ายบางอย่างที่คุณสามารถระบุใน @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 วิธีข้างต้นมี a 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);
}
}
ตอนนี้เรามีปัญหาสุดท้ายแล้ว ชุดทดสอบดั้งเดิมของเราไม่รู้อะไรเลยเกี่ยวกับการดำเนินการ "ลองใหม่" ที่นั่น นี่คือที่ที่มันน่าเกลียดจริงๆ เราต้องบอกนักข่าวของเราว่าเกิดอะไรขึ้น และนี่คือส่วนที่ฉันแนะนำให้คุณปรับปรุง ฉันไม่มีเวลาทำสิ่งที่ดีกว่า แต่ถ้าฉันสามารถฉันจะแก้ไขได้ในบางจุด
ก่อนอื่นเราต้องรู้ว่าการดำเนินการ retryTestNG สำเร็จหรือไม่ อาจมีวิธีนับล้านที่จะทำให้ดีขึ้นได้ แต่ตอนนี้ใช้งานได้แล้ว ฉันตั้งค่าฟังสำหรับการดำเนินการลองใหม่ คุณสามารถดูได้จาก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