Recently, I was able to give a demo at my local user group showing how to get start with Mobile UI Automation testing using the Appium framework. I figured I would share this information with out listeners and whoever else might come across this. At the end of this, the slide deck along with the source code will be available.
4 Types of Testing
For a mobile app to be tested correctly, we need to make sure we cover all areas. Mobile apps normally have some sort of communication channel with an API or authentication service. We want to make sure all of this works.
Unit tests are easy to write as developers. They are designed to test smaller pieces of your code and are extremely helpful for quick regression.
Performance testing is normally the type of testing that gets ignored, but it can be very important once your app starts getting thousands of users. Not only do you have to check the API, but you have to make sure the your app will run on lower performing hardware.
Testing you API can also be done with Unit Tests, but again is something that can get overlooked. It helps you check endpoints during a regression without having to hook your app up to it.
This is the type of testing we will be covering with Appium. UI Testing allows us to test actions and features as a user would be using them.
Appium is what we will be going over in the rest of this article. It is an open-source automation framework meant for testing iOS and Android native, hybrid and web apps in essentially any language.
App Center by Microsoft allows you to continuously build, test, release, and monitor apps for every platform. They support building your app whether written natively (swift, objective-c, or java) or with a cross platform solution (xamarin or react). You can also run UI tests across multiple devices at the same time using appium.
AWS Device Farm is a testing service that lets you test your Android, iOS and web apps across multiple devices. Just upload your app and test suite and away they go.
What is Appium?
So this is great so far. I know what I need to test, the approaches I can take to test my app, but what is this Appium thing and how do I use it?
Appium is an open-source tool for automating native, mobile web, and hybrid applications. It is based off the Selenium WebDriver which allows these tests to be written in almost any language and be cross platform. That's right, you read that correctly. Not only can I write the same line of code to run a test on an iOS device and an Android device, I can write that desk in almost any language! Some of the supported languages appium has listed on their website and we have used during this demo...
Crazy right? How does Appium accomplish this? Appium works by starting an HTTP server written in Node.JS. This server handles sessions to iOS and Android devices for you. So for example, in my Appium tests if I want to tap a button I would write the following.
MobileElement el1 = driver.GetElementById("MyButton");
This generates a JSON message and sends it over HTTP to the Appium Server. Appium then knows based off the session it created when I made my driver that this is an iOS or Android device. If an iOS device, it will communicate the to the Apple Instruments Command Client and run tests on the device using XCUITest (iOS 9.3+) or UiAutomator (< iOS 9.3). If this was an Android device, it would communicate with Googles UiAutomator2 command server and run the needed tests.
Appium in Action
Let's see real quick how this would work. I wrote a simple test for a Weather App written in Xamarin we used for Xamarin Dev Days. All it does it open the app, click a button that says "Get Weather", then grab a screenshot. Let's see how it works.
Woah! That was quick and easy right? Let's look at the code.
public void GetWeatherTest()
var screenshot = driver.GetScreenshot().AsByteArray;
var filePath = Path.Combine(TestContext.CurrentContext.TestDirectory, "Weather.jpg");
using (var fs = File.Create(filePath))
fs.Write(screenshot, 0, screenshot.Length);
TestContext.AddTestAttachment(filePath, "Weather Results");
Easy right? See any specific code for iOS or Android? That's cause there isn't (well, not really). The only code that is specific that you can't see is connecting to the device. This is only need to be done once, but once it is all tests are the exact same!
As a developer, what I'm doing is pretty simple. Writing code, running in on devices, I do this every day. What about people who don't write code? How can I expect them to write tests?
Appium has an answer for this. It's called Appium Desktop. This application that runs on both Windows and macOS will allow anything to connect to a device, open/install an app and then record actions to write a test! Yes it's actually that easy. Don't believe me? Let's write a test that changes the text bar from 'Seattle, WA' to 'Albany, NY' and then get the weather.
I didn't cover how to setup your device with Appium, but this is actually really easy. Before you start a session, you need to define device capabilities based on how you want to connect. Appium does a great job listing the ones you need and maybe the ones you don't but would be helpful to know here.
Taking these tests to the cloud
I have my app. I used Appium Desktop to write my tests. I tested them on a device I have on my desk. Now how do I test a bunch of devices at one?
Using AWS Device Farm you can tests tens, even hundreds of devices at the same time to make sure you app performs as it should no matter what the hardware is. Doing this is super easy. If you want to see how to write the tests, you can follow AWS tutorial here and/or use the tests I wrote in the Github link below.
After you create and upload your app and tests to the AWS device farm, you can select how you want to run your tests. The first 1,000 minutes are free, so feel free to give it a shot first. You can select the exact type of devices you want and even the configurations of the device such as if WiFi is enable, throttling, etc. I choose 5 devices for this example.
- Amazon Fire HD 7
- Google Pixel 2
- LG Nexus 5
- Motorola Moto X
- Samsung Galaxy S9
AWS gives you a lot of information to verify your tests. It runs across all devices at the same time, prints passed/failed tests, video playback, devices logs, device performance and more. You can see how your app performance at a quick glance or drill down into a specific device to see more information.
As you probably have noticed, a few tests have failed. Why would a test fail for one device over another? For my "get weather" button, I'm using XPath locators. XPath locators are '''not''' reliable and as shown can have issues across devices and versions of androids. Best practice for Android and iOS is to use an identifier. This will ensure finding that element on the 'page' without these issues across devices.
UI testing is normally something that gets over looked, but with mobile development it becomes almost needed. iOS has a handful of devices, but Android has over 19,000. Even though most share the same screen size and other elements you want to make sure you cover as many as possible for your users. UI testing can save time on a smaller team and allow you to scale testing as your app continues to grow. Using Appium allows your tests to work for your team not against. Since Appium allows the same code to work on both Android and iOS devices as well as being written in any language, you aren't locked in to a specific set of rules if your development changes. It allows you to move just as fast as your product.
If you want to see the slide deck from the user group meeting, you can download it here. To see all the code available and try it out for yourself fork it from github. Of course of if you have any questions or need help getting started please feel free to email me at firstname.lastname@example.org.