Wednesday, February 20, 2013

PRACTICUM: Selenium 2 Testing Tools Beginner's Guide: Mobile Devices


This is the next installment (in progress) of my PRACTICUM series. This particular grouping is going through David Burns' "Selenium 2 Testing Tools Beginner's Guide".

Note: PRACTICUM is a continuing series in what I refer to as a somewhat "Live Blog" format. Sections may vary in time to complete. Some may go fast. Some may take much more time to get through. Updates will be daily, they may be more frequent. Feel free to click refresh to get the latest version at any given time. If you see "End of Section" at the bottom of the post, you will know that this entry is finished :).

Chapter 7: Mobile Devices

As David rightly points out, Mobile is the current "killer app" for our times. Some might even say it's the "killer paradigm" in the sense it is adding a whole new slew of approaches and considerations to testing. This section will look at how to get into and use three mobile platforms; Android, MobileOpera and iOS.

Note: The tests in question will be using emulators for this chapter. Real app testing, however, should be performed on real devices (the emulator will only tell part of the story).

Creating an Android Emulator

The following example requires three things. First, you need an Android emulator, and to do that, you can download the Android SDK from:

http://developer.android.com/sdk/index.html#download

I called my dowloaded directory android-sdk to be consistent with the book

Next, open a shell window and cd to android-sdk/sdk/tools. Type the following:


./android create avd -n my_android -t 1

‰ "–n my_android" gives the emulator the name "my_android".

‰ –t 1 tells it which version of android to use. "1" gives us Android 4.2.


Note, the book says to enter "14", this will not work with the current distribution.


$ ./android create avd -n my_android -t 14
Error: Target id is not valid. Use 'android list targets' to get the target ids.

$ ./android list targets
Available Android targets:
----------
id: 1 or "android-17"
Name: Android 4.2
Type: Platform
API level: 17
Revision: 1
Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in
ABIs : armeabi-v7a

Entering "1" will get the default version, which is Android 4.2.


STadmins-MacBook-Pro-2:tools michaellarsen$ ./android create avd -n my_android -t 1
Auto-selecting single ABI armeabi-v7a
Android 4.2 is a basic Android platform.


When prompted "Do you wish to create a custom hardware profile [no]", hit the return button (ie. accept the "no" option).

Do you wish to create a custom hardware profile [no]
Created AVD 'my_android' based on Android 4.2, ARM (armeabi-v7a) processor,
with the following hardware config:
hw.lcd.density=240
vm.heapSize=48
hw.ramSize=512

Run the emulator with:


./emulator -avd my_android & 


If all goes well, you will see something that looks like this (note, it'll take some time to load, be patient):



Installing the Selenium WebDriver Android Server on the Emulator

Next, we need to load the android-server[ver].apk onto the Android emulator. Downloaded the APK file from http://code.google.com/p/selenium/downloads/list.

Start the emulator.

Go to android_sdk/sdk/platform-tools and run "./adb devices")


$ ./adb devices
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
List of devices attached
emulator-5554 device


Note: My serial number is "emulator-5554" your serial number will probably be different from mine.

Install the server:


$ ./adb -s emulator-5554 -e install -r /Users/michaellarsen/selenium/android-server-2.21.0.apk
2602 KB/s (1881490 bytes in 0.705s)
pkg: /data/local/tmp/android-server-2.21.0.apk
Success

On the device you will see this (I put it on the main screen for effect, you'll see it listed in the apps section, though: 



Creating a Test for Android

Those examples we used in the last chapter should work with a minor change. In this case, that change will be to use AndroidDriver. There are some steps to do before that can happen:



Start the WebDriver server on the device. After experimenting with some errors, I restarted the emulator, and then ran the server process from the command line in the android-sdk/sdk/platform-tools directory as follows:


$ ./adb -s emulator-5554 shell am start -a android.intent.action.MAIN -n org.openqa.selenium.android.app/.MainActivity
Starting: Intent { act=android.intent.action.MAIN cmp=org.openqa.selenium.android.app/.MainActivity }



Next, forward HTTP traffic to the emulator.


adb -s emulator-5554 forward tcp:8080 tcp:8080 

With that, let's try a test we're already familiar with...


All we did was add an import statement and change the webdriver to point to AndroidDriver. Let's click Compile (success!) and let's click run test...



Success!!! Cool, we just ran a test on an Android. Well, Android Emulator, but good enough for a first step. 


Working With OperaMobile

As I've come to discover over the past few years, While Opera has a dedicated fan base, they are not really a big player overall in the browser and Mobile world. Still, even though they are a small niche player here stateside, they have put a lot of time and emphasis into their tools, and really, their tools are quite nice. What's more, they have made a really strong push and commitment to making their products very responsive to Selenium, so that alone makes them deserving of a look.

Setting up OperaMobile is actually pretty easy. They have an application package that can be installed on Darwin, so if you are using a Mac like I am, setup is a breeze. Just go to http://www.opera.com/developer/tools/mobile/, get the OperaMobileEmulator.dmg file, double click, put the OperaMobile application into the Applications folder, and that's it. The default location for the application is /Applications/Opera Mobile Emulator.app/Contents/MacOS/Opera Mobile Emulator .


Once you have set up OperaMobile, you can open it up and take a look at the rather large number of emulation modes it supports:



Here's an example page with Amazon Kindle Fire HD 8.9 selected as a destination device.


Making a test is much the same as previous examples, in that we are defining in the setup stage what driver will actually open. In this case, driver will open OperaMobile, with some parameters that David has provided, including a path to the executable (which, in this instance actually compiles :) ).


From there, we can compile (success), and run our test (not successful):



So this will take some playing with, I guess. The OperaMobile profile chooser launches, and if we select something, we get a browser. We have to do that select choice, though, and I suspect that may be part of the problem. Also, we get the OperaMobile browser to appear, but the get command is not posted, and the test times out. Again, something seems to be missing from these steps. The question is what?

Next steps will be to try to figure out what's happening with OperaDriver, but I may just forge ahead and start looking at iOS and the iPhone/iTouch/iPad framework.

Working with iOS
So I have to say at this point I'm a bit disappointed. No, it has noting to do with David or his explanations. It has more to do with Apple and their need to provision my emulator, and charging me $99.00 for the privilege. In short, that annoys me and frankly, I'm not willing to do that at this immediate point in time. I may well address this later on, but for my purposes right now, I'm willing to bypass this for the time being.

Still, I read through the details, and found out much of the information is very similar for what to do to set up and start driving Android and OperaMobile. Put simply, you fork Selenium from git, you build selenium to run in the simulator or on an iOS device, and then you set up your environment (for a fee) to be provisioned to run applications. From there, create a test like we have for the rest of the examples, with the following changes.  

1. Add an import statement that points to:

import org.openqa.selenium.iphone.IphoneDriver; 


2. In the @Before setUp() block, put the following line:

driver = new IPhoneDriver();

With all things being equal, that's pretty much all you have to do to make a test that will run on iPhone.

So there you have it. Much of the details are setting up the environments and geting the code needed to run inside of the environments so that they can be controlled by WebDriver. The cool thing to see is the fact that so little "code" needs to be written at the test level to make these changes. Creating and maintaining tests to be run on multiple different browsers and environments, it's really nice to see that there is very little that one has to do to make changes.

End of Section.

No comments: