Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing a static variable with multiple different threads running - TestNG

I am using TestNG in order to run automated mobile tests in parallel using Appium.

I have a method in one class that initiates an AppiumDriver object.

I call this method from my TestNG class in order for each thread to create it's own instance of the driver. Trouble is, because it's a static variable, when each of the threads tries to access the driver from another class via a static method:

There is always conflicts, as each thread only has access to a single implementation of the AppiumDriver object.

I understand i can bypass this by having all this code within a single class that the TestNG XML file communicates with, but this is messy and i'd prefer to have separate classes for different parts of functionality.

For example, i have a custom TestNG listener that i would like to print driver details each thread is using after each test method is run. With the following method:

However, this always prints the last running thread's driver.

How might i go about ensuring the returned driver the from the method is consistent to the driver that was created in the method?

like image 665
BIGJOHN Avatar asked May 05 '26 23:05

BIGJOHN


1 Answers

If you are running your test in parallel, then we need to use the non static method to avoid the conflicts. All the above methods needs to be changed as non static.

You need to modify your listener class as below and it will give the driver details correctly. We need to get the current class instance from the ITestResult

Listener Code:

public class ResultsListener implements ISuiteListener, IInvokedMethodListener {

    @Override
    public void afterInvocation(IInvokedMethod method, ITestResult testResult) {

        Object currentClass=testResult.getInstance();
        WebDriver driver = ((AppiumSetUp) currentClass).getDriver();
        System.out.println("Driver details:  " + driver);
     }
}

Edit:

You can extends the AppiumSetUp class in all required class(atleast in @BeforeTest method class).So, that you can directly access the setup method as below. For the example purpose, I have added the class name as BeforeTestSetup

   public class BeforeTestSetup extends AppiumSetUp{


    @BeforeTest(alwaysRun = true)
    @Parameters({"platform", "udid", "chromeDriverPort", "chromeDriverPath", "deviceName"}) 
    public void setUp(String platform, String udid, String chromeDriverPort, @Optional String chromeDriverPath, String deviceName) throws Exception { 

        driver = setUp(platform, udid, chromeDriverPort, deviceName); 
    }

}
like image 61
Subburaj Avatar answered May 07 '26 13:05

Subburaj