从Xcode运行UIAutomation脚本

20

有人成功在Xcode中设置自动化UIAutomation测试吗?

我正在尝试在我的Xcode项目中设置一个目标,该目标应运行我准备的所有UIAutomation脚本。目前,该目标的唯一构建阶段是这个运行脚本块:

TEMPLATE="/Applications/Xcode.app/Contents/Applications/Instruments.app/Contents/PlugIns/AutomationInstrument.bundle/Contents/Resources/Automation.tracetemplate"
MY_APP="/Users/Me/Library/Application Support/iPhone Simulator/6.0/Applications/564ED15A-A435-422B-82C4-5AE7DBBC27DD/MyApp.app"
RESULTS="/Users/Me/Projects/MyApp/Tests/UI/Traces/Automation.trace"
SCRIPT="/Users/Me/Projects/MyApp/Tests/UI/SomeTest.js"
instruments -t $TEMPLATE $MY_APP -e UIASCRIPT $SCRIPT -e UIARESULTSPATH $RESULTS

当我构建此目标时,几秒钟后成功,但实际上脚本并没有运行。在构建日志中,我得到了以下错误:
instruments[7222:707] Failed to load Mobile Device Locator plugin
instruments[7222:707] Failed to load Simulator Local Device Locator plugin
instruments[7222:707] Automation Instrument ran into an exception while trying to run the script.  UIATargetHasGoneAWOLException
+0000 Fail: An error occurred while trying to run the script.
Instruments Trace Complete (Duration : 1.077379s; Output : /Users/Me/Projects/MyApp/Tests/UI/Traces/Automation.trace)

我很确定我的JavaScript和运行脚本都是正确的,因为如果我在bash中运行完全相同的Instruments命令,它会按预期工作。这可能是Xcode的一个错误吗?


你尝试过通过xcrun运行Instruments吗?也许这可以帮助正确设置其环境?例如:xcrun instruments -t [...] - Till
哦,如果需要更多灵感,请看一下我和同事开始的一个小项目:jenkins-automation - Till
我得到了相同的结果。非常奇怪,因为你似乎做了同样的事情。但是你是在Xcode之外运行这个脚本,对吧?我的问题是,如果我尝试将其作为目标运行,它就无法正常工作。如果我只是在终端上运行脚本,那就没问题。 - DrummerB
是的,那个脚本是通过 Jenkins 运行的,在 Xcode 之外。 - Till
6个回答

4

我终于找到了解决这个问题的方法。看起来Xcode以受限权限运行Run Scripts,导致instruments命令失败。但是使用su切换到您的用户将可以解决它。

su $USER -l -c <instruments command>

显然,这会要求您输入密码,但在脚本运行时无法输入。我没有找到指定su密码的方法,但是如果以root身份运行它,则不必指定密码。幸运的是,sudo可以通过管道接受密码:
echo <password> | sudo -S su $USER -l -c <instruments command>

如果您不想硬编码密码(这总是一个坏主意),则可以使用一些AppleScript来请求密码。

我在下面发布了结果脚本。将其复制到项目中的*.sh文件中,并从“运行脚本”中运行该脚本。

#!/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 folder
TRACES="${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 activate
on error
    tell application "iOS-Simulator" to activate
end try'

# Prepare an Apple Script that promts for the password.
PASS_SCRIPT="tell application \"System Events\"
activate
display dialog \"Password for user $USER:\" default answer \"\" with hidden answer
text returned of the result
end 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
    fi

done

rm results.log

谢谢你的回答。我发现这个脚本在我的情况下工作得很好。但是输出文件有问题。我找不到任何*.trace文件。能帮忙吗? - sahara108
我不理解这行代码 mv *.trace "${TRACES}/${TRACENAME}"。我在电脑上没有找到任何跟踪文件。请帮忙。 - sahara108

1
晚来一步,但我有一个适用于Xcode 5.1的解决方案。不知道这是否破坏了上述解决方案。使用旧的解决方案仍然会出现以下问题:
Failed to load Mobile Device Locator plugin, etc.

然而,这仅适用于Xcode 5.1的发布版本。
echo <password> | sudo -S -u username xcrun instruments

注意我删除了不必要的su命令,并添加了xcrun命令。 xcrun是所需的魔法。

这是我的完整命令:

echo <password> | sudo -S -u username xcrun instruments\ 
  -w "iPhone Retina (3.5-inch) - Simulator - iOS 7.1"\
  -D "${PROJECT_DIR}/TestResults/Traces/Traces.trace"\
  -t "${DEVELOPER_DIR}/Instruments.app/Contents/PlugIns/AutomationInstrument.bundle/Contents/Resources/Automation.tracetemplate"\
  "${BUILT_PRODUCTS_DIR}/MyApp.app"\
  -e UIARESULTSPATH "${PROJECT_DIR}/TestResults"\
  -e UIASCRIPT "${PROJECT_DIR}/UITests/main.js"

顺便提一下,如果你输入:

instruments -s devices

您将获得所有支持的设备列表,可用于-w选项。

编辑:为了使不同的人检查项目而工作,请替换以下内容:

echo <password> | sudo -S -u username xcrun instruments

使用

sudo -u ${USER} xcrun instruments

由于您只是对同一用户进行sudo操作,因此不需要密码。


1

看起来这可能真的是一个Xcode问题;无论如何,至少有一个人已经提交了Radar报告另一个帖子中的某个人声称,你可以通过断开当前连接到计算机的任何i设备来解决此异常,但我怀疑当你试图将脚本作为Xcode目标运行时,这并不适用。

我建议您也提交Radar报告;您可能会从苹果那里获得更多关于该问题的详细信息,或者至少让他们相信很多人都遇到了这个问题,他们应该找出问题所在。

很抱歉提供的答案不是非常有帮助(本应该是评论,但评论和链接/格式不太兼容)。请在此问题上更新任何您发现的有关问题的信息。


抱歉,我打算接受我的新解决方案。无论如何,感谢你的帮助。 - DrummerB
不要道歉 - 感谢您抽出时间回来更新帖子!这个解决方法最终会对我们许多人都有用。 - Arkaaito

1

注意:这不是对问题的直接回答,但它是解决潜在问题的另一种方案。

在寻找有关UIAutomation的深入信息时,我偶然发现了一个由Square开发的框架KIF(Keep it functional)。它是一个集成测试框架,可以实现与UIAutomation许多相同的功能,但最好的是,您可以只用Objective-C编写集成测试。

它非常容易设置(通过CocoaPods),他们也有很好的示例,最好的事情是它可以轻松地与您的CI系统(如Jenkins)一起设置。

请查看:http://github.com/square/KIF


是的,我知道,当KIF实际上解决了我的潜在问题时,我遇到了这样的问题。我添加了一条说明。干杯。 - epologee

0

0
在XCode中,如果您加载组织器(XCode->窗口->组织器)
然后在设备下选择您的机器 ->“启用开发者模式”
这应该消除了使用instruments时的提示需求。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接