Built.io Blog

Start Automating Native iOS testing with Appium using Node.js

,

What is Appium?

Appium is an open source testing tool that allows you to easily write functional tests to automate iOS and Android mobile applications. It is an HTTP server that manages WebDriver sessions and has support for real device testing. This blog post will guide you through automating iOS testing using this tool and node.js.

The technique presented in this article is a practical way to automate user interface as well as functional testing in iOS. This is ideal when the product design is relatively dynamic or when you have limited resources for test automation. This allows you to test iOS native apps on different versions and various devices. It meets recurrent mobile application testing needs in a simple manner and adheres to the scrum methodology.

Requirements

Install Tools

Perform the following steps in Terminal:

  • Install homebrew by this command (sudo password will be prompted):
    $ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
    
  • Install libimobiledevice: a cross-platform protocol library to communicate with iOS devices.
    $brew install -v --devel --fresh  automake autoconf libtool wget libimobiledevice
    
  • Install ideviceinstaller: A tool to interact with the installation_proxy of an iOS device allowing installing, upgrading, uninstalling, archiving, and restoring apps.
    $brew install -v --HEAD --fresh --build-from-source ideviceinstaller

Overview of Appium

  • How does it work?

Working-of-Appium.png

As shown in the above figure, Appium proxies command to a UI Automation script running in a Mac Instruments environment. Apple provides an application called Instruments which is used to do things like profiling, controlling and building iOS apps. It also has an automation component which allows you to write commands in JavaScript which uses UI Automation APIs to interact with the App UI. Appium utilizes these same libraries to automate iOS Apps.

  • Open Appium, click settings icon to input IP address to listen.
  • Click the Apple Settings Icon and input Appium server capabilities
  • :Appium.png

Application

  • App Path: The path to the iOS application (.app, .zip, or .ipa) you wish to test.
  • Choose Button: Used to choose the path to your application.
  • BundleID: The bundle ID for the application you wish Appium to use (e.g. com.yourCompany.yourApp).
  • Use Mobile Safari: This will make Appium start the Mobile Safari app instead of using a user-supplied application. BundleID or App Path should both be unchecked when this option is used.

Device Settings

  • Force Device: This will make Appium force the Simulator to iPhone or iPad mode.
  • Platform Version: Version of the mobile platform.
  • Force Orientation: Force the orientation of the Simulator.
  • UDID: This is the UDID for the mobile device on which you want to run Appium. If this box is checked, Appium will use the attached iOS device. If this field is checked, bundle ID must be supplied and app path should be unchecked.
  • Show Simulator Log: If checked, the iOS simulator log will be written to the console.

Testing iOS Native Apps on Real Devices

What are the desired capabilities of Appium VS Selenium?

The capabilities were updated to match the mobile version of JSWP. Selenium wasn’t designed for mobile, so we worked with the Selenium project to define a new set of capabilities that support mobile.

  • Create a folder named Node_Sample.
  • In Node_Sample folder, Create a folder named helpers.
  • Open Sublime Text and write the following code in the caps.js file and save in helpers folder:
    exports.mycapabilities = {
      browserName: '',
      'appium-version': '1.3',
      platformName: 'iOS',
      platformVersion: '8.1.1',
      deviceName: 'mydevice'
    };
    Hint: Check Version on iOS device (settings > General > About)
  • Create new file in Sublime Text and write the following code in the appiumserver.js file and save in helpers folder:
    exports.local = {
      host: '127.0.0.1', //Your  IP address
      port: 4723
    };
    
  • Create new file in Sublime Text and write the following code in the app.js file and save in helpers folder:
    exports.myTestApp = "/Users/…/Desktop/myapp.ipa";
    
  • Create new file in Sublime Text and write the following code in the setup.js file and save in helpers folder:
    var wd = require("wd");
    require('colors');
    var chai = require("chai");
    var chaiAsPromised = require("chai-as-promised");
    chai.use(chaiAsPromised);
    var should = chai.should();
    chaiAsPromised.transferPromiseness = wd.transferPromiseness;
    exports.should = should;
  • Create new file in Sublime Text and write the following code in the logging.js file and save in helpers folder:
    "use strict";
    exports.configure = function(driver) {
      driver.on('status', function(info) {
        console.log(info.cyan);
      });
      driver.on('command', function(meth, path, data) {
        console.log(' > ' + meth.yellow, path.grey, data || '');
      });
      driver.on('http', function(meth, path, data) {
        console.log(' > ' + meth.magenta, path, (data || '').grey);
      });
    };

Create new file in Sublime Text and write the following code in the sample.js file and save in Node_Automation folder:

"use strict";
require("./helpers/setup");
var wd = require("wd"),
_ = require('underscore'),
Q = require('q'),
serverConfigs = require('./helpers/appiumserver');
describe("Node Sample Automation Code", function() {
  this.timeout(300000);
  var allPassed = true;
  before(function() {
    var serverConfig = process.env.SAUCE ?
        serverConfigs.sauce : serverConfigs.local;
    var driver = wd.promiseChainRemote(serverConfig);
    require("./helpers/logging").configure(driver);
    var desired = _.clone(require("./helpers/caps").mycapabilities);
    desired.app = require("./helpers/apps").myTestApp;
    if (process.env.SAUCE) {
        desired.name = 'Automation Code';
        desired.tags = ['sample'];
  }
    return driver
        .init(desired);
});
after(function() {
  return driver
    .sleep(3000)
    .quit()
    .finally(function() {
      if (process.env.SAUCE) {
        return driver.sauceJobStatus(allPassed);
    }
    });
});
afterEach(function() {
    allPassed = allPassed && this.currentTest.state === 'passed';
});
it("Should Click Login Button", function()
    return driver.elementByAccessibilityId(“Login Button”).click();
    // Use Appium inspector for inspecting elements
    });
});

Appium-Inspector.png

  • Turn on Enable UIAutomation on iOS device (settings > Developer)
  • Open the package.json file and copy the following code:
    {
      "name": "Automation iOS Testing",
      "version": "1.0.0",
      "description": "",
      "main": "sample.js",
      "author": "",
      "license": "ISC",
      "devDependencies": {
      "mocha": "*",
      "chai": "*",
      "chai-as-promised": "*",
      "wd": "*",
      "colors": "*",
      "underscore": "*",
      "q": "*"
      }
    }
  • Open Terminal; Make sure your current directory must be Node_Sample and type npm install to install all node modules.
  • Run: $mocha sample.js

Appium is used to test critical user operations at scale, and make sure they are working correctly. In conclusion, it can be said that this is successful automation tool that depends on a standard testing process.

I hope this was a helpful guide to automating native iOS testing with Appium, using node.js. Please leave questions in the comments.

Subscribe to our blog