Search code examples
androidtestingadbappiumgenymotion

Issue with identifying genymotion emulators from appium command


I'm using Appium for Android testing with a Genymotion emulator. I have several emulators, and what I'm trying to do is build a script that tests my app on every emulator one after the other (and in parallel). The script starts an emulator, tests the app on it and then shuts it down.

To that end, I need to feed the appium command with a specific device identifier on each iteration (this is crucial, as there is more than one emulator running at any given time):

appium --udid XXXXXXXX

Appium then runs adb with the -s XXXXXXXX parameter.

The problem is that Genymotion emulators do not display udid serials, and instead when running adb I see the address:port that were assigned to the device on startup, and these cannot be used for automation as they are unpredictable.

I have found that adb can call a specific device using parameters other than the udid by specifying the property to use. This way, all I need to do is use the model of the emulator and everything should work:

adb -s model:Google_Nexus_4___4_4_4___API_19___768x1280

However, when I try to incorporate this into Appium like so:

appium --udid model:Google_Nexus_4___4_4_4___API_19___768x1280

I get the following error:

[36minfo[39m: Retrieving device
[36minfo[39m: [debug] Trying to find a connected android device
[36minfo[39m: [debug] Getting connected devices...
[36minfo[39m: [debug] executing cmd: /Users/mor/Library/Android/sdk/platform-tools/adb devices
[36minfo[39m: [debug] 2 device(s) connected
[36minfo[39m: [debug] Sent shutdown command, waiting for UiAutomator to stop...
[33mwarn[39m: UiAutomator did not shut down fast enough, calling it gone
[36minfo[39m: [debug] Cleaning up android objects
[36minfo[39m: [debug] Cleaning up appium session
[36minfo[39m: [debug] Error: Device model:Google_Nexus_4___4_4_4___API_19___768x1280 was not in the list of connected devices

This obviously means that Appium first runs adb devices and only then tries to match the udid with the one given in the parameter, so no luck there.

Does anyone have a solution/workaround to this problem?


Solution

  • You should be able to get the udid using adb

    adb -s model:Google_Nexus_4___4_4_4___API_19___768x1280 shell settings get secure android_id
    

    Then give this to appium.

    If you need to pass it into a command line (and you have a bash shell) you can use xargs

    adb -s model:Google_Nexus_4___4_4_4___API_19___768x1280 shell settings get secure android_id | xargs -I myudid appium --udid myudid
    

    EDIT from more details in questions:

    adb devices | grep `adb -s model:Google_Nexus_4___4_4_4___API_19___768x1280 shell ip route | cut -d" " -f1 | cut -d"/" -f1` | sed "1 d" | cut -f 1 | xargs -I ip appium --udid ip 
    

    EDIT by question author:

    When using adb -s model:Google_Nexus_4___4_4_4___API_19___768x1280 shell ip route on a Genymotion device, the result looks like this:

    default via 10.0.3.2 dev eth1
    default via 10.0.3.2 dev eth1  metric 205
    10.0.3.0/24 dev eth1  scope link
    10.0.3.0/24 dev eth1  proto kernel  scope link  src 10.0.3.15  metric 205
    10.0.3.2 dev eth1  scope link
    192.168.56.0/24 dev eth0  proto kernel  scope link  src 192.168.56.101
    

    My working command:

    adb -s model:Google_Nexus_4___4_4_4___API_19___768x1280 shell ip route | grep "eth0" | rev | cut -d" " -f2 | rev | cut -d" " -f1
    

    As far as I know, the port is always defaulted to 5555, so this way I get the address and can build my own "udid" for the appium command.