Appium - Parallel Execution (Grid)

@bhaskar Thanks !
As you mentioned in point no 1:
I am using TestNG (parallel=“tests”) only in my textng.xml

For the point no 2:
I have tried using node port numbers while assigning url to driver.
I think you are saying like below:
driver = new AndroidDriver(new URL(“http://xxxx:5566/wd/hub”), capabilities);
driver = new AndroidDriver(new URL(“http://xxxx:5577/wd/hub”), capabilities);

As the port 4441 is hub port and rest are nodes 5566 and 5577

Ultimately only last driver is considered as previous is/are overwritten and the script gets executed on last one. (i.e. install app on both but executes on one)
I am mentioning hub port number because we load the tests to hub and then hub distributes it to nodes as per the properties set.Please correct me if I am wrong.

@bhaskar @Appium_Master @rgonalo @Arvind_Patel @jonahss Please share your thoughts.
Thanks in advance ! :smile:

Hi @Nitin_Thite,

Take a look at hub logs, you should have something like this:

  1. INFO org.openqa.grid.web.servlet.handler.RequestHandler - Got a request to create a new session: Capabilities [{browserName=android, … }]
  2. INFO org.openqa.grid.internal.ProxySet - Available nodes: [http://…:5566, http://…:5577, …]
  3. INFO org.openqa.grid.internal.BaseRemoteProxy - Trying to create a new session on node http://…:5566
  4. INFO org.openqa.grid.internal.BaseRemoteProxy - Node http://…:5566 has no matching capability
  5. INFO org.openqa.grid.internal.BaseRemoteProxy - Trying to create a new session on node http://…:5577
  6. INFO org.openqa.grid.internal.TestSlot - Trying to create a new session on test slot {seleniumProtocol=WebDriver, browserName=android, … }

Line 4 occurs when requested capabilities (line 1) don’t match with node capabilities and line 6 occurs when they match.

I think that in your case both requests match with both nodes, so the first node executes the tests in both cases. The hub uses only browserName, version, platform and applicationName capabilities to search the node, and these capabilities are equal in NODE 1 and NODE 2.

You are right @rgonalo :smile:
in the mean time I created 2 objects of driver and tried with success. But its not recommended.

@rgonalo @Appium_Master @bhaskar @Arvind_Patel @Hassan_Radi - Please share your thoughts.

  1. Can we achieve parallel testing with one driver object only?
  2. I am referring to device ports directly in the node url while assigning to driver, I think we should load our tests on hub. Please share your thoughts.

A code for reference would help a lot.

But my goal is to execute it parallel.

Looking forward for help.

Yes @Nitin_Thite,

  1. We’re currently doing with only one driver object.
  2. Start two Appium servers with different port numbers and give them in TestNG xml file by parameterizing the values. (it will make easier).
  3. Call the same class file in both test tags as like below…!!
<test name="RunTests_On_Android_4.4 Moto G">
   <parameter name="app-apk" value="com.sample.apk"/>
   <parameter name="device-Name" value="Moto G"/>
   <parameter name="device-Version" value="5.0.2"/>
   <parameter name="device-url" value="http://0.0.0.0:4723/wd/hub"/>
   <parameter name="udid" value="xyzgvhkljh"/>
   
   <classes>
	<class name="com.test.Class1"/>
   </classes>
 </test> 
 
<test name="RunTests_On_Android_4.4 Samsung Galaxy">
   <parameter name="app-apk" value="com.sample.apk"/>
   <parameter name="device-Name" value="Galaxy S"/>
   <parameter name="device-Version" value="4.4"/>
   <parameter name="device-url" value="http://0.0.0.0:4724/wd/hub"/>
   <parameter name="udid" value="abcgvhkljh"/>
   
   <classes>
	<class name="com.test.Class2"/>
   </classes>
 </test> 

Please let me know if you need any info.

Regards,
Bhaskar.

Thanks @bhaskar
Following is my xml: - for running only one test in both the devices::

<?xml version="1.0" encoding="UTF-8"?>

Script:
public class appGRID {

WebDriver driver = null;
WebDriver driver1 = null;
WebDriver driver2 = null;
WebDriver driver3 = null;
DesiredCapabilities capabilities = new DesiredCapabilities();

@Parameters(value={"device_id1","device_id2","ApplicationPath"})
@BeforeTest
public void atStart(@Optional("nnn")String device_id1,String device_id2,String ApplicationPath) throws MalformedURLException, InterruptedException
{    
    capabilities=DesiredCapabilities.android();        
    capabilities.setCapability("automationName", "Appium");
    capabilities.setCapability(CapabilityType.PLATFORM,"ANDROID");
    capabilities.setCapability("app", ApplicationPath);
    capabilities.setCapability("appPackage", "packg"); //Replace with your app's package
    capabilities.setCapability("appActivity", "app.ui.SplashActivity"); //Replace with app's Activity
    //setting new command timeout for selenium server
    capabilities.setCapability("newCommandTimeout", "2000000");//33.33 mins
    
 if ("3204da2a5075c0b5".equalsIgnoreCase(device_id1))
    {
        System.out.println("in Samsung galaxy: "+device_id1);
        //
        capabilities.setCapability("deviceName", device_id1);
        capabilities.setCapability("udid", device_id1);
        capabilities.setCapability(CapabilityType.BROWSER_NAME,"android");
        capabilities.setCapability("platformVersion", "4.4.2");//Or//capabilities.setCapability(CapabilityType.VERSION, "4.1.2");
        
        //capabilities.setCapability("applicationName",device_id1);
                
         try
            {
                driver = new AndroidDriver(new URL("http://xxxx:5566/wd/hub"), capabilities);
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        
    }
 
 if("4d00c71c781e50eb".equalsIgnoreCase(device_id2))
    {
        System.out.println("in nexus: "+device_id2);
        //
        capabilities.setCapability("deviceName",device_id2);
        capabilities.setCapability("udid",device_id2);
        //capabilities.setCapability("applicationName",device_id2);
        capabilities.setCapability(CapabilityType.BROWSER_NAME,"chrome");
        capabilities.setCapability("platformVersion", "4.4");//Or//capabilities.setCapability(CapabilityType.VERSION, "4.1.2");
        
        
         try
            {
                driver = new AndroidDriver(new URL("http://xxxx:5577/wd/hub"), capabilities);
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
    }
}
    
@Test
public void testCase() throws InterruptedException
    {
    for (int i=0;i<=2;)
    {
        if(i==0)
            driver=driver1;
        else (i==1)
            driver=driver2;

           ((AppiumDriver)driver).findElementByName("Create Account / Sign In").click();
           ((AppiumDriver)driver).findElementByName("I already have an account").click();
           ((AppiumDriver)driver).findElementById(packg:id/email").sendKeys("[email protected]");
           ((AppiumDriver)driver).findElementById("packg:id/password").sendKeys("12345678");
           ((AppiumDriver)driver).findElementById("packg:id/login").click();
           ((AppiumDriver)driver).findElementByName("Continue free trial").click();
           
    i++;
    }
}

I think I need to update the script only, but dont know how!!
Can you please guide?

Thanks in advance ! :smile:

Yeah…This is not required !!

  1. Just create a class and use TestNG @BeforeClass annotation, give DesiredCapabilities with specific to AndroidDriver using @Parameters (Those can override in TestNG.xml).
  2. Inside @Test write your script
  3. Call the class file in TestNG xml file as i was mentioned above.

Regards,
Bhaskar.

Ok @bhaskar,

Could you please share me the script code of @BeforeClass annotation for example?
That would help.

Thanks alot for quick replies !

@bhaskar @Appium_Master @rgonalo @Hassan_Radi @jonahss Could you please help me in parallel execution?

I would like to know “How we can assign multiple urls and different capabilities to a single driver object?”
As we are setting the capabilities as per the device.
If I have to do that I have to give port of HUB that will load the tests over hub and then distribute and apss on to respective nodes. BUT that is not happening as the test only executes over last mentioned device.

I am mentioning driver object and assigning the capabilities as well the url in each IF condition for devices. Which ultimately runs the script on the last assigned device.

A bit urgent for me. (You may mail me the scripts on [email protected])
Thanks in advance ! :smile:

Eagerly waiting for replies.

Regards,
Nitin

@jonahss : When can we have 1.5? Would be great to have for parallel testing. :wink: :smiley:

@bhaskar @Appium_Master @rgonalo @Hassan_Radi @jonahss @Arvind_Patel

Really looking forward for solution to run scripts parallel. :pensive:
I am able to run sequential and have done the changes suggested by @bhaskar.

You can run scripts in parallel by starting multiple appium servers on multiple ports.
But you should create a new Driver object for each device and each url, not try to put it all on the same driver object.

1 Like

Thanks @jonahss !

@bhaskar Are you able to run the scripts with only one driver object?
Please let me know.

Regards,
Nitin

Hi,

Yes, I’m able to run with only one driver object.As i was mentioned in the following !!!

regards,
Bhaskar.

1 Like

@bootstraponline will this help to bring up parallel iOS simulator

Yes, Facebook has figured out how to do parallel iOS simulators. I’ve opened an issue on appium to adopt this new tool.

Hi @bootstraponline and @saikrishna321 ,

Did you achieved parallel execution on IOS devices/simulators ? Please let us know.

Thanks,
Bhaskar.

Facebook figured it out with https://github.com/facebook/WebDriverAgent plus https://github.com/facebook/FBSimulatorControl

Appium integration is being worked on.

3 Likes

Thanks for the reply !!
Looking forward to receive updates on this.

Thanks,
Bhaskar.

@PavithraRavichandran

Could you find solution for same?

@bootstraponline i was able to spin up two iOS Simulators, from commandline can i tell appium to run against a specific UDID ??

Steps to get two simulators

  1. xcrun simctl create “mynewsimulator” “iPhone 6” “com.apple.CoreSimulator.SimRuntime.iOS-8-4”

  2. open -n /Applications/Xcode.app/Contents/Developer/Applications/iOS\ Simulator.app/ --args -CurrentDeviceUDID ‘0F3826F2-2C2A-47E2-869C-7CE043C12F81’