Running UIAutomation scripts from Xcode Running UIAutomation scripts from Xcode xcode xcode

Running UIAutomation scripts from Xcode


I finally found a solution for this problem. It seems like Xcode is running the Run Scripts with limited rights. I'm not entirely sure, what causes the instruments command to fail, but using su to change to your user will fix it.

su $USER -l -c <instruments command>

Obviously, this will ask you for your password, but you can't enter it when running as a script. I didn't find a way to specify the password for su, however if you run it as root, you don't have to specify one. Luckily sudo can accept a password via the pipe:

echo <password> | sudo -S su $USER -l -c <instruments command>

If you don't want to hardcode your password (always a bad idea), you could use some AppleScript to ask for the password.

I posted the resulting script below. Copy that to a *.sh file in your project and run that script from a Run Script.

#!/bin/bash# This script should run all (currently only one) tests, independently from# where it is called from (terminal, or Xcode Run Script).# REQUIREMENTS: This script has to be located in the same folder as all the# UIAutomation tests. Additionally, a *.tracetemplate file has to be present# in the same folder. This can be created with Instruments (Save as template...)# The following variables have to be configured:EXECUTABLE="TestApp.app"# Optional. If not set, you will be prompted for the password.#PASSWORD="password"# Find the test folder (this script has to be located in the same folder).ROOT="$( cd -P "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"# Prepare all the required args for instruments.TEMPLATE=`find $ROOT -name '*.tracetemplate'`EXECUTABLE=`find ~/Library/Application\ Support/iPhone\ Simulator | grep "${EXECUTABLE}$"`SCRIPTS=`find $ROOT -name '*.js'`# Prepare traces folderTRACES="${ROOT}/Traces/`date +%Y-%m-%d_%H-%M-%S`"mkdir -p "$TRACES"# Get the name of the user we should use to run Instruments.# Currently this is done, by getting the owner of the folder containing this script.USERNAME=`ls -l "${ROOT}/.." | grep \`basename "$ROOT"\` | awk '{print $3}'`# Bring simulator window to front. Depending on the localization, the name is different.osascript -e 'try    tell application "iOS Simulator" to activateon error    tell application "iOS-Simulator" to activateend try'# Prepare an Apple Script that promts for the password.PASS_SCRIPT="tell application \"System Events\"activatedisplay dialog \"Password for user $USER:\" default answer \"\" with hidden answertext returned of the resultend tell"# If the password is not set directly in this script, show the password prompt window.if [ -z "$PASSWORD" ]; then    PASSWORD=`osascript -e "$PASS_SCRIPT"`fi# Run all the tests.for SCRIPT in $SCRIPTS; do    echo -e "\nRunning test script $SCRIPT"    COMMAND="instruments -t \"$TEMPLATE\" \"$EXECUTABLE\" -e UIASCRIPT \"$SCRIPT\""    COMMAND="echo '$PASSWORD' | sudo -S su $USER -l -c '$COMMAND'"    echo "$COMMAND"    eval $COMMAND > results.log    SCRIPTNAME=`basename "$SCRIPT"`    TRACENAME=`echo "$SCRIPTNAME" | sed 's_\.js$_.trace_g'`    mv *.trace "${TRACES}/${TRACENAME}"    if [ `grep " Fail: " results.log | wc -l` -gt 0 ]; then        echo "Test ${SCRIPTNAME} failed. See trace for details."        open "${TRACES}/${TRACENAME}"        exit 1        break    fidonerm results.log


It seems as though this really might be an Xcode problem; at any rate, at least one person has filed a Radar report on it. Someone in this other thread claims you can work around this exception by disconnecting any iDevices that are currently connected to the computer, but I suspect that does not apply when you're trying to run the script as an Xcode target.

I would suggest filing a Radar report as well; you may get further details on the issue from Apple, or at least convince them that many people are having the problem and they ought to figure out what's going on.

Sorry for a not-terribly-helpful answer (should have been a comment, but comments and links/formatting do not mix very well). Please update this question with anything you find out on the issue.


Note: this is not a direct answer to the question, but it is an alternative solution to the underlying problem.

While searching for in-depth information about UIAutomation, I stumbled across a framework by Square called KIF (Keep it functional). It is a integration testing framework that allows for many of the same features as UIAutomation, but the great thing about is is that you can just write your integration tests in Objective-C.

It is very easy to setup (via CocoaPods), they have good examples too, and the best thing is that it's a breeze to set up with your CI system like Jenkins.

Have a look at: http://github.com/square/KIF