Error message

The spam filter installed on this site is currently unavailable. Per site policy, we are unable to accept new submissions until that problem is resolved. Please try resubmitting the form in a couple of minutes.
alex.reggiani's picture

Everytime we add a new feature to our applications, launching the simulator and running a long sequence of repetitive actions in order to verify if it is all functioning, we execute the so-called “Test” phase.
Testing the software requires an amount of work rather repetitive so XCode helps us again. How? Instead of performing the same actions of the “Test” phase, like tapping buttons or executing gesture of every type, it allows us to create scripts which carry out this work in our place.

For this aim, we’ll see how to use the UI Automation tool, integrated into Instruments.

As a case study, we’ll take account of an app that manages only a simple table with a list of food and the only possible actions are the following:

  • add a new food on the list
  • delete an element
  • sort food in alphabetic order or in date entry


Capturing our first script from the simulator
Open instruments choosing Profile from the Product menu. Xcode will compile the application in “Release” mode. When Instruments is opened, it presents a set of templates, but we only need to choose the UI Automation template.


Once selected, Instruments creates a new Trace Document and it instantly starts to record a track of the application. But given that we want to launch our capture from zero, we stop the recording clicking on the red button that we find in the upper left corner.


We create a new script clicking on the button Add→ Create on the left dashboard, as we can see from the picture.


Once it is created, the panel is shown in the lower part of the screen, and


as it is possible to notice, UIAutomation displays everything through JavaScript.
The first line, captures the target instance currently in use, that is the simulator.

Now we can start to record a script performing different actions on our application, for example:

  • Click on the button “By Name”
  • Click on the button “Edit”
  • Click on the button “Done”

To do so, click on the lower red button, in the script dashboard. As the simulator is opened we start to perform the procedure above mentioned.

Everytime we perform an action, a line of code is added into the script panel, showing us how UIAutomation collects and catches events.
Once performed all the four actions click on the stop button.

If we take a look at the script dashboard, we’ll notice the lines of code added in relation to the actions it has collected:


Now simply click on the Play button to launch the simulator again; Instruments substitutes automatically the script panel with a log panel

and magically all the actions we had recorded, will be reproduced.

So we learned how to record a script that reproduces a repetitive series of actions in our place. But for now the recorded script doesn’t do anything useful.
Now we see how it writes an acceptance test so that we can verify if the application behaviour actually corresponds to what we expect.

We write a simple test to verify that the user is able to delete an item from the food list, as an example we try to delete the item “pizza”.
Delete all the script contents recorded earlier, leaving only the first line:

var target = UIATarget.localTarget();

and record a new one performing these actions:

  • Click on the “Edit” button
  • Click on the red button on the left of the “pizza” item, in order to show the “delete” button
  • Click on the “delete” button
  • Click on the “done” button

If you have performed everything in the right way, the script will report the following code:


Now we try to “corrupt” the application code so the item won’t be delete again. Before proceeding we write the script in a more comprehensible way:


When we access to the table’s cells with the instruction:


we obtain an UIAElementArray object which it supplies different research methods in one collection.
The most suitable for us is the method firstWithName() which returns the first element found and which it corresponds to the name used as parameter.

var pizzaCell = cells.firstWithName("pizza");

or its equivalent form

var pizzaCell = cells["pizza"]; 

We access the navigation bar for the pressure of the Edit button:

var navigationBar = app.navigationBar();

var editButton = navigationBar.leftButton();

if (editButton.name() == "Edit") {



Once in edit mode, we have to recover and click on the red button on the left of "pizza element" to bring up the Delete button and then click on this button:

var deleteSwitch = pizzaCell.switches()[0];

if (deleteSwitch.value() == 0) {



var deleteButton = pizzaCell.buttons()[0];


At this point, we have written the code recorded earlier from Instruments, and if we perform it we’ll obtain the same result, that is deleting the cell of the element “Pizza”.
The real benefit, though, is that we can verify if the cell has been actually deleted or not, after pushing on the “delete” button. That allows to report errors, making the test fail, in case the deletion hasn’t succeeded.
In order to follow this control we can tell the script to wait for the cell (the one that will be deleted) to be invalidated.
There are two methods pushTimeout() and popTimeout() that say to the system whether to wait before questioning the interface again. So we need to wait some time after pushing the “delete” button in order to verify if the cell that must be deleted is still present or not.
Both in positive and negative case, a message will be printed into the log panel.




if (pizzaCell.isValid()) {

	UIALogger.logError("Error: the cell was not deleted!!");

} else {

	UIALogger.logMessage("The cell is gone!!!");


Before performing the script again, make sure that the “pizza” element appears on the list: if not, we immediately add it.
Once performed, if everything is correct, the “pizza” element should have been deleted and the log panel will display these messages:

Now we can try to derail the test commenting the instruction that deletes the table line:

//[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];

We click again on the menu Product-->Profile, so that XCode compiles our changes and then we launch again the script (it is important to check if the “pizza” element is still present on our list before performing the script and eventually we need to add it).

This time, the cell won’t be deleted and our test will fail.
Besides a visual validation, it suffices to control the log panel which will bring back the following messages:


As we can see, the error message is shown to report the fact that the test has failed.

This is only a tiny example of how it is possible to create a script for an application test. We can create a multitude of tests and each one will evaluate a subset of application features.
Finally, in order to enhance this topic we suggest to you this text "Test iOS Apps with UI Automation” written by Jonathan Penn.

Add new comment

Filtered HTML

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.