How To Use Selenium for Mobile Cross Browser Testing (with Examples)

Server-side vs. Client-Side Run with Appium

Dear Testdroiders,

We’ve highlighted Appium here at Testdroid blog every week and primarily our focus has been in mobile app and game testing. As you know, Appium is based on the WebDriver JSON Wire Protocol and therefore works extremely well also for mobile web testing. Being a subset of the Selenium, it also provides infrastructure, platform and language-agnostic interface that is compatible with all major web browsers – also on Android and iOS.

In this blog I’ll walk you through a basic example of how to use Appium / Selenium for mobile cross browser testing using real Android and iOS devices and real web browsers on these platforms.

selenium_appium_2016

As said, Appium works really well as a bridge between the mobile test automation approach and web testing done with Selenium WebDriver. With Appium, the power of Selenium in web testing can be now taken on mobile devices and more importantly – mobile browsers and do mobile cross browser testing across different browsers and device configurations. One of the greatest things with this kind of combination is that it fits perfectly into agile process and makes full use of test automation – but now also for mobile web. You can use Appium to write Selenium test scripts for mobile browsers and then easily scale the number of devices and browsers you use for testing up to hundreds.

Download The Guide to Succeed in Mobile Cross Brower Testing

Mobile Cross Browser Testing with Any Language for All Platforms

Another awesome aspect of Appium / Selenium is that it works with any programming language as well as both these major OS platforms (Android and iOS). These means you have more freedom on language you use and you can build the same script for both of these OS platforms. The same test script, API and the workflow backs up testing on native apps, mobile games, hybrid apps and the mobile web. Furthermore, your application either as APK or IPA doesn’t need any modifications or tweaks to make it testable with Appium.

As Appium is an open source project that can be downloaded and use freely to run tests on your localhost with emulators and real devices, we always recommend using real devices and real browsers for testing efforts done on any sort of mobile product targeted for mass audience. There are several things you should take into consideration whether using emulators or real devices, but the fact is that all end-users using your stuff will use those real devices. Getting something ‘verified’ on emulators unfortunately doesn’t mean much. In fact, it maybe even difficult – if not impossible – to get certain mobile web browsers working on emulators.

There are different test automation approaches available for Appium: client-side and server-side execution. The following picture illustrates the difference between these two:

Screen Shot 2016-01-21 at 12.34.02 PM

 

The difference between running your test script from localhost and running it on Testdroid Cloud is really small, but benefits are different. In both cases your test script would run the app or website on those mobile devices (and web browser) we host at Testdroid Cloud. In server-side execution you don’t need to configure desired capabilities but things work based on your preferences. For the cross browser testing and having your website running on as many devices and browsers as possible before you launch or made something available for users is always highly recommended. And good news is that both of these approaches are usable for your cross browser testing.

Let’s look at the example how a simple test can be created using Python and have it executed on a real device and real browser on cloud.

Python Example – Run Mobile Web Tests on Real Web Browser

I’ll be using Python here and if you need any instructions on how to set up Python, Selenium and any other required component, take a look at this. It provides a step-by-step instructions on how to get everything properly installed.

First in your test scrips import the following modules:

import os
import time
import unittest
from time import sleep
from selenium import webdriver
from device_finder import DeviceFinder

You can find device_finder.py at Github. Simply download it and locate this file on the same folder where you’ll be running your Python test script.

To make test script output real-time information about the progress or any information that you might need while test is running, it’s a good idea to write few helper functions – for example, to output ‘debugging’ information to your console:

def log(msg):
    print (time.strftime("%H:%M:%S") + ": " + msg)

If you are running the test on server-side this data will be available on Appium log that you find under Device Run view at Testdroid Cloud:

Screen Shot 2016-01-21 at 1.25.15 PM

When tests are executed simultaneously on variety of different devices (regardless whether those are Android or iOS) you should always strive to take screenshots as they will illustrate how the app looks on device and if there are any visual aspects to be fixed. Simply, create a function for taking and saving screenshots with the following function:

def screenshot(self, name):
    self.screenShotCount = 1
    screenshotName = str(self.screenShotCount) + "_" + name + ".png" 
    log ("Taking screenshot: " + screenshotName)
    sleep(1) # wait for animations to complete before taking screenshot
    self.driver.save_screenshot(self.screenshotDir + "/" + screenshotName)
    self.screenShotCount += 1

After your test run is done the taken screenshots will be available on Test Run view:

Screen Shot 2016-01-21 at 1.31.22 PM

Or if you are using client-side execution and you want to fetch screenshots to your local environment, you defined this with TESTDROID_SCREENSHOTS environment variable:

self.screenshotDir = os.environ.get('TESTDROID_SCREENSHOTS') or "/Users/vvh/pywebtest/screenshots"

In order to establish connection between your localhost and Testdroid Cloud, you’ll need to configure these few parameters:

testdroid_url = os.environ.get('TESTDROID_URL') or "https://cloud.testdroid.com/"
testdroid_apiKey = os.environ.get('TESTDROID_APIKEY') or "123456789abcdefghijklmnopqrstuvx"
appium_url = os.environ.get('TESTDROID_APPIUM_URL') or 'http://appium.testdroid.com/wd/hub'

Note that we’re now using API Key to authorize access between the localhost and Testdroid Cloud. The API Key can be fetched from Testdroid Cloud -> your profile (top right corner) -> My account and API key. Simply copy that and paste in to your testdroid_apiKey variable:

Screen Shot 2016-01-21 at 1.37.58 PM

The next thing to do is to secure any available device for your test session. We’ve built a basic device finder function to help in that and speed up the device acquisition for your test runs. Basically it will go through available devices and pick you the one. Furthermore, you can define the device with testdroid_device variable. You can find more information – as well as some tips and tricks using this function in this blog.

deviceFinder = None
testdroid_device = os.environ.get('TESTDROID_DEVICE') or "Samsung Galaxy Tab 3 10.1 GT-P5210 4.4.2"
     
deviceFinder = DeviceFinder(url=testdroid_url)
   if testdroid_device == "":
      # Loop will not exit until free device is found
      while testdroid_device == "":
            testdroid_device = deviceFinder.available_free_android_device()

If you want to find available iOS device for your test session, you would use available_free_ios_device instead of deviceFinder.available_free_android_device() in that last line.

Setting Up Desired Capabilities

If you are using client-side execution you basically need to have all these desired capabilities properly configured in your test script. With the server-side execution, there is no need to configure any of those as app and test is already uploaded on our server and it will fetch all this information based on your projects, device selections and test run preferences.

Here is the example for desired capabilities on client-side execution:

desired_capabilities_cloud = {}
desired_capabilities_cloud['testdroid_apiKey'] = testdroid_apiKey
desired_capabilities_cloud['testdroid_target'] = 'chrome'
desired_capabilities_cloud['testdroid_project'] = 'Appium Chrome Webtest Demo'
desired_capabilities_cloud['testdroid_testrun'] = 'Test Run 1'
desired_capabilities_cloud['testdroid_device'] = testdroid_device
desired_capabilities_cloud['platformName'] = 'Android'
desired_capabilities_cloud['deviceName'] = 'AndroidDevice'
desired_capabilities_cloud['browserName'] = 'chrome'
desired_caps = desired_capabilities_cloud;

These desired capabilities can be configured based on your preferences, how and on what device you want tests to be executed.

Using Real Devices and Browsers with Selenium

To launch several simultaneous device runs (devices running your tests at the same time) you can build an instigator script with array of devices to specify all devices you want to start your run on:

AndroidDeviceList = [“Acer Iconia Tab 8 A1-840FHD US”, 
                        “Asus Google Nexus 7 ME370T 4.3 JWR66Y”,
                        “Dell Venue 8 3840 EU”,
                        “HTC One M7 5.0.2”,
                        “HTC One M9”,
                        “Huawei Honor 6 H60-L01”,
                        “LG Google Nexus 5 6.0”,
                        “Lenovo Lemon K3 K30-T”,
                        “Motorola DROID RAZR HD XT926”,
                        “Motorola Google Nexus 6 XT1100 5.1 EU”,
                        “NVIDIA Shield Tablet”,
                        “Samsung Galaxy Note 5 SM N920R4”,
                        “Samsung Galaxy S5 SM-G900T (T-Mobile) -US”,
                        “Samsung Galaxy Tab 4 10.1 SM-T530NU”,
                        “Sony Xperia Tablet Z”,
                        “Sony Xperia Z SO-02E (Sony Yuga)”,
                        “Xiaomi MI 3 (Tegra 4 powered)”,
                        “Xiaomi Redmi 2 LTE”,
                        “Yota Phone 2 YD201”,
                        “ZTE V5 Red Bull U9180”
]
...
for each device in AndroidDeviceList:
    testdroid_device =  DeviceFinder.getDevice(device)
       if testdroid_device is not None:
          break

With the server-side execution this would be very convenient as you can manually select on which device group you want to use for test session:

Screen Shot 2016-01-21 at 2.03.56 PM

 

Once the device selection is done, you can also specify which browser will be used for the test session (as set in ['browserName'] = 'chrome' variable). With Android we support pretty much any browser available (however, typically the only meaningful ones are the Android Browser or Chrome) and on iOS Safari is pretty much the one you want to use for your test session.

Creating and Running A Mobile Browser Test

After all these steps have been done, let’s look how to use WebDriver to get test running. First, you need to initiate the WebDriver. Note that if you are using client-side execution this really may take some time as the device will be prepared for your session. If you didn’t use Finder Device, the device may not be either available and WebDriverException is thrown saying that device could not be acquired in certain time.

log ("WebDriver request initiated. Waiting for response, this typically takes 2-3 mins")
self.driver = webdriver.Remote(appium_url, desired_caps)

To specify which web page will be used for testing will be done next, with the action to take a screenshot of it, as follows:

log ("Loading page http://bitbar.com/testing/")
self.driver.get("http://bitbar.com/testing/")
log ("Taking screenshot of home page: '1_home.png'")
self.driver.save_screenshot(self.screenshotDir + "/1_home.png")

Next you can call some interaction (e.g. click) on certain UI elements or links on that page – and take the screenshot of the view:

log ("Finding 'Solutions'")
elem = self.driver.find_element_by_xpath('//*[@id="menu"]/ul/li[1]/a')
log ("Clicking 'Solutions'")
elem.click()
log ("Taking screenshot of 'Products' page: '2_products.png'")
self.driver.save_screenshot(self.screenshotDir + "/2_products.png")

Furthermore, you can use XPath locators to find certain elements in that web page.

Quit the WebDriver Session

Finally, you can call tearDown to quit WebDriver:

def tearDown(self):
   log ("Quitting")
   self.driver.quit()

If you are interested to fetch this example we just walked through you can find the template at Github.

Happy Web Testing folks!


The Beginner’s Guide of Using Appium for Mobile App Testing

Learn all the basics about Appium, how to set it up and how to use it for mobile app testing.

Download

By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close