Muhammad Ehtsham
Muhammad Ehtsham

Reputation: 9

How 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">
    <classes>
        <class name="tests.PersonalRegistrationTests" />
        <class name="tests.LoginTests"></class>
    </classes>
</test> <!-- Test -->
<test verbose="2" name="Galaxy A20s">
    <classes>
        <class name="tests.PersonalRegistrationTests" />
        <class name="tests.LoginTests"></class>
    </classes>
</test> <!-- Test -->

This is my TestBase.java code

public class TestBase {

static AppiumDriver androidDriver;

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

This is my DeviceUtility.java 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("http://192.168.88.60:4444/wd/hub"), 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.allowLocationPermission();
        registrationScreens.allowContactsPermission();
        registrationScreens.visitOnboardingScreens();
        registrationScreens.selectCountry("United States");
        registrationScreens.enterPhoneNumber("5678911111");
        registrationScreens.sendCode();
        
        Assert.assertTrue(registrationScreens.checkOTPScreenVisibility());
        
    }catch(Exception ex){
        throw new SkipException(ex.getMessage());
    }
    
}

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

Upvotes: 0

Views: 732

Answers (1)

Kundan
Kundan

Reputation: 217

  1. For the setup function instead of @BeforeSuite use @BeforeTest, this will ensure that the function is executed before each test

  2. In the "getAndroidDriver" function you are setting capabilities of only one mobile device. Instead here is how you can frame the solution:

    a. Use "parameters" tag under your test tags of testng xml file b. Set the capabilities value in the parameters e.g. to set device name c. Do it under the other test tag as well for Galaxy A20s

  3. Use @Parameters annotation for the setup function to receive the passed values e.g. @Parameters({"udid", "deviceName"})

  4. Change the setup function definition to accept the parameter values e.g. setUp(String udid, String deviceName)

  5. Send the parameter values received in setup function to getAndroidDriver function.

  6. With above done, your setup and then getAndroidDriver functions will be executed in parallel with two different set of parameter values

Make sure that you also pass the appium port number via parameters tag.

Upvotes: 0

Related Questions