Get started with mobile automation: Appium & Python

Problem: There is a perception among testers that getting started with mobile automation is hard.

Why this post?

I strongly believe that a tester must have a wide range of skills. You do not need to be an expert in all of them, but it is extremely important to have contemplated a spectrum of concepts and explored a variety of tools. The context under which you test will inform you of the specific choice of testing methodology and test tools to choose. The more options you are aware of, the better your context-specific choice is going to be. In this regard, I began noticing that mobile testing has become somewhat of a niche among testers. Testers are reluctant to get started with mobile testing – probably because they think getting started involves a lot of time and effort. At Qxf2 Services, we have decided to tackle the problem head-on. This post is the second in a series of quick, easily consumable tutorials geared towards hands-on testers looking to start exploring the mobile testing landscape.

NOTE: In this post we are concentrating only on the “getting started” phase. The tools your test team uses to solve the specific and unique problems can greatly vary. There is no one silver bullet.


A little bit of history

On the eve of Christmas 2013, Selenium officially retired their own AndroidDriver and iPhoneDriver in favour of Selendroid, iosdriver and Appium. In an earlier post we explored using Selendroid and Python. In this post, we will help you get started with Appium.

Appium is an open-source tool you can use to automate mobile native, mobile web, and mobile hybrid applications on iOS and Android platforms. Appium is “cross-platform”: it allows you to write tests on multiple platforms (iOS, Android), using the same API. This enables a large or total amount of code reuse between iOS and Android test suites.


Appium setup

Here are the steps to setup Appium on Windows 7 and use it with Android emulator.
1. Download the latest Appium
I have used appium-desktop-Setup-1.5.0-ia32.exe. You can run the exe to install the appium desktop app
2. Download and Install Android Studio
Once you install Android Studio make sure the AVD Manager is also installed as we are going to run our tests on an emulator. Set ANDROID_HOME to be your Android SDK path and add the tools and platform-tools folders to your PATH variable. I could find the Android SDK installed on the below-mentioned path
$\AppData\Local\Android\Sdk

3. Install the Java JDK
Set JAVA_HOME to your JDK folder
4. Install the Python client library
There are client libraries (in Java, Ruby, Python, PHP, JavaScript, and C#) which support Appium’s extensions to the WebDriver protocol. When using Appium, you want to use these client libraries instead of your regular WebDriver client. I have used the Appium Python client available here. Assuming you have pip installed on your machine, you can use the following command to install it

pip install Appium-Python-Client

Woot! You are now set up. Next stop: launch the emulator and start the Appium server.

5. Start the Android Virtual Device (AVD) Manager
Start the Android Studio and launch the Android Virtual Device (AVD) Manager from by clicking on the link as shown in the screenshot below.
AVD_Manager

Create an emulator with the preferences you need and launch it using the start button
android_emulator
6. Start the Appium server console
Start the Appium server console by double clicking on the Appium file.

start_appium
7. Launch the Appium node server
Click on the ‘rocket’ icon to launch the Appium node server
Launch_Appium
appium_node_server_console


Your first test using Appium

For this test we will use one of my favorite Android apps – the highly recommended Chess Free application created by the UK based AI Factory. For this blog post, we will pretend that our test is to launch the application and click on “PLAY” button.

1. Obtain the .apk for the application under test
We obtained the .apk for Chess Free over here. Copy the chess application to a directory of your choice. I used ($Directory_Of_My_Choice\apps\Chess Free.apk )
2. Peek into the AndroidManifest.xml
To write the test, you need two pieces of information specific to your application:
a) Java package of the Android app you want to run
b) Activity name for the Android activity you want to launch your package

You can get this information by running the following command

ANDROID_HOME\sdk\build-tools\android-4.4.2>aapt dump badging path_to_apk_file

aapt_pkg_activity

Another approach is using the AndroidManifest.xml which is present in the root directory of all Android applications and has the information we need. You can use Android Studio to view the AndroidManifest.xml file. Go to Build/Analyze APK and select your apk. Then you can see the content of the AndroidManifset file.

package="uk.co.aifactory.chessfree" and 
android:name=".ChessFreeActivity"

3. Write the test
Create a test script (android_chess.py) in $Directory_Of_My_Choice based on the snippet below. Pay particular attention to the setup() method.

"""
Qxf2: Example script to run one test against the Chess Free app using Appium
The test will:
- launch the app
- click the 'PLAY!' button
"""
 
import os
import unittest
from appium import webdriver
from time import sleep
 
class ChessAndroidTests(unittest.TestCase):
    "Class to run tests against the Chess Free app"
    def setUp(self):
        "Setup for the test"
        desired_caps = {}
        desired_caps['platformName'] = 'Android'
        desired_caps['platformVersion'] = '8.0'
        desired_caps['deviceName'] = 'Pixel'
        # Returns abs path relative to this file and not cwd
        desired_caps['app'] = os.path.abspath(os.path.join(os.path.dirname(__file__),'apps/Chess Free.apk'))
        desired_caps['appPackage'] = 'uk.co.aifactory.chessfree'
        desired_caps['appActivity'] = '.ChessFreeActivity'
        self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
 
    def tearDown(self):
        "Tear down the test"
        self.driver.quit()
 
    def test_single_player_mode(self):
        "Test the Chess app launches correctly and click on Play button"
        element = self.driver.find_element_by_id("uk.co.aifactory.chessfree:id/ButtonPlay")
        element.click()
        sleep(5)
 
#---START OF SCRIPT
if __name__ == '__main__':
    suite = unittest.TestLoader().loadTestsFromTestCase(ChessAndroidTests)
    unittest.TextTestRunner(verbosity=2).run(suite)

4. Run the test
Run the script android_chess.py. The chess application is launched in the test emulator
Run_Chess_App
5. Check the result
appium_test_run

Celebrate a little – you just upgraded your skills by a little bit in a very short span of time!

There you have it! You have just run your first mobile automated test with Appium and Python. If you are looking for Python based mobile automation framework, check out our open-sourced GUI and API automation framework based on the page object model. Happy exploring from Qxf2 Services!

P.S.: As a chess fanatic, I think it is a crime to test chess applications in an automated fashion. I sincerely believe infinite manual testing is the only correct way to test chess applications 😉

P.P.S: We were pleasantly surprised by positive reaction we got to our last tutorial on mobile application testing with Selendroid. Please chime in on the direction you want our future blog posts to go. We will try our best to keep churning out useful posts for testers.


Hire QA consultants from Qxf2

This is an extremely old article but as you can see, Qxf2 was an early adopter of Appium. Not only did we work with Appium, we shared our learnings with the QA community as well. This has been our culture and over the years we have improved and stayed in touch with the rapid changes in the software space. In fact, we have innovated in the QA services domain too. Qxf2 offer several top-notch, unique testing services aimed towards startups that most folks are not aware of. So, if you are working at a startup or on an early-stage product, browse our services and get in touch. After all, every team benefits from having one good technical tester!

110 thoughts on “Get started with mobile automation: Appium & Python

  1. Hi ,
    Thanks again. I did change this but still the error. My appium folder is in the below directory
    C:\BSG\Appium\AppiumForWindows-1.0.0\AppiumForWindows

    My scripts now look like
    ———————————

    import os
    import unittest
    from appium import webdriver
    from time import sleep

    class ChessAndroidTests(unittest.TestCase):
    “Class to run tests against the Chess Free app”
    def setUp(self):
    “Setup for the test”
    desired_caps = {}
    desired_caps[‘platformName’] = ‘Android’
    desired_caps[‘platformVersion’] = ‘4.4.2’
    desired_caps[‘deviceName’] = ’emulator-5554′
    # Returns abs path relative to this file and not cwd
    desired_caps[‘app’] = os.path.abspath(os.path.join(os.path.dirname(__file__),’BSG/apps/Chess Free.apk’))
    desired_caps[‘appPackage’] = ‘uk.co.aifactory.chessfree’
    desired_caps[‘appActivity’] = ‘.ChessFreeActivity’
    self.driver = webdriver.Remote(‘http://127.0.0.1:4723/wd/hub’, desired_caps)

    def tearDown(self):
    “Tear down the test”
    self.driver.quit()

    def test_single_player_mode(self):
    “Test the Single Player mode launches correctly”
    element = self.driver.find_element_by_name(“PLAY!”)
    element.click()
    self.driver.find_element_by_name(“Single Player”).click()
    textfields = self.driver.find_elements_by_class_name(“android.widget.TextView”)
    self.assertEqual(‘MATCH SETTINGS’, textfields[0].text)

    #—START OF SCRIPT
    if __name__ == ‘__main__’:
    suite = unittest.TestLoader().loadTestsFromTestCase(ChessAndroidTests)
    unittest.TextTestRunner(verbosity=2).run(suite)

    ————————————-

    error
    c:\>android_chess.py
    test_single_player_mode (__main__.ChessAndroidTests)
    Test the Single Player mode launches correctly … ERROR

    ======================================================================
    ERROR: test_single_player_mode (__main__.ChessAndroidTests)
    Test the Single Player mode launches correctly
    ———————————————————————-
    Traceback (most recent call last):
    File “C:\android_chess.py”, line 26, in setUp
    self.driver = webdriver.Remote(‘http://127.0.0.1:4723/wd/hub’, desired_caps)
    File “build\bdist.win32\egg\appium\webdriver\webdriver.py”, line 35, in __init__
    super(WebDriver, self).__init__(command_executor, desired_capabilities, browser_profile, proxy, keep_alive)
    File “C:\Python27\lib\site-packages\selenium-2.42.1-py2.7.egg\selenium\webdriver\remote\webdriver.py”, line 73, in __init__
    self.start_session(desired_capabilities, browser_profile)
    File “C:\Python27\lib\site-packages\selenium-2.42.1-py2.7.egg\selenium\webdriver\remote\webdriver.py”, line 121, in start_session
    ‘desiredCapabilities’: desired_capabilities,
    File “C:\Python27\lib\site-packages\selenium-2.42.1-py2.7.egg\selenium\webdriver\remote\webdriver.py”, line 171, in execute
    response = self.command_executor.execute(driver_command, params)
    File “C:\Python27\lib\site-packages\selenium-2.42.1-py2.7.egg\selenium\webdriver\remote\remote_connection.py”, line 347, in execute
    return self._request(command_info[0], url, body=data)
    File “C:\Python27\lib\site-packages\selenium-2.42.1-py2.7.egg\selenium\webdriver\remote\remote_connection.py”, line 415, in _request
    resp = opener.open(request)
    File “C:\Python27\lib\urllib2.py”, line 404, in open
    response = self._open(req, data)
    File “C:\Python27\lib\urllib2.py”, line 422, in _open
    ‘_open’, req)
    File “C:\Python27\lib\urllib2.py”, line 382, in _call_chain
    result = func(*args)
    File “C:\Python27\lib\urllib2.py”, line 1214, in http_open
    return self.do_open(httplib.HTTPConnection, req)
    File “C:\Python27\lib\urllib2.py”, line 1184, in do_open
    raise URLError(err)
    URLError:

    ———————————————————————-
    Ran 1 test in 1.059s

    FAILED (errors=1)

    c:\>

    once again thanks.

    1. Great! You are past the previous error. This error is different. It seems similar to the error that ‘B’ commented on a little earlier. The likely solutions are:
      1. Appium server is not up and running (steps 6 & 7 in the Appium Setup section)
      2. Appium server is running on a port other than 4723 (use netstat or TCPView on Windows to confirm)
      Can you check if your Appium server is up and running?

  2. thanks again.
    here i can see that appium using the port
    > Starting Node Server
    > info: Welcome to Appium v1.0.0 (REV f0a00fab2335fa88cb355ab4dc43a9cd3f3236c0)
    > info: Appium REST http interface listener started on 127.0.0.1:4723
    > info: socket.io started
    > info: Non-default server args: {“address”:”127.0.0.1″,”logNoColors”:true,”avd”:”appium”}

    what when i look on the TCPView i can only see the node.exe on port 4723 and listening.
    do you have an instruction for ubuntu hwo to run this. i can try on ubuntu

    1. Weird. Your previous URLError exception indicates that your script was not able to connect to the Appium Server. Try stopping the server, restarting it and then use a new command prompt to run the script again.

      To setup Appium on Ubuntu,
      1. Install NodeJs: sudo apt-get install nodejs
      2. Install npm: sudo apt-get install npm
      3. Install appium: npm install -g appium
      4. Install the appium client: npm install wd
      5. Start the appium server: appium

      You will need to set up your environment variables in a similar fashion. The rest of the tutorial will be nearly identical between Windows and Ubunutu.

  3. Thanks for this post. It was very useful.
    I’m encountering the following “Access Denied”error.

    E:\ToolEvaluations\Appium_Projects\SampleProj>python android_chess.py
    test_single_player_mode (__main__.ChessAndroidTests)
    Test the Single Player mode launches correctly … ERROR
    ======================================================================
    ERROR: test_single_player_mode (__main__.ChessAndroidTests)
    Test the Single Player mode launches correctly
    ———————————————————————-
    Traceback (most recent call last):
    File “android_chess.py”, line 19, in setUp
    self.driver = webdriver.Remote(‘http://127.0.0.1:4723/wd/hub’, desired_caps)
    File “build\bdist.win32\egg\appium\webdriver\webdriver.py”, line 35, in __init
    __
    super(WebDriver, self).__init__(command_executor, desired_capabilities, brow
    ser_profile, proxy, keep_alive)
    File “C:\Python27\lib\site-packages\selenium-2.43.0-py2.7.egg\selenium\webdriv
    er\remote\webdriver.py”, line 73, in __init__
    self.start_session(desired_capabilities, browser_profile)
    File “C:\Python27\lib\site-packages\selenium-2.43.0-py2.7.egg\selenium\webdriv
    er\remote\webdriver.py”, line 121, in start_session
    ‘desiredCapabilities’: desired_capabilities,
    File “C:\Python27\lib\site-packages\selenium-2.43.0-py2.7.egg\selenium\webdriv
    er\remote\webdriver.py”, line 173, in execute
    self.error_handler.check_response(response)
    File “C:\Python27\lib\site-packages\selenium-2.43.0-py2.7.egg\selenium\webdriv
    er\remote\errorhandler.py”, line 136, in check_response
    raise exception_class(value)
    WebDriverException: Message: ‘\r\nAccess Denied\r\n\r\n\r\n\r\n\r
    \n\r\n

    \r\n\r\n\r\n\r\nAccess Denied (authentication_failed)\r\n\r\n\r\n\r\n\r\n\r\n\r\nYour credentials could not be authenticated: “Credentials are missing.”. Y
    ou will not be permitted access until your credentials can be verified.\r\n\r\n\r\n\r\n\r\nThis is typically cau
    sed by an incorrect username and/or password, but could also be caused by networ
    k problems.\r\n\r\n\r\n\r\n\r\n\r\nFor assistance, contact your network support team.\r\n\r\n\r\n\r\n

    \r\n\r\n\r\n’
    ———————————————————————-
    Ran 1 test in 0.022s
    FAILED (errors=1)

    1. Evelyn, I’m making a wild guess based on past experience with webdriver. Do you have a proxy setup on your machine? If so, try again after removing the proxy settings.

  4. Hi,

    I am trying to run the example in python and the script does not do any thing.
    Any suggestions.

    Thanks

    DeviceName”:”Android”,”app”:”c:\\users\\user\\documents\\visual studio 2012\\Projects\\PythonApplication3\\PythonApplication3\\apps\\ChessFree.apk”,”platformVersion”:”4.2″,”ap]
    > info: Starting android appium
    > info: [debug] Using fast reset? true
    > info: [debug] Preparing device for session
    > info: [debug] Checking whether app is actually present
    > info: [debug] Checking whether adb is present

    Python:
    test_single_player_mode (__main__.ChessAndroidTests)
    Test the Single Player mode launches correctly …

  5. Hi,

    I am trying to run the example in python and the script does not do any thing.
    Any suggestions.

    Thanks

    DeviceName”:”Android”,”app”:”c:\\users\\user\\documents\\visual studio 2012\\Projects\\PythonApplication3\\PythonApplication3\\apps\\ChessFree.apk”,”platformVersion”:”4.2″,”ap]
    > info: Starting android appium
    > info: [debug] Using fast reset? true
    > info: [debug] Preparing device for session
    > info: [debug] Checking whether app is actually present
    > info: [debug] Checking whether adb is present

    Python:
    test_single_player_mode (__main__.ChessAndroidTests)
    Test the Single Player mode launches correctly …

      1. Thanks on your response. The python just hang with:

        test_single_player_mode (__main__.ChessAndroidTests)
        Test the Single Player mode launches correctly …

        Appium:
        > info: Starting android appium
        > info: [debug] Using fast reset? true
        > info: [debug] Preparing device for session
        > info: [debug] Checking whether app is actually present
        > info: [debug] Checking whether adb is present

        Thanks

      2. Eldad,
        Have you done the Android SDK setup as mentioned in step 2?
        Are you able to run ‘adb’ command from the command prompt?

        Following is the snippet for my test run-
        > info: [debug] Checking whether adb is present
        > info: [debug] Using adb from D:\adt-bundle-windows-x86_64-20140321\adt-bundle-windows-x86_64-20140321\sdk\platform-tools\adb.exe
        > info: Retrieving device

      3. Hi,

        Thanks on the help , it worked.
        The issue was wrong platform-tools folder in my PATH variable..

      4. please help me out

        i have a scenario like i need to print all the contacts of the contact list, some contacts are below the screen, it should not print duplicate contacts using appium code.

        can you mail me a code
        [email protected]

  6. can we test a website functionality using appium and selenium scripts??
    i want to create selenium scripts to test a website functionality.

    1. Hi Selva,
      I replied to your comments on other blog regarding swipe functionality.
      “https://qxf2.com/blog/appium-tutorial-python-physical-device/”

  7. Hi Praveen,
    You can perform test on Mobile web apps using appium.

    For this you need to set the browserName in your desired capability to one that you intend to use
    eg: desired_caps[‘browserName’] = ‘Chrome’
    Then you then launch any website using self.driver.get() function.

  8. error: Unhandled error: Error: ENOENT, no such file or directory ‘D:\adt-bundle-windows-x86-20131030\sdk;D:\adt-bundle-windows-x86-20131030\sdk\platform-tools\build-tools’

    I am getting the above error message, Request to help me to sort it out

Leave a Reply

Your email address will not be published. Required fields are marked *