How to execute appium tests parallel on different devices using appium grid

GOAL: As I’m new to Appium. I’m trying to automate Appium test parallel on multiple android devices using Appium grid on Ubuntu.
I’ve successfully started a Grid hub server and 2 nodes with different ports.
ISSUE: Unable to run test cases on both devices at the same time (I’m sure the issue is with how I’m designing my Framework). I don’t know how to pass the capabilities of both devices and start the devices at the same time (MAJOR PROBLEM). Do I have to use multi-threading for this, if yes then how?
ACTUAL: When I run multiple test classes on the same device, it works but as I have only a single instance of Android Driver in my BaseTest class, I’m unable to run parallel.
WHAT I TRIED: I went through so many threads on google but was unable to find the exact solution.
This is my testng.xml code

<suite name="Functional" parallel="tests" thread-count="2">
<test verbose="2" name="Pixel 4a">
        <class name="tests.PersonalRegistrationTests" />
        <class name="tests.LoginTests"></class>
</test> <!-- Test -->
<test verbose="2" name="Galaxy A20s">
        <class name="tests.PersonalRegistrationTests" />
        <class name="tests.LoginTests"></class>
</test> <!-- Test -->

This is my code

public class TestBase {

static AppiumDriver androidDriver;

public void setup() {
    try {
        androidDriver = DeviceUtility.getAndroidDriver();
    } catch (Exception exp) {
        System.out.println("Message is : " + exp.getMessage());

This is my code

public static AppiumDriver getAndroidDriver() throws Exception {
    DesiredCapabilities capability = new DesiredCapabilities();
    AppiumDriver androidDriver;
    try {
        capability.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
        capability.setCapability(MobileCapabilityType.PLATFORM_VERSION, "11.0");
        capability.setCapability(MobileCapabilityType.DEVICE_NAME, "Pixel 4a");
        capability.setCapability(MobileCapabilityType.UDID, "09091JEC214196");
        capability.setCapability(MobileCapabilityType.APP, System.getProperty("user.dir") + getApkRelativePATH());
        androidDriver = new AndroidDriver<MobileElement>(new URL(""), capability);
        androidDriver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
        return androidDriver;
    } catch (Exception ex) {
        throw new Exception("Error : " + ex.getMessage());

And this is a test sample.

public class PersonalRegistrationTests extends TestBase{

@Test(priority = 1)
public void verifyRegistrationWithSupportedCountry() throws Exception { 
    RegistrationScreens registrationScreens = new RegistrationScreens(androidDriver);
    try {
        registrationScreens.selectCountry("United States");
    }catch(Exception ex){
        throw new SkipException(ex.getMessage());

Where am I doing wrong in my Framework? Thanks in advance :slight_smile:

This is fist problem. Static means all tests use same driver. While expected each test uses own driver. ‘androidDriver’ should be thread safe variable.

Second problem. Driver init should start in ‘beforeMethod’ which means right before each test. In your example you start driver only one time with first test.

Third problem you should start 2 appium servers with different port settings. Each driver init should use it own appium server and use same ports as started appium servers. Appium servers better start one time and run till last test completed. So ‘beforeSuite’ start appium servers and ‘afterSuite’ stop them.

More about servers and ports: