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 中运行完全相同的仪器命令,它会按预期工作。这可能是 Xcode 中的错误吗?

4

6 回答 6

4

我终于找到了解决这个问题的方法。似乎 Xcode 正在以有限的权限运行运行脚本。我不完全确定,是什么导致仪器命令失败,但使用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
于 2013-01-04T17:05:48.307 回答
1

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

我建议也提交一份雷达报告;您可能会从 Apple 获得有关此问题的更多详细信息,或者至少让他们相信很多人都遇到了问题,他们应该弄清楚发生了什么。

很抱歉给出一个不太有用的答案(应该是评论,但评论和链接/格式不能很好地混合)。请使用您在该问题上发现的任何内容更新此问题。

于 2012-12-27T08:10:35.103 回答
1

注意:这不是问题的直接答案,而是潜在问题的替代解决方案。

在搜索有关 UIAutomation 的深入信息时,我偶然发现了 Square 的一个名为 KIF(保持功能)的框架。它是一个集成测试框架,允许许多与 UIAutomation 相同的功能,但最棒的是您可以在 Objective-C 中编写集成测试。

它非常容易设置(通过 CocoaPods),它们也有很好的示例,而且最好的是使用 Jenkins 等 CI 系统设置起来轻而易举。

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

于 2013-02-02T09:45:45.717 回答
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,因此不需要密码。

于 2014-03-19T18:42:53.357 回答
0

查看本教程,该教程解释了如何使用 Jenkins 进行自动化 UI 测试。不过,它也在教程中使用了 Jasmine。http://shaune.com.au/automated-ui-testing-for-ios-apps-uiautomation-jasmine-jenkins/希望这会有所帮助。它有一个示例项目文件,因此您可以将其作为模板下载。希望这可以帮助。

于 2012-12-25T07:18:55.073 回答
0

在 XCode 中 - 如果您加载管理器 (XCode->Window->Organizer)

然后在设备下选择您的机器->“启用开发者模式”

这应该消除对仪器提示的需要。

于 2014-05-24T20:41:39.690 回答