Often we wanted to perform mobile execution in parallel. The best way of performing the parallel execution is through selenium grid. I’ve faced few issues while setting up the grid for appium. I’ll share my learnings about setting up the grid for appium mobile automation.
Pre-requisites
- Download selenium standalone server jar file – At the time of writing, the version of latest selenium is 2.53.
- Appium – The version that I was using is 1.4.16 and installed as Node npm package. I recommend to you also use npm package.
- Atleast two android devices for this experiment.
Setup the selenium grid
Place the downloaded selenium standalone server jar in some directory. In my case I’ve placed in /Users/<username>/Tools/selenium.
Open your terminal and navigate to the directory to where you placed the jar file and execute the following command:
[code language="bash"]
java -jar selenium-server-standalone-2.53.0.jar -role hub
[/code]
This will start the selenium grid server in your local ip with the default port of 4444. After you see this message Selenium Grid hub is up and running, open your browser and hit the following url:
http://<your ip>:4444/grid/console and you should be able to see the following in your browser:

Congratulations!!! You started your grid successfully. Let’s setup the nodes for our mobile devices.
Setup the Appium nodes
I’ve two devices with me now, samsung S4 and samsung S5. I’m going to setup grid nodes for these two devices.
As per the documentation of appium here, we need a node config json file to hook our appium node to our selenium grid hub. Let’s prepare our 1st node config json and I’m calling that as node_s4.json:
[code language="javascript"]
{
"capabilities": [
{
"applicationName": "Samsung S4",
"browserName": "Samsung S4",
"platformName": "ANDROID",
"maxInstances": 1
}
],
"configuration": {
"cleanUpCycle": 2000,
"timeout": 30000,
"proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy",
"host": "127.0.0.1",
"port": 4723,
"maxSession": 1,
"register": true,
"registerCycle": 5000,
"hubPort": 4444,
"hubHost": "192.168.0.198"
}
}
[/code]
Here applicationName is mandatory since the grid identifies to which appium node the job should b e routed. Also, make sure you change the hubHost to your ip address.
Now let’s start our appium node with this node config. In your terminal, start your appium like this:
[code language="bash"]
appium –nodeconfig /Users/<<username>>/Tools/selenium/node_s4.json -p 4723 -bp 4724 -U <<s4 device id>>
[/code]
This will start the appium server on the port 4723 and the bootstrap port 4724 (remember, the bootstrap port is mandatory for android devices) and with the device id of your device which you can get from adb devices.
Now refresh your grid console in your browser and you should see this:

Do the same for another device. In my case, the node json for samsung S5 device will look like:
[code language="javascript"]
{
"capabilities": [
{
"applicationName": "Samsung S5",
"browserName": "Samsung S5",
"platformName": "ANDROID",
"maxInstances": 1
}
],
"configuration": {
"cleanUpCycle": 2000,
"timeout": 30000,
"proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy",
"host": "127.0.0.1",
"port": 4730,
"maxSession": 1,
"register": true,
"registerCycle": 5000,
"hubPort": 4444,
"hubHost": "<<your ip>>"
}
}
[/code]
Changed the applicationName, browserName and port of appium node, and saved the file as node_s5.json. Now start your 2nd appium node in another terminal like this:
[code language="bash"]
appium –nodeconfig /Users/<<username>>/Tools/selenium/node_s5.json -p 4730 -bp 4731 -U <<s5 device id>>
[/code]
Refresh your browser and you should see this in your grid console page:

Voila!!! We have two appium nodes connected to our selenium hub.
In your test now, add the applicationName as part of your desired capabilities and point to the grid url instead of appium url. For example, my DesiredCapabilities and driver instantiation would look like:
[code language="java"]
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("platformName", "Android");
capabilities.setCapability("deviceName", "Android");
capabilities.setCapability("applicationName", "Samsung S4");
capabilities.setCapability("app", "ApiDemos-debug.apk");
capabilities.setCapability("appPackage", "io.appium.android.apis");
capabilities.setCapability("appWaitActivity", "io.appium.android.apis.ApiDemos");
capabilities.setCapability("noReset", true);
driver = new AndroidDriver(new URL("http://<your ip>:4444/wd/hub/"), capabilities);
[/code]
This will execute tests on Samsung S4 device.
Mistakes done and Lessons learnt
- applicationName – I spent more time on solving this issue. I was using dataProvider to execute tests in parallel. Even I was having 2 nodes setup, always grid was routing my tests to one node only. This was the haunting problem. Make sure you have this applicationName in your capabilities. The selenium default capability matcher explains about this. Follow this blog for more information: Rationale Emotions.
- nodeconfig – Even though you start your appium from the same directory where you placed the node config json files, you should provide the absolute path of the node config json for the parameter –nodeconfig while starting your appium server.
- UDID – Make sure you start your appium server with the -U parameter with your device id in case you have more than one device. The reason is appium always selects the first device in your device list.
There will be a followup post on how I performed parallel execution using this grid setup. Coming Soon!!!
Good one
my script is working on only one node i also using applicationName my json as
{
"capabilities": [{
"applicationName": "5.0.2Android",
"browserName": "5.0.2Android",
"version": "5.0.2",
"maxInstance": 1,
"platform": "ANDROID"
}
],
"configuration":
{
"nodeTimeout": 120,
"port": 4725,
"hubPort": 4444,
"proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy",
"hubHost": "10.2.10.45",
"host": "127.0 .0 .1",
"role": "node",
"nodePolling": 2000,
"register": true,
"registerCycle": 1000,
"cleanUpCycle": 2000,
"timeout": 30000,
"masSession": 1
}
}
hi can you please share your testng.xml file i am stuck in it
Hi Pushpank,
Kindly refer this post: http://www.vimalselvam.com/2016/07/24/appium-parallel-execution-using-testng/
How to run the hub and nodes from the java code?
Why do you want to do that? But to answer your question you can simply use ProcessBuilder to run your selenium server as hub and use AppiumDriverLocalService to create node at run time. But I’m against on doing this, since I prefer my hub and nodes should be running always.
Thanks for your answer. I want to run my tests cycle with one click so I can run it over and over again with maven. When I run the hub and nodes manually, all devices run on first cycle but on the second one only one device run. So I need to close the hub and all nodes and rerun them again on every new cycle.
You can pretty much do it with Java. But I prefer to do this using shell script. And I hook my shell script into Jenkins as pre build script.
hi vimal
can u share me code to create batch file to execute on mac machine as like windows using shell script or something
I don’t have any script ready with me since I’ve never came across the situation where I’ve to run things using script. A simple maven based jenkins job is itself keeping me happy to run my tests. I would recommend you to try out and reach out to me for any help in case you are stuck at any specific point.
Hey Vimal,
Thanks a ton for detailed info, I was struck for 2 days with this issue and it solved.
You’re my hero of the day 🙂
Regards,
Vikram
Glad it helped you Vikram
Hi,
How to do the same thing on Mac? I mean the commands to run on multiple devices. Can you please help?
The example given here was ran in Mac only
Hi Vimal,
can you please clarify “…I was using dataProvider to execute tests in parallel….”. I’m trying to run tests in parallel with help maven surefire / failsafe plugin but no success yet.
Thanks & Regards,
Vikram
Where are you stuck? Kindly share the details and I’ll try to help you.
HI Vimal,
I have to execute parallel test on mobile browser
This is how I started appium node
{
“capabilities”: [
{
“applicationName”: “Lenovo K4 Note”,
“browserName”: “Lenovo K4 Note”,
“platformName”: “ANDROID”,
“maxInstances”: 1
}
],
“configuration”: {
“cleanUpCycle”: 2000,
“timeout”: 30000,
“proxy”: “org.openqa.grid.selenium.proxy.DefaultRemoteProxy”,
“host”: “127.0.0.1”,
“port”: 4757,
“maxSession”: 1,
“register”: true,
“registerCycle”: 5000,
“hubPort”: 4444,
“hubHost”: “10.98.13.204”
}
}
here is driver initialization code
AppiumDriver appiumDriver ;
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, “Android”);
capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, “Android”);
capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, “Lenovo K4 Note”);
// capabilities.setCapability(MobileCapabilityType.”noReset”, true);
capabilities.setCapability(MobileCapabilityType.BROWSER_NAME, “Lenovo K4 Note”);
try {
appiumDriver = new AndroidDriver(new URL("http://10.98.13.204:4444/wd/hub"), capabilities);
} catch (Exception e) {
System.out.println("Error while trying to initialize android Driver");
e.printStackTrace();
}
attached node to selenium grid using
appium –nodeconfig C:\Users\dmore\Desktop\selenium\appium_nodes\lenovo_k4_note.json -p 4757 -bp 4758 -U 10.98.4.37:5555
Giving below error
org.openqa.selenium.SessionNotCreatedException: A new session could not be created. (Original error: No app set; either start appium with –app or pass in an ‘app’ value in desired capabilities, or set androidPackage to launch pre-existing app on device) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 175 milliseconds
Build info: version: ‘2.46.0’, revision: ’87c69e2′, time: ‘2015-06-04 16:16:47’
System info: host: ‘MTO37914GU1376C’, ip: ‘10.98.13.204’, os.name: ‘Windows 7’, os.arch: ‘amd64’, os.version: ‘6.1’, java.version: ‘1.8.0_102’
Driver info: io.appium.java_client.android.AndroidDriver
In your DesiredCapabilities, you are passing an automationName. It should be applicationName.
Next, there is not browser called Lenovo K4 note. The browser name should either be chrome if you want to automate on chrome browser or just browser if native browser. Make sure you change this in you desired capabilities and node capabilities.
Hi guys!, Thanks for the post.
I wish to generate the reports using this setup with Extent Reports and TestNG but I am unable to do so.
Could you explain the setup if we wish to do that?.
Thanks in advance.
Where are you stuck? It would be great if you can provide more information on the issue to help you.
Hey Vimal,
this is not working with current version of appium server and selenium server 3.4.0
can you please clarify if this still working for you and if yes which version of appium & selenium are you using ?
Thanks,
Vikrma