Four Picks #4

After a long pause I am restarting the “Four Picks” series back again and hope you find it useful. Here is 4th edition of “Four Picks”

  1. Josh Glade has written an excellent article Five Sins of Mobile Testing on Stickyminds. Josh has given some very important tips for building an effective mobile testing strategy and avoid some common mistakes. His point on testing mobile apps on Emulator Software is valid, however emulators also provide first line of defence before apps are tesed on real devices. If you’re interested in learning more about mobile testing, I also recommend reading Jonathan Kohl’s book Tap into Mobile Application Testing I’m currently reading this book. It is packed with some real practical advice on testing mobile apps, I’ll post a review soon.
  2. Testability and Cost of Change I found this post while watching a video lesson. A well researched post with examples from Google. It provides very useful tips on testability and associated costs. There is an interesting example on cost savings with a bug found during TDD (again a solid reason to adopt TDD)
  3. From One Expert to Another: Dale Emery  Dale Emery talks about his recent talk on Test Automation Zombie Apocalypse I loved this presentation, though I do not agree to all points. This provides great stuff to reflect on your test automation efforts and assess the good and bad things. I also recommend reading Tales of Test Automation Gone Wrong by Elisabeth Hendrickson, in fact we built a assessment out of this presentation to check health of our test automation projects.
  4. Mindmaps! Here is a beautiful mind map on testing tools I found on Twitter

[tweet https://twitter.com/BugFinders/status/353179395822854145 ]

 


iOS Automation with Appium & Selenium

Note: This post is not up to date with latest release of Appium. An update coming soon…

Yesterday I saw a tweet on Appium release from Sauce Labs and immediately started exploring it. This post summarizes my initial experience with Appium.

Appium (http://appium.io/) is an open source tool/framework for automating iOS Native and Hybrid Apps. It uses the WebDriver JSON wire protocol to drive iOS apps.

Appium server is written in Node.js and talks to iOS using UIAutomation via Instruments. You can use the Selenium WebDriver API for writing tests which talk to Appium via JSON wire protocol for running the Selenium commands. This also gives you advantage of writing tests in your language of preference.

Installation

I found installing Appium quite easy on a local machine. You need Node.js installed before using Appium.

1. Install Node.js from http://nodejs.org/

2. Install WebDriver package for Node.js with the following command

sudo npm install wd

3. Install Appium with the following command

sudo npm install appium -g

4. Start the Appium server with the following command

appium &

Appium server will start at http://localhost:4723

Implementing test using Selenium WebDriver

I am using a sample BMI Calculator App developed with native iOS SDK for this example

Bmi Calculator App

Bmi Calculator App

Build the app using xcodebuild command (In this example the BmiCalc app)

xcodebuild -sdk iphonesimulator6.1

I am using Maven to setup a Java project for this test and here is pom.xml with the following dependencies added. For this example I have used IntelliJ IDEA. For more information on using Maven for Selenium script development refer bonus Chapter Integration with other Tools from my Selenium Testing Tools Cookbook

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.bmicalc.test</groupId>
    <artifactId>bmi-ios-test</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>LATEST</version>
        <scope>test</scope>
    </dependency>
    </dependencies>
</project>

And here is BmiCalcTest class

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.By;

import java.io.File;
import java.net.URL;
import java.util.List;

import static org.junit.Assert.assertEquals;

public class BmiCalcTest {

    private WebDriver driver;

    @Before
    public void setUp() throws Exception {

        //Appium needs the path of app build
        //Set up the desired capabilities and pass the iOS SDK version and app path to Appium
        File app = new File("/Users/upgundecha/Desktop/AppExamples/BmiCalculator/build/Release-iphonesimulator/BmiCalculator.app");
        DesiredCapabilities capabilities = new DesiredCapabilities();
        capabilities.setCapability(CapabilityType.BROWSER_NAME, "iOS");
        capabilities.setCapability(CapabilityType.VERSION, "6.1");
        capabilities.setCapability(CapabilityType.PLATFORM, "Mac");
        capabilities.setCapability("app", app.getAbsolutePath());

        //Create an instance of RemoteWebDriver and connect to the Appium server.
        //Appium will launch the BmiCalc App in iPhone Simulator using the configurations specified in Desired Capabilities
        driver = new RemoteWebDriver(new URL("http://localhost:4723/wd/hub"), capabilities);
    }

    @Test
    public void testBmiCalc() throws Exception {

        //iOS controls are accessed through WebElement class
        //Locate the Height & Weight textField by their accessibility labels using By.name()
        WebElement heightTextField = driver.findElement(By.name("Height"));
        heightTextField.sendKeys("181");

        WebElement weightTextField = driver.findElement(By.name("Weight"));
        heightTextField.sendKeys("80");

        //Locate and tap on Calculate button using the click() method
        WebElement calculateButton =  driver.findElement(By.name("Calculate"));
        calculateButton.click();

        //Locate all the label elements using By.tagName()
        List<WebElement> labels = driver.findElements(By.tagName("staticText"));

        //Check the calculated Bmi and Category displayed on labels
        //Label with index 8 has value of the Bmi and index 9 has the value for category
        assertEquals("24.42",labels.get(8).getText());
        assertEquals("Normal",labels.get(9).getText());
    }

    @After
    public void tearDown() throws Exception {
        //Close the app and simulator
        driver.quit();
    }
}

I really liked using Selenium WebDriver API for writing iOS tests with Appium. I can add iOS support to my existing Selenium Framework with minimal changes. Appium presently supports locating elements using the tag name (i.e type of iOS control) and accessibility labels.

Running tests in Cloud

You can also run Appium with Sauce Labs Cloud, for more details read http://sauceio.com/index.php/2013/02/announcing-appium-on-sauce-native-hybrid-ios-testing-in-the-cloud/

Overall Appium is a great tool to start with.

References:
Getting Started – http://appium.io/getting-started.html
Appium on GitHub – http://sauceio.com/index.php/2013/02/announcing-appium-on-sauce-native-hybrid-ios-testing-in-the-cloud/
Samples – https://github.com/appium/appium/tree/master/sample-code
Wiki – https://github.com/appium/appium/wiki
Google Group – https://groups.google.com/forum/?hl=en&fromgroups=#!forum/appium-discuss