簡體   English   中英

TestNG - 如何在每次測試結束時運行相同的方法

[英]TestNG - how to run the same method at the end of each test

我有類似的東西:

@Test(priority = 1)
public void test1() {
    testSomething1();
    Assert.assertFalse(errorsExists());
}
    
@Test(priority = 2)
public void test2() {
    testSomething2();
    Assert.assertFalse(errorsExists());
}
    
@Test(priority = 3)
public void test3() {
    testSomething3();
    Assert.assertFalse(errorsExists());
}

我想將Assert.assertFalse(errorsExists())移動到BaseTestCaseTestListener ,這樣我就不必每次在測試結束時都通過它。 我試圖將它移到 TestsListener 到onFinish但方法errorsExists()需要驅動程序,我有問題將它放在那里。

更新:我想方法 errorsExists() 影響測試結果。 假設在 test2 方法中 errorsExists 返回 true -> 我想得到以下結果: test1 通過 test2 failed test3 通過

據我所知,我不能將此方法放在任何 @After 注釋中,也不能將其放在 TestListener 中的 onTestFailure 或 onTestSuccess

您應該能夠將其移至使用 @AfterMethod 注釋的新方法。 任何帶有@AfterMethod 注解的方法都將在每個測試方法執行后執行。 像這樣的東西應該工作:

@Test(priority = 1)
public void test1() {
  testSomething1();
  //Assert.assertFalse(errorsExists());
}

@Test(priority = 2)
public void test2() {
  testSomething2;
  //Assert.assertFalse(errorsExists());
}

@Test(priority = 3)
public void test3() {
  testSomething3();
  //Assert.assertFalse(errorsExists());
}

@AfterMethod
public void assertError() {
  Assert.assertFalse(errorsExists());
}

如果您並行運行每個 @Test 方法,則可以通過以下方式實現此目的。 但前提是,每個 @Test 都應該有自己的 WebDriver 實例。 您可以使用 ThreadLocal 變量來實現這一點。 例如:

public class Driver {

    public static ThreadLocal<AppiumDriver> driver = new ThreadLocal<>();
  
    public static AppiumDriver getDriver() {
        return driver.get();
    }

public synchronized void initalizeDriver(String deviceName, String platformVersion, String port, String udid) {
        if (deviceName.contains("iPhone")) {
            setIOSCapabilities(driver, deviceName, platformVersion, port, udid);
        } else if (deviceName.equalsIgnoreCase("pcloudy-apple")) {
            setPcloudyIOSCapabilties(driver,platformVersion);
        } else {
            if (deviceName.contains("R-")) {
                setAndroidCapabilities(driver, deviceName, platformVersion, port, udid);
            } else if (deviceName.equalsIgnoreCase("pcloudy-Android")) {
                setPcloudyAndroidCapabilties(driver,platformVersion);
            } else {
                startAndroidEmulator(deviceName, udid);
                setAndroidCapabilities(driver, deviceName, platformVersion, port, udid);
            }
        }
    }
}

public void setAndroidCapabilities(ThreadLocal<AppiumDriver> driver, String device, String platformVersion, String port, String udid) {

        try {
            File sourceDir = new File("src");
            File app = new File(sourceDir, ANDROID_APP_PATH);

            DesiredCapabilities desiredCapabilties = new DesiredCapabilities();
            desiredCapabilties.setCapability(MobileCapabilityType.DEVICE_NAME, device);
            
            desiredCapabilties.setCapability(AndroidMobileCapabilityType.IGNORE_UNIMPORTANT_VIEWS,true);
            driver.set(new AndroidDriver<>(new URL(APPIUM_DEFAULT_URL), desiredCapabilties));
        } catch (Exception e) {
            log.error(e.getMessage());
            log.error("Exception in launching the Android Driver " + e);
            e.printStackTrace();
        }
    }

基礎 class 中的方法為每個 @Test 方法啟動一個新的驅動程序實例

@BeforeMethod(alwaysRun = true)
@Parameters(value={"deviceName","platformVersion","port","udid"})
public synchronized void executeBeforeTest(String deviceName, String platformVersion,
                                               @Optional("Port Required") String port, @Optional("UDID Required") String udid){
        Driver driverObj = new Driver();
        Thread.currentThread().setName(deviceName);
        driverObj.initalizeDriver(deviceName,platformVersion,port,udid);
        if(Driver.getDriver() == null) {
            driverObj.initalizeDriver(deviceName,platformVersion,port,udid);
        }
    }

最后是您正在尋找的 TestListener class,

public class TestListener extends UITest implements ITestListener {
@Override
    public void onTestFailure(ITestResult iTestResult) {
        log.info("Driver getDriver() value is :: "+Driver.getDriver().toString());
        log.info("Driver getSessionId() value is :: "+Driver.getDriver().getSessionId().toString());
            if (Driver.getDriver() != null || Driver.getDriver().getSessionId() != null) {
                try {
                    if (Driver.getDriver() instanceof IOSDriver) {
                        JavascriptExecutor js = (JavascriptExecutor) Driver.getDriver();
                        Map<String, Object> params = new HashMap<>();
                        params.put("bundleId", DeviceCapabalities.IOS_APP_BUNDLE_ID);
                        final Long state = (Long) js.executeScript("mobile: queryAppState", params);
                        System.out.println("Application state code is :" + state);
                        if (state == 1) {
                            log.error("Application has Crashed");
                        }
                    } else {
                        if (!(((AndroidDriver) (Driver.getDriver())).currentActivity().contains("app.name"))) {
                            log.error("Application has Crashed");
                        }
                    }
                    saveScreenshot(Driver.getDriver(),iTestResult);
                } catch (Exception e) {
                    log.error("Exception :: " + e);
                    e.printStackTrace();
                    Assert.fail("Test case failed due to exception " + e);
                }
            }
    }

您可以使用IHookable接口來實現這一點。 這通常是(根據文檔),用於在測試開始之前做一些操作。 但它也適用於每次測試結束時的操作。

創建一個實現此接口的BaseTest並讓您的測試類擴展BaseTest

public class BaseTest implements IHookable {

    @Override
    public void run(IHookCallBack cb, ITestResult testResult) {
        cb.runTestMethod(testResult); // invokes the actual test case
        Assert.assertFalse(errorsExists());
    }
}

您可以使用IInvokedMethodListener調用一些代碼並修改測試結果。

請注意,這是一個非常簡單的實現,僅基於您的代碼示例。 它可能需要一些改進。

測試 Class:

@Listeners(ErrorsExistsListener.class)
class MyTest {

    @Test(priority = 1)
    public void test1() {
        testSomething1();
    }

    @Test(priority = 2)
    public void test2() {
        testSomething2;
    }

    @Test(priority = 3)
    public void test3() {
        testSomething3();
    }

    boolean errorsExists() {
        // some logic
    }
    

}

測試監聽器:

class ErrorsExistsListener implements IInvokedMethodListener {

    @Override
    void afterInvocation(IInvokedMethod method, ITestResult result) {
        if (method.isTestMethod() && result.getStatus() != ITestResult.FAILURE) {
            Object[] instances = result.getTestClass().getInstances(false);
            MyTest myTestClass = (MyTest) instances[0]; // you'll get exception here if set this listener for non-MyTest class.
            try {
                Assert.assertFalse(myTestClass.errorsExists());
            } catch (AssertionError e) {
                result.setStatus(ITestResult.FAILURE);
                result.setThrowable(e);
            }
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM