Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / DevOps / testing

How Do I Perform UI Automation Testing in iOS 4

4.63/5 (7 votes)
7 Sep 2010CPOL3 min read 108.3K   1.2K  
Beginner level guide (step by step) on UI Automation Testing in iOS 4

Introduction

This is a beginner level article. I hope after going through it, a typical iPhone developer would be able to perform automated UI testing.

Background

UI Automation testing is an important value addition in iOS4. It is supported by a new instrument object called “Automation”. It’s quite suitable for UI testing of Productivity style applications.

Automation instrument works from scripts (written in JavaScript). It simulates/fires required events on target Application. Test script must be a valid executable JavaScript file accessible to the instrument on the host computer.

What is a Test Script?

Test script is an ordered set of commands, each of which accesses a user interface element in application to perform a user action on it or to use the information associated within it.

In this article, I will explain UI Automation testing with the help of one sample application developed using Coco Touch framework.

Description

My sample application has one screen called “Login”. It contains two text fields name as “User name” and “Password” and one Button called “Login”.

Before writing the test script, tag all your UI controls in “Interface Builder” with names, by setting the Accessibility label to a unique value for the view (It is a mandatory requirement).

Now compile your application in debug mode.

Test Scripts

As I mentioned above, test scripts are basically a set of ordered commends. In other words, it’s conversion of textual test cases into JavaScript which would be auto executed by “Automation” instrument.

Here is the sample test script:

C#
// Get the handle of applications main window 
var window = UIATarget.localTarget().frontMostApp().mainWindow(); 

// Get the handle of view 
var view = window.elements()[0]; 

var textfields = window.textFields(); 
var passwordfields = window.secureTextFields(); 
var buttons = window.buttons(); 
var textviews = window.textViews(); 
var statictexts = window.staticTexts(); 
var target = UIATarget.localTarget(); 

// Check number of Text field(s) 
if(textfields.length!=1) 
{
   UIALogger.logFail("FAIL: Inavlid number of Text field(s)"); 
} 
else 
{ 
   UIALogger.logPass("PASS: Correct number of Text field(s)"); 
} 
// Check number of Secure field(s) 
if(passwordfields.length!=1) 
{ 
   UIALogger.logFail("FAIL: Inavlid number of Secure field(s)"); 
} 
else 
{ 
   UIALogger.logPass("PASS: Correct number of Secure field(s)"); 
} 

// Check number of static field(s) 
if(statictexts.length!=2) 
{ 
   UIALogger.logFail("FAIL: Inavlid number of static field(s)"); 
} 
else 
{ 
   UIALogger.logPass("PASS: Correct number of static field(s)"); 
} 

// Check number of buttons(s) 
if(buttons.length!=1) 
{ 
   UIALogger.logFail("FAIL: Inavlid number of button(s)"); 
} 
else 
{ 
   UIALogger.logPass("PASS: Correct number of button(s)"); 
} 

//TESTCASE_001 : Test Log on Screen 
//Check existence of desired TextField On UIScreen 
if(textfields["username"]==null || textfields["username"].toString() == 
	"[object UIAElementNil]") 
{ 
   UIALogger.logFail("FAIL:Desired textfield not found."); 
} 
else 
{ 
   UIALogger.logPass("PASS: Desired UITextField is available"); 
} 

//TESTCASE_1.2 :Check existence desired of PasswordField On UIScreen 
if(passwordfields[0]==null || passwordfields[0].toString() == "[object UIAElementNil]") 
{ 
   UIALogger.logFail("FAIL:Desired UISecureField not found."); 
} 
else 
{ 
   UIALogger.logPass("PASS: Desired UISecureField is available"); 
} 

//TESTCASE_1.3 :Check For Existence of Buttons On UIScreen 
if(buttons["logon"]==null || buttons["logon"].toString() == "[object UIAElementNil]") 
{ 
   UIALogger.logFail("FAIL:Desired UIButton not found."); 
} 
else 
{ 
   UIALogger.logPass("PASS: Desired UIButton is available"); 
} 

//TESTCASE_001 : Missing User Name 
/////////////////////////////////////// 

textfields["username"].setValue(""); 
passwordfields[0].setValue("password"); 
buttons["logon"].tap(); 

//target.delay(2); 

var errorVal=textviews["error"].value(); 
if(errorVal!="Invalid User Name or Password") 
{ 
   UIALogger.logFail("Did Not Get Missing UserName Error : "+errorVal); 
} 
else 
{ 
   UIALogger.logPass("Missing User Name"); 
} 

//TESTCASE_002 : Missing Password 
//////////////////////////////////////////////// 

textfields["username"].setValue("username"); 
passwordfields[0].setValue(""); 
buttons["logon"].tap(); 
target.delay(2); 

var errorVal=textviews["error"].value(); 
if(errorVal!="Invalid User Name or Password") 
{ 
   UIALogger.logFail("Did Not Get Missing Password Error : "+errorVal); 
} 
else 
{ 
   UIALogger.logPass(" Missing Password"); 
} 

//TESTCASE_003 : Successful Log On 
textfields["username"].setValue("username"); 
passwordfields[0].setValue("password"); 
buttons["logon"].tap(); 
target.delay(2); 

All UI elements in the application are represented to the script through an ordered hierarchy of objects defined by the UIAElements class and its subclasses like UIATarget, UIALogger, etc.

For more information, refer to the UI Automation Reference Collection available at Apple Developer site.

After completing the script, we’re all set for execution. Here are the steps:

Step 1

Open Instruments (You can find it is Spotlight). Select “Automation” from template selection window.

Step 2

It will open Trace Window. Here, you have to select debugging version of your application with the help of “Choose Target” pull down.

Step 3

Use “Script” pull down to select test script file and then click on “Run and Record” button.

It will auto launch “iPhone Simulator” and start executing the test scripts (this operation might take 4-5 seconds).

Reusable Test Scripts

The API offers a #import directive that allows you to write smaller, reusable discrete test scripts.

E.g. If you were to define commonly used functions in a file named TestUtilities.js, you could make those functions available for use in your test script TestXYZ.js by including in that script the line:

#import "<path-to-library-folder>/TestUtilities.js" 

Hardware Requirement to Try Out the Attached Sample Code

Mac Mini (Intel processor based) with Snow Leopard 10.6 (or above) and iOS SDK 4.0:

  1. Unzip attached “LoginWindow_src.zip”, compile it in debug mode and test it on Simulator.
  2. “username/password” are valid credentials; enter these values in corresponding “user ID” and “Password” field.

Are You Facing "Unexpected error ...." ?

"Unexpected error in -[UIATarget_0x5a20d20 frontMostApp], 
/SourceCache/UIAutomation_Sim/UIAutomation-37/Framework/UIATargetElements.m line 437"

If you are facing this problem, this can be corrected by copying a com.apple.Accessibility.plist to 4.0.1.

Copy com.apple.Accessibility.plist to:

~/Library/Application Support/iPhone Simulator/4.0.1/Library/Preferences

Make sure that there should be only two Keys in this file name as “AccessibilityEnabled” and “ApplicationAccessibilityEnabled”. Both the keys should be checked.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)