Setting up iOS Automation on Sauce Labs with Cucumber and Appium

Automated mobile testing with Cucumber & Appium

Abstract

Sauce Labs has recently announced Appium support which makes it easier to test mobile apps in the cloud. Appium is a mobile test automation framework for hybrid and native mobile apps. Cucumber is a behaviour driven development a.k.a BDD tool used with different programming languages. The combination of Cucumber and Appium can be used for automating iOS apps in the cloud using Sauce Labs. This is a repost of the original post. In this post, we will see how to set up test automation of our iOS app in the cloud using Sauce Labs.

Getting Started

In order to get started, we need to have the initial setup handy. This includes the following:

  • Mac OSX 10.7.4 or higher with Xcode installed with command line tools.
  • Your app source code or a prebuilt .app bundle for your app. Browse wide range of open-source iOS apps
  • Saucelabs Username and API key. Signup for Saucelabs free account.
  • Web development environment on Mac OSX for Ruby including Xcode, RVM, HomeBrew, Git and Ruby. Follow Moncef’s blog
  • Appium-Ruby-console with Node and npm (Node must be >= v0.8)
  • Ruby 1.9.3

Get Appium and Your iOS App

Before we go ahead, let’s get the Appium server up and running. There are two ways to do it-

  • You can download Mac OSX Appium.dmg package and launch Appium.
  • You can run it from source. Follow instructions. You need to make sure, You have authorized use of the iOS Simulator. If you are running Appium from NPM, you’ll do this by running
$ sudo authorize_ios

There are a wide range of open source iOS mobile apps available here, we are going to use PlainNote iOS app for this tutorial.

Compile and Upload iOS App on SauceLabs

Now we need to compile PlainNote App with Sauce. [ Note Additional parameter TARGET_DEVICE_FAMILY]

$ git clone https://github.com/vkoser/PlainNote
$ cd PlainNote
$ xcodebuild -sdk iphonesimulator6.0 TARGETED_DEVICE_FAMILY=1

In Sauce, there are optional parameters like TARGETED_DEVICE_FAMILY parameter . To build an app for iPhone, we use TARGETED_DEVICE_FAMILY= 1, for iPad TARGETED_DEVICE_FAMILY=2 .

Now, once the build is successful, it will create “PlaneNote.app” at ‘/build/Release-iphonesimulator‘.

$ cd /build/Release-iphonesimulator/
$ ls
PlainNote.app PlainNote.app.dSYM
  • Zip the PlainNote App & Upload to SauceLabs



Now that we have ‘PlainNote.app‘, we need to zip it by navigating to that directory

$ cd /build/Release-iphonesimulator/
$ zip -r PlainNote.zip PlainNote.app

Now you will see ‘PlainNote.zip‘ file in that directory

$ ls
PlainNote.app      PlainNote.app.dSYM PlainNote.zip

Now, we need to upload this file to Sauce Labs temporary storage using the Sauce REST API. I am using my Username and API key here.

$ curl -u Shashikant86:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxbfc3 -X POST "http://saucelabs.com/rest/v1/storage/Shashikant86/PlainNote.zip?overwrite=true" -H "Content-Type: application/octet-stream" --data-binary @/path/to/PlainNote/build/Release-iphonesimulator/PlainNote.zip

It will show you response something like this,

{"username": "Shashikant86", "size": 42190, "md5": "6ef42125b024188976af9d6b8a104105", "filename": "PlainNote.zip"}

It will be now uploaded to “sauce-storage:PlainNote.zip
“. Now we are all set for writing tests for the application with Cucumber.


Setup Cucumber project

Now that we have already uploaded our app on SauceLabs temporary storage, we can setup Cucumber project to talk to the mobile app in the cloud. I assume that you are familiar with the BDD Code and code structure for the Cucumber project. Please refer my old post if you are not aware of BDD code.

  • Create Gemfile



We need a Gemfile in order to specify all our dependencies

$ mkdir sauce-cucumber-appium
$ cd sauce-cucumber-appium
$ rvm use 1.9.3
$ vim Gemfile

Now insert the following dependencies into the Gemfile

source "https://www.rubygems.org"
gem "rest-client"
gem "rspec"
gem "selenium-webdriver"
gem "cucumber"
gem "rspec-expectations"

Now we need to install the bundle to download all the dependencies.

$ bundle install

This will create a ‘Gemfile.lock’ file.

  • Create Feature File



Now, we will write a feature file using Given When Then format. The feature file is written using the Gherkin Domain Specific Language.

Let’s create ‘features/plain_note_sauce.feature‘ file.

$ vim features/plain_note_sauce.feature

The PlainNote app feature will look something like this

Feature: Notes 
  As iOS automation specialist 
  I want to setup iOS app automation in the cloud using Saucelabs, Appium and cucumber 

Scenario: Add new Note using PlainNote App

Given I have App running with appium on Sauce When click + button using sauce driver And I enter text "Data" and saved it on sauce Then I should see "Data" note added on home page in the sauce cloud

This feature is self explanatory, we are going to add a new note and make sure it displayed on the Home page.

  • Setup Cucumber Environment



Let’s create ‘features/support/env.rb‘ where we can put our support code. We need to add sauce_capabilities mentioned in the Sauce Labs Appium tutorial.

$ vim features/support/env.rb

Insert the following code in the file.

require 'rspec/expectations'
require 'selenium-webdriver'

def sauce_capabilities { 'app' => 'sauce-storage:PlainNote.zip', 'device' => 'iPhone Simulator', 'username' => 'Shashikant86', 'access-key' => 'a0e37e25-e2f3-4cba-95d3-936007d8bfc3', 'platform' => 'OS X 10.8', 'version' => '6.0', 'name' => 'Running PlainNote wit Cucumber and Appium', 'passed' => 'true' } end

def sauce_url "http://Shashikant86:a0e37e25-e2f3-4cba-95d3-936007d8bfc3@ondemand.saucelabs.com:80/wd/hub" end

def sauce @sauce ||= Selenium::WebDriver.for(:remote, :desired_capabilities => sauce_capabilities, :url => sauce_url) end

After { @sauce.quit }

Now that we have a created ‘sauce’ driver with all required desired capabilities, ee will using the ‘sauce’ object in our step_definitions

  • Write Step definitions using Selenium-Webdriver JSON Wire Protocol



At this point if you run the ‘bundle exec cucumber’ command it will tell you steps that are not implemented yet. We need to implement these step definitions using Selenium-Webdriver JSON Wire Protocol for Appium. Now we will create a step definition file and implement it

$ vim features/step_definitions/plain_note.rb

Now add these step definitions to the file.

Given(/^I have App running with appium on Sauce$/) do
end

When(/^click + button using sauce driver$/) do sauce.find_element(:name, "Add").click end

When(/^I enter text "(.*?)" and saved it on sauce$/) do |data| sauce.find_element(:xpath, "//window[1]/scrollview[1]/textview[1]").send_keys data sauce.find_element(:name, "Done").click sauce.find_element(:name, "Save").click end

Then(/^I should see "(.*?)" note added on home page in the sauce cloud$/) do |text| note = sauce.find_element(:xpath, "//window[1]/tableview[1]/cell[1]/text[1]") note.attribute("value").should match text end

Appium Inspector

Appium Inspector is a feature of the Appium OSX app which allows you to inspect elements on your mobile app. You can also record tests in the different languages. Writing the Ruby code is easy if you have used Appium Inspector locally to record tests. Watch this video to know ‘How to use Appium Inspector‘.

Now, we are all set to run cucumber to execute tests on the SauceLabs

$ bundle exec cucumber features/plain_note_sauce.feature

Now you will see the tests running on Sauce Labs and in your terminal you will see something like this

Feature: Notes
  As iOS automation specialist
  I want to setup iOS app automation in the cloud using Saucelabs, Appium and cucumber

Scenario: Add new Note using PlainNote App # features/plain_note_sauce.feature:5 Given I have App running with appium on Sauce # features/step_definitions/plain_note_sauce.rb:1 When click + button using sauce driver # features/step_definitions/plain_note_sauce.rb:4 And I enter text "Data" and saved it on sauce # features/step_definitions/plain_note_sauce.rb:8 Then I should see "Data" note added on home page in the sauce cloud # features/step_definitions/plain_note_sauce.rb:14

1 scenario (1 passed) 4 steps (4 passed) 0m35.213s

You can watch video and screenshots of the job.

Cucumber-Appium-SauceLabs

You can find source code on GitHub:

GitHub : cucumber-appium

Watch this video get a clear idea of the cucumber-appium setup on Sauce Labs. If any questions, feel free to contact me.

Discuss: Setting up iOS Automation on Sauce Labs with Cucumber and Appium
0 Comments

Free Trial

Get access to a free 14-day trial version, or contact Sales for more information.