Appium - Parallel Execution (Grid)

@Appium_Master : Just now I tried it and it is working fine.

Hi @Appium_Master,

Thanks for the reply. I had done the same few days ago. But Appium should be installed on Remote Machine and also be on running state.

Thanks,
Bhaskar.

Yes @Arvind_Patel ,

It could be possible with Appium Master’s inputs…go ahead.

Thanks,
Bhaskar.

OOHH man,
parallel execution killing me. :stuck_out_tongue_winking_eye: . though any how i made it but still there is one problem i am facing

i am running two different test parallely on different device
like

  1. 2 appium node running with two devices, ports and josn config
  2. Selenium grid is running and both node registered

Now i am setting capability dynamically (getting parameter from suite file )
ex:
Test1


Test2


when i run suite
its taking devices randomly like sometime test1 runs on emulator and some time on device1

Is there any one facing same issue ?

Hi @Arvind_Patel ,

Sorry for the late response. Have you tried with all the three flags for both the instances like below…?
appium --nodeconfig path\to\nodeconfig1.json -p 4723 -bp 5723 --udid 1stdeviceUdidNum
appium --nodeconfig path\to\nodeconfig2.json -p 4724 -bp 5724 --udid 2nddeviceUdidNum

have a try !!!

Bhaskar.

@bhaskar

Is there any possibility of running a testsuite containing multiple testcases with same appium instance. As when I tried to run a test suite, first testcase ran successfully but failed at second testcase and so on stating A new session cannot be started … BTW I am trying to run 10 testcase in the same IOS simulator.

I have posted this issue here:

1 Like

@bhaskar
Hi Bhaskar,

I am trying to run parallel test on different OS by connecting to selenium Hub.
Here is my scenario:

Hub: On Windows machine
Node1: On same window machine as HUB
Node2: On Mac Machine.

I am trying to run on Android devices connected to both the OS.
I am able to run on Windows but on MAC appium is throwing an error "Unable to load node configuration file to register with grid"

Here is my both Node files:

Node1: {
“capabilities”:
[
{
“browserName”: “Android”,
“version”:“5.1.1”,
“udid”:“052d6d76002e47df”,
“maxInstances”: 1,
“platform”:“ANDROID”,
“deviceName”:“google Nexus 5”
}],
“configuration”:

{
“nodeTimeout”:120,
“port”:4740,
“hubPort”:4444,
“proxy”: “org.openqa.grid.selenium.proxy.DefaultRemoteProxy”,
“url”:“http://127.0.0.1:4740/wd/hub”,
“hub”: “127.0.0.1:4444/grid/register”,
“hubHost”:“127.0.0.1”,
“nodePolling”:2000,
“registerCycle”:10000,
“register”:true,
“cleanUpCycle”:2000,
“timeout”:30000,
“maxSession”:1

Node2: {
“capabilities”:
[
{
“browserName”: “Android”,
“version”:“4.3”,
“udid”:“4df742b317683077”,
“maxInstances”: 1,
“platform”:“ANDROID”,
“deviceName”:“samsung GT-N7100”
}],
“configuration”:

{
“nodeTimeout”:120,
“port”:4728,
“hubPort”:4444,
“proxy”: “org.openqa.grid.selenium.proxy.DefaultRemoteProxy”,
“url”:“http://127.0.0.1:4728/wd/hub”,
“hub”: “10.123.23.123:4444/grid/register”,
“hubHost”:“10.123.23.123”,
“nodePolling”:2000,
“registerCycle”:10000,
“register”:true,
“cleanUpCycle”:2000,
“timeout”:30000,
“maxSession”:1
}
}

By the way, the work we are doing for Appium v1.5 will make it so we will finally be able to have multiple sessions (parallel tests) with just one appium server ^.^

4 Likes

@jonahss Thats really good news… it will save our lot of effort to setup parallel execution :relaxed:

1 Like

Great news…!!! Looking forward to receive updates from you… :thumbsup:

Hi @RISHI_KHANNA ,
Well tried, Make sure that Appium server is running on Mac with 4728 port as you’re mentioned in NodeConfig2.json file.

Note : I’ve observed there is no need of Selenium server to interact with Appium. Just start Appium on your MAC OS X with port num (e.g. 4728) and give URL as http://192.xxx.x.xxx:4728/wd/hub and run your test from any machine it will listen on port number and executes your tests…Have a try,Good Luck. :smile:

@bhaskar

I tried after changing the URL to my Windows ip where my other node is located and my script are kept but again it is throwing an error :

FAILED: test2(“4df742b317683077”, “samsung GT-N7100”, “4.3”)

org.openqa.selenium.SessionNotCreatedException: A new session could not be created. (Original error: Device 4df742b317683077 was not in the list of connected devices) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 8.52 seconds

Sceanario is: My test script and one node is located in Windows machine from where I m triggering the job and my second node is located in MAC machine.

So, in nodeconfig file for MAC my URL and hub will be of Window machine?

@bhaskar,

While running my code, my getting the below error
11:42:37.400 WARN - Exception: The path to the driver executable must be set by
the webdriver.ie.driver system property; for more information, see https://githu
b.com/SeleniumHQ/selenium/wiki/InternetExplorerDriver. The latest version can be
downloaded from http://selenium-release.storage.googleapis.com/index.html

Can you please help me to sort out this issue ?

@bhaskar:
Also, how to pass build information?
Like my capabilities are set in Windows machine where I have defined my build path and name and I m triggering it from windows to run on MAC. How to pass these info?

Hi all @Appium_Master @rgonalo @bhaskar @Arvind_Patel @Hassan_Radi

I am able to install and launch the app in both the devices connected but script is being executed only on one.

NODE 1:
{
“capabilities”:
[
{
“browserName”:“android”,
“version”:“4.4.2”,
“maxInstances”:5,
“platform”:“ANDROID”,
“deviceName”: “3204da2a5075c0b5”
}
],
“configuration”:
{
“nodeTimeout”:120,
“cleanUpCycle”:2000,
“timeout”:10000,
“proxy”:“org.openqa.grid.selenium.proxy.DefaultRemoteProxy”,
“url”:“http://xxxx:5566/wd/hub”,
“maxSession”:2,
“port”:5566,
“register”:true,
“registerCycle”:5000,
“hub”: “xxxx:4441/grid/register”,
“hubPort”: 4441,
“hubHost”: “xxxx”,
“role”:“node”
}
}

NODE 2:
{
“capabilities”:
[
{
“browserName”:“android”,
“version”:“4.4.2”,
“maxInstances”:5,
“platform”:“ANDROID”,
“deviceName”: “8a2d363”
}
],
“configuration”:
{
“nodeTimeout”:120,
“cleanUpCycle”:2000,
“timeout”:10000,
“proxy”:“org.openqa.grid.selenium.proxy.DefaultRemoteProxy”,
“url”:“http://xxxx:5577/wd/hub”,
“maxSession”:2,
“port”:5577,
“register”:true,
“registerCycle”: 5000,
“hub”: “xxxx:4441/grid/register”,
“hubPort”: 4441,
“hubHost”: “xxxx”,
“role”:“node”
}
}

I am passing device id as a parameter from testng.xml file

Script:
public class appGrid {
WebDriver driver = 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.BROWSER_NAME,"android");
    capabilities.setCapability("platformVersion", "4.4.2");//Or//capabilities.setCapability(CapabilityType.VERSION, "4.1.2");
    capabilities.setCapability(CapabilityType.PLATFORM,"ANDROID");
    //capabilities.setCapability("platformName","ANDROID");//Or//capabilities.setCapability(CapabilityType.PLATFORM, "Android");
    capabilities.setCapability("app", ApplicationPath);
    capabilities.setCapability("appPackage", "com.app.android.staging"); //Replace with your app's package
    capabilities.setCapability("appActivity", "com.app.android.ui.TabActivity"); //Replace with app's Activity
    //setting new command timeout for selenium server
    capabilities.setCapability("newCommandTimeout", "2000000");//33.33 mins
        
    if("8a2d363".equalsIgnoreCase(device_id2))
    {
        System.out.println("in nexus: "+device_id2);
        //
        capabilities.setCapability("deviceName",device_id2);
        //capabilities.setCapability("udid","8a2d363");
        //capabilities.setCapability("deviceName","Micromax A311");
        capabilities.setCapability("sleep", "1000");
        
         try
            {
                driver = new AndroidDriver(new URL("http://xxxx:4441/wd/hub"), capabilities);
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
    }
    
 if ("3204da2a5075c0b5".equalsIgnoreCase(device_id1))
    {
        System.out.println("in Samsung galaxy: "+device_id1);
        //
        capabilities.setCapability("deviceName", device_id1);
    //    capabilities.setCapability("udid", "3204da2a5075c0b5");
    //    capabilities.setCapability("deviceName","SM-N750");
        capabilities.setCapability("sleep", "15000");
        
         try
            {
                driver = new AndroidDriver(new URL("http://xxxx:4441/wd/hub"), capabilities);
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }   
    }
}

I understand the driver mentioned 1st is overwriting the last one but If I mention the last one only out of IF block, I see the installation in only one device.

Really looking forward for help.
I have been struggling for implementing at last point from long time.

Thanks in advance ! :wink:

Hi @Nitin_Thite ,

  1. First of all this is not the better way to execute the multiple device execution parallel. Instead you can use different objects for AndroidDriver (or) use TestNG (parallel=“tests”).
  2. You’ve mentioned 4441 port number for both the devices. There should be n no.of Appium servers should be started for n n no.of devices with different port numbers. In your case 2 port numbers are required for 2 devices.

driver = new AndroidDriver(new URL(“http://xxxx:4441/wd/hub”), capabilities);

driver = new AndroidDriver(new URL(“http://xxxx:4441/wd/hub”), capabilities); //highlighted should be unique

Please do the needful and let us know !!!

Regards,
Bhaskar.

@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.