เรียกใช้คลาสที่สมบูรณ์อีกครั้งไม่ใช่แค่ @Test ใน TestNG


9

ฉันเรียกดู stackoverflow มาหลายวันแล้วพยายามหาวิธีทดสอบคลาสทั้งหมดอีกครั้งไม่ใช่แค่@Testขั้นตอนเดียว หลายคนบอกว่าสิ่งนี้ไม่ได้รับการสนับสนุนจาก TestNG และIRetryAnalyzerในขณะที่บางคนโพสต์การแก้ไขปัญหาที่ไม่ได้ผลจริงๆ มีใครจัดการที่จะทำมันได้หรือไม่ และเพื่อชี้แจงเหตุผลสำหรับสิ่งนี้เพื่อหลีกเลี่ยงคำตอบที่บอกว่าไม่รองรับวัตถุประสงค์: TestNG เป็นเครื่องมือที่ไม่เพียง แต่สำหรับนักพัฒนาเท่านั้น ความหมายที่ใช้จากผู้ทดสอบ sw สำหรับการทดสอบ e2e การทดสอบ E2e สามารถมีขั้นตอนที่ขึ้นอยู่กับแต่ละการทดสอบก่อนหน้านี้ ดังนั้นใช่มันเป็นความถูกต้องในการทดสอบระดับ re-run ทั้งมากกว่าที่เรียบง่ายซึ่งจะสามารถทำได้อย่างง่ายดายผ่านทาง@TestIRetryAnalyzer

ตัวอย่างของสิ่งที่ฉันต้องการบรรลุคือ:

public class DemoTest extends TestBase {

@Test(alwaysRun = true, description = "Do this")
public void testStep_1() {
    driver.navigate().to("http://www.stackoverflow.com");
    Assert.assertEquals(driver.getCurrentUrl().contains("stackoverflow)"));

}

@Test(alwaysRun = true, dependsOnMethods = "testStep_1", description = "Do that")
public void testStep_2() {
    driver.press("button");
    Assert.assertEquals(true, driver.elementIsVisible("button"));

}

@Test(alwaysRun = true, dependsOnMethods = "testStep_2", description = "Do something else")
public void testStep_3() {
   driver.press("button2");
Assert.assertEquals(true, driver.elementIsVisible("button"));

}

}

สมมติว่าtestStep_2ล้มเหลวฉันต้องการรันใหม่class DemoTestและไม่เพียงtestStep_2


คุณช่วยแสดงวิธีแก้ปัญหาที่ไม่ได้ผลได้ไหม
AndiCover

โปรดแก้ไขคำถามของคุณใส่ตัวอย่างและแสดงให้เราเห็นว่าคุณคาดหวังอะไร นั่นจะเป็นการช่วยผู้อื่นให้คำตอบที่ตรงกับความคาดหวังของคุณ
Krishnan Mahadevan

@AndiCover ลิงค์ไปยังวิธีการแก้ปัญหาที่ไม่ทำงาน (หรือวิธีการแก้ปัญหาที่ทำลายตรรกะ TestNG): stackoverflow.com/questions/25781098/... stackoverflow.com/questions/50241880/... stackoverflow.com/questions/53736621/...
gandalf_the_cool

คำตอบ:


1

ตกลงฉันรู้ว่าคุณอาจต้องการคุณสมบัติที่ง่ายบางอย่างที่คุณสามารถระบุใน @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


โอ๊ะโอฉันลืมเพิ่มเงื่อนไขใน Listener หลักเพื่ออัปเดตรายงานขั้นสุดท้ายหากมีชุดทดลองซ้ำเกิดขึ้นและประสบความสำเร็จ เพิ่มตอนนี้
Rodrigo Vaamonde
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.