Automated Mobile App Testing with Python and Nose

May 16th, 2013 by Adam Christian

One of the coolest parts about using Appium for automated functional testing is that you can write your tests in whatever language has the testing tools that suit you best. One of the most popular choices for testing is Python. Writing tests for iOS and Android apps with Appium and Python is easy.

In this post we’ll walk through the steps involved in testing an iOS sample app using Appium’s Python example tests, but the steps for running tests on android are very similar.

To start, fork and clone Appium from https://github.com/appium/appium, and follow the installation instructions to set up Appium on your machine.

We’ll need to install Appium’s dependencies and build the sample apps. To do this, run the following command from the Appium working directory:

$ ./reset.sh --ios

Once the project is built, you can start Appium by running:

$ grunt appium

Now that Appium is running, switch to the sample-code/examples/python directory. Install the dependencies with pip (if you are not in a virtualenv, you will need to use sudo):

$ pip install -r requirements.txt

Then, run the example test:

$ nosetests simple.py

Now that you’re set up to run tests, let’s take a closer look at the example test that we just ran to get an idea of how Appium works. This test launches our demo app, fills in some boxes, clicks a button, and checks for an expected result. First, we create the test class and a setUp method:

class TestSequenceFunctions(unittest.TestCase):

    def setUp(self):
        app = os.path.join(os.path.dirname(__file__),
                           '../../apps/TestApp/build/Release-iphonesimulator',
                           'TestApp.app')
        app = os.path.abspath(app)
        self.driver = webdriver.Remote(
            command_executor='http://127.0.0.1:4723/wd/hub',
            desired_capabilities={
                'browserName': 'iOS',
                'platform': 'Mac',
                'version': '6.0',
                'app': app
            })
        self._values = []

The “desired_capabilities” parameter is used to specify the platform (iOS 6.0) and the app we want to test. Next we’ll add a tearDown method to send the quit command after each test:

    def tearDown(self):
        self.driver.quit()

Finally, we’ll add a helper method that fills in the forms, and the main test method:

    def _populate(self):
        # populate text fields with two random number
        elems = self.driver.find_elements_by_tag_name('textField')
        for elem in elems:
            rndNum = randint(0, 10)
            elem.send_keys(rndNum)
            self._values.append(rndNum)

    def test_ui_computation(self):
        # populate text fields with values
        self._populate()
        # trigger computation by using the button
        buttons = self.driver.find_elements_by_tag_name("button")
        buttons[0].click()
        # is sum equal ?
        texts = self.driver.find_elements_by_tag_name("staticText")
        self.assertEqual(int(texts[0].text), self._values[0] + self._values[1])

That’s it! There are more Python examples in Appium’s sample tests. Please let us know if you have any questions or comments about running Appium’s tests with Nose and Python.

Leave a Comment