Appium Parallel test runs on both platform

I have appium 2.0 java project thats works in one thread and everyfing is ok, but when I start to use a few devices all set ups is ok, but tests isnt started, only app started, for test using PageFactory. I set ports and udids in my code with methods

`public class Base extends SetDrivers {

@BeforeClass
public void setDriverToApp() throws IOException {
    List<Devices> devices = getAllConnectedDevices();

    for (Devices device : devices) {
        if (device.getPlatformName().equalsIgnoreCase("ios")) {
            SetDrivers.setIOSDriver(device);
        } else if (device.getPlatformName().equalsIgnoreCase("android")) {
            SetDrivers.setAndroidDriver(device);
        } else {
            System.out.println("No devices connected");
        }
    }
}

}`

I iterate all connected devices and send it udid to its driver

`    public static AppiumDriver getDriver() {
    return driver.get();
}

public static void setDriver(AppiumDriver driver) {
    SetDrivers.driver.set(driver);
}

public static ThreadLocal<AppiumDriver> driver = new ThreadLocal<>();`

`  public static int getFreePort() throws IOException {
    ServerSocket socket = new ServerSocket(0);
    int port = socket.getLocalPort();
    socket.close();
    return port;
}

public static void setIOSDriver(Devices device) throws IOException {
    var xcuiTestOptions = new XCUITestOptions();
    xcuiTestOptions.setPlatformName("IOS");
    xcuiTestOptions.setUdid(device.getUdid());
    xcuiTestOptions.setFullReset(false);
    xcuiTestOptions.setWdaLocalPort(getFreePort());
    xcuiTestOptions.setApp(System.getProperty("user.dir") + "app.ipa");
    xcuiTestOptions.setCapability("appium:xcodeOrgId", "xxxxx");
    xcuiTestOptions.setCapability("appium:xcodeSigningId", "xxxx");

    setDriver(new IOSDriver(service.getUrl(), xcuiTestOptions));
    setHelpers(getDriver());
}

public static void setAndroidDriver(Devices device) throws IOException {
    var uiAutomator2Options = new UiAutomator2Options();
    uiAutomator2Options.setPlatformName("Android");
    uiAutomator2Options.setApp(System.getProperty("user.dir") + "//app.apk");
    uiAutomator2Options.setFullReset(false);
    uiAutomator2Options.setUdid(device.getUdid());
    uiAutomator2Options.setSystemPort(getFreePort());
    uiAutomator2Options.setMjpegServerPort(getFreePort());
    uiAutomator2Options.setChromedriverPort(getFreePort());
    uiAutomator2Options.setUnlockType("pin");
    uiAutomator2Options.setUnlockKey("xxxx");
    uiAutomator2Options.setCapability("skipChromeDownload", false);
    uiAutomator2Options.setCapability("appium:testTagsAsResourceId", true);
    uiAutomator2Options.setCapability("appium:disableIdLocatorAutocompletion", true);
    uiAutomator2Options.setCapability("appium:enableMultiWindows", true);
    uiAutomator2Options.setCapability("appium:allowInvisibleElements", true);
    setDriver(new AndroidDriver(service.getUrl(), uiAutomator2Options));
    setHelpers(getDriver());
}`

testng xml sample is:

<test name="Device 1" >
    <classes>
        <class name="tests.testpackage.Test"/>
    </classes>
</test>
<test name="Device 2" >
    <classes>
        <class name="tests.testpackage.Test"/>
    </classes>
</test>
<test name="Device 3" >
    <classes>
        <class name="tests.testpackage.Test"/>
    </classes>
</test>

Get error org.openqa.selenium.SessionNotCreatedException: Could not start a new session. Response code 500. Message: An unknown server-side error occurred while processing the command. Original error: Could not proxy command to the remote server. Original error: socket hang up

1 Like

I think you need to set certain other ports. Here’s some reading material:

https://appium.io/docs/en/advanced-concepts/parallel-tests/

https://www.headspin.io/blog/running-multiple-appium-tests-in-parallel

https://medium.com/quinbay/appium-with-parallel-execution-part-1-db44cc1c2458

1 Like

Thanks for your answer, I read the Appium with Parallel Execution: PART — 1 | by Shreyas Jain S | Quinbay | Medium approach2, and appium can manage a few device with 4723 port, that in my code.
You say that i i must set port from 8100 -8199?
But I dont know how to set it dynamically, i dont want to harcode ports, cause it need additional classes to every device. Or it`s mandatory for that case?

appreciate your help in that question

I don’t like to act like I’m an authority on this, but I do try to help.

For the ports, it’s not clear from the getFreePort() method what port you will get. Maybe you could add a parameter to that method that restricts it to getting a free port within a certain range. It’s also important that the Appium server knows what ports you are using, which is something I don’t see in your code, but maybe just didn’t include that.

My best advice is to play around with the code provided in those links and find out what suits your needs and coding style. There is some really good advice on this subject in those links, but more is just a web search away if these don’t work for you.

1 Like

This task requires more research. Thanks for advices, i will try to use them.
If you will have more information, please reply to this thread.

this url must be unique per device. you did not add this function code to check.

Aleksei, thanks for answer. For start Appium server i use this function
public class AppiumManage {

static AppiumDriverLocalService service;

@BeforeSuite
public static AppiumDriverLocalService runAppium() {

        service = new AppiumServiceBuilder()
                .withIPAddress("127.0.0.1")
                .usingPort(4723)
                .build();
        service.start();
        System.out.printf("Appium server started on url: '%s'%n",
                service.getUrl()
                        .toString());

    return service;
}

I want to run 1 Appium server, so can I just run this server, and when set driver I must
setDriver(new AndroidDriver(“localhost” + port, uiAutomator2Options));
Where port is the same port like in this setup uiAutomator2Options.setSystemPort(getFreePort());
?

does not work. you should run same number of appium servers as phones you have. each of appium server should use unique port. If you run all in ONE thread all works - same as you wrote. But in parallel it will not work.

Do I need to set this ports in testng.xml, or can I set port ramdom when appium bilder class and the same port in systemPort capability and URL in my code, for every appium server?

It all up to you. Hardly i can reccomend.