Android – Running automated tests using appium and selenium grids can only be run on one device

Running automated tests using appium and selenium grids can only be run on one device… here is a solution to the problem.

Running automated tests using appium and selenium grids can only be run on one device

I’m trying to run some mobile automation tests using appium and selenium grids. Once all the configuration is done and the grid nodes are added, how do I run tests in parallel on both devices?

This is my setUp():

desired_caps = {}
    desired_caps['platformName'] = 'Android'
    desired_caps['platformVersion'] = '5.1'
    desired_caps['deviceName'] = ''
    desired_caps['app'] = os.path.abspath(os.path.join(os.path.dirname(__file__), 'C:/Users/XXXXX/Desktop/workspace/XXXX/apps/XXXXX.apk'))
    desired_caps['appPackage'] = 'XXXXXXXX'
    desired_caps['appActivity'] = '. MainActivity'
    desired_caps['noReset'] = False
    self.driver = webdriver. Remote('http://localhost:4444/wd/hub', desired_caps)
    self.driver.implicitly_wait(15) 

What should deviceName be in this case?

If I leave it blank, this is what I get :

C:\Users\XXXXX\Desktop\workspace\XXXXX>java -jar selenium-server-standalone-2.44.0.jar -role hub

19:16:58.691 INFO - Launching a selenium grid server

2016-02-18 19:16:59.937:INFO:osjs. Server:jetty-7.x.y-SNAPSHOT

2016-02-18 19:16:59.968:INFO:osjsh. ContextHandler:startedo.s.j.s.ServletContextHandler{/,null}2016-02-18 19:16:59.995:INFO:osjs. AbstractConnector:[email protected]:4444

19:49:48.183 INFO - Got a request to create a new session: Capabilities[{app=C:\Users\XXXXX\Desktop\workspace\XXXXX\apps\XXXXX.apk, appPackage=XXXXXXX, appActivity=. MainActivity, noReset=true, platformVersion=5.1, platformName=Android, deviceName=}]

19:49:48.183 INFO - Available nodes: [host :http://127.0.0.1:4723, host :http://127.0.0.1:4733]

19:49:48.183 INFO - Trying to create a new session on node host :http://127.0.0.1:4723

19:49:48.183 INFO - Trying to create a new session on test slot {newCommandTimeout=30, browserName=Android, maxInstances=1, version=5.1,deviceName=0429058934,deviceReadyTimeout=5, platform=ANDROID}

I can only run one registration node in the mesh. I even tried to create a script with two setup(), each for each device, but even then the tests only run on the same device.

Here is my grid console:

enter image description here

Solution

    I did try to run tests using Grid with Appium server in java, same logic you can adopt for your own language. Here is the explanation:

1. This is the same content of node.json file on two node machines:

{
    "capabilities":
         [
           {
             "version":"4.4.2",
             "maxInstances": 3,
             "platformName":"ANDROID"
           }
         ],
    "configuration":
    {
       "cleanUpCycle":2000,
       "timeout":30000,
       "proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy",
       "url":"http://WHERE_APPIUM_RUNNNING:4723/wd/hub",
       "host": "WHERE_APPIUM_RUNNNING_IP",
       "port": 4723,
       "maxSession": 6,
       "register": true,
       "registerCycle": 5000,
       "hubPort": 4444,
       "hubHost": "WHERE_HUB_RUNNNING_IP"
    }
    } 

2. Downloaded selenium-server-standalone-2.52.0.jar and started as hub on one machine like: 
    java -jar ~/Downloads/selenium-server-standalone-2.52.0.jar -role hub maxInstances=2 maxSessions=2 

3. Started ONLY appium server on node machines and registered with hub using command as: appium --nodeconfig ~/Desktop/node.json

4. Now declare all the common capability in GridTest.java and only deviceName was passed from testNG.xml in order to avoid any hardcoding in code and keeping node.config as generic for all node machines, sample testNG.xml is like:

<?xml version="1.0" encoding="UTF-8"?>
    <! DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
    <suite name="Automation" parallel="tests">

<test name="Test1">
        <parameter name="deviceName" value="XYZZZZZ" />
            <classes>
                <class name="poc.grid.GridTest" />
            </classes>
        </test>

<test name="Test2">
        <parameter name="deviceName" value="ZYXXXXX" />
            <classes>
                <class name="poc.grid.GridTest" />
            </classes>
        </test>

</suite>

5. And I wrote a GridTest.java class like:

package poc.grid;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.util.concurrent.TimeUnit;

import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.remote.DesiredCapabilities;
    import org.openqa.selenium.remote.RemoteWebDriver;
    import org.testng.annotations.Parameters;
    import org.testng.annotations.Test;

public class GridTest {

@Parameters({"deviceName"})
        @Test
        public void test (String deviceName) throws MalformedURLException, InterruptedException
        {
            appium_driver(deviceName);
        }

public void appium_driver(String deviceName)
        {
            try
            {
                DesiredCapabilities capabilities = new DesiredCapabilities();
                capabilities.setCapability("deviceName", deviceName);
                capabilities.setCapability("platformName", "Android");

if(deviceName.equalsIgnoreCase("4d0025b440ca90d5")){
                    capabilities.setCapability("app", "/XXXXXX/chocolate.apk");
                }else{
                    capabilities.setCapability("app", "/XXXXXX/chocolate.apk");
                }

capabilities.setCapability("newCommandTimeout", "120");
                WebDriver driver = new RemoteWebDriver(new URL("http://WHERE_HUB_RUNNNING_IP:4444/wd/hub"), capabilities);

driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
            }
            catch(Exception e)
            {
                System.out.println(e.getMessage());
                e.printStackTrace();
            }
        }
    }

6. If you are using eclipse, then Right Click on testNG.xml and select Run As --> TestNg Suite.

7. Now you can see I've kept a condition only for apk file location because the node machines have different directory, if possible you should choose a similar location which exists in all node machines, else you may have to live with if - else.  Hope This Helps !!

Related Problems and Solutions