问题描述
我们一直使用 Jenkins 和 Xcode 插件来运行我们 iOS 应用程序的持续集成,包括自动执行和单元测试报告.这在 Linux 机器上使用 Jenkins 和运行 Xcode 4.6.3 的 Mac 从设备运行良好.
We've been using Jenkins with the Xcode plugin to run continuous integration of our iOS applications including automatic execution and reporting of the unit tests. This worked well using Jenkins on a Linux machine and a Mac slave running Xcode 4.6.3.
现在我们希望将设置更新到 Xcode 5 以支持定位到 iOS 7,但遇到了以下问题.
Now we are looking to update the setup to Xcode 5 to support targetting iOS 7 and have run into the following problems.
首先,单元测试根本无法运行,因为我们使用的是 Xcode 5 中不再支持的 Xcode 4 中的 RunUnitTests 脚本.按照 Xcode 的建议,我通过使用适当的方案设置工作区来解决这个问题与单元测试目标.
First, the unit tests would not run at all because we were using the RunUnitTests script from Xcode 4 that is no longer supported in Xcode 5. I addressed this, as recommended by Xcode, by setting up the workspace with an appropriate scheme with the unit test target.
然后我将 Jenkins 作业的 Xcode 步骤配置为将自定义 xcodebuild 参数设置为 test -destination platform=${DESTINATION_PLATFORM},name=${DESTINATION_NAME},OS=${DESTINATION_OS}
到让它运行单元测试.
I then configured the Xcode step of the Jenkins job with custom xcodebuild arguments set to test -destination platform=${DESTINATION_PLATFORM},name=${DESTINATION_NAME},OS=${DESTINATION_OS}
to get it to run the unit tests.
如果我在自己的机器上的终端中运行 Jenkins 的 Xcode 插件在终端中运行的 xcodebuild 命令行,则会运行单元测试,但是当 Jenkins 作业运行时,它会在尝试运行单元测试时失败或挂起.
If I run the xcodebuild command line that the Xcode plugin for Jenkins runs in Terminal on my own machine, the unit tests run, but when the Jenkins job runs, it either fails or hangs when trying to run the unit tests.
我怀疑这是因为使用 Xcode 5 和测试构建操作而不是 RunUnitTests 脚本,单元测试现在在需要交互式会话的 iOS 模拟器中运行,并且 Jenkins 从进程正在从 Jenkins 主机(Linux)通过 SSH 运行).如果我使用 Jenkins 用于 SSH 的帐户登录从机,我可以看到 iOS 模拟器在应该运行单元测试时启动,但测试似乎没有运行并且作业挂起.如果我没有登录到从机,Jenkins 作业将无法运行单元测试.
I suspect this is because with Xcode 5 and the test buildaction instead of RunUnitTests script, unit tests now run in the iOS Simulator which requires an interactive session, and the Jenkins slave process is being run over SSH from the Jenkins master (Linux). If I am logged into the slave machine with the account Jenkins uses for SSH, I can see that the iOS Simulator launches when the unit tests are supposed to run, but the tests don't appear to run and the job hangs. If I am not logged into the slave machine, the Jenkins job fails to run the unit tests.
有什么办法可以让 iOS 单元测试通过 SSH 在 Jenkins slave 上运行,如果没有,当项目必须使用 Xcode 5 构建时,关于如何保持单元测试自动化执行的任何建议?
Is there any way to get the iOS unit tests to run on a Jenkins slave over SSH, and if not, any suggestions on how to keep automating the execution of the unit tests when the project must be built with Xcode 5?
推荐答案
基于 coffeebreaks' 答案,我想出了一个完整的解决方案.
Based on coffeebreaks' answer, I've come up with a full solution.
首先,Mac 从站无法通过 SSH 启动,必须使用交互式会话手动启动,然后始终保持登录状态.在我的情况下,奴隶实际上是无头的,所以这是一个更复杂的问题.
First of all, the Mac slave cannot be launched with SSH and must be launched manually using an interactive session and then left logged in at all times. In my situation, the slave is actually headless, so this is a further complication.
以下是我用来使这一切正常运行的步骤.
Here are the steps I used to get this all operational.
在配置了唯一标签的 Jenkins 主节点上创建一个新的从节点(我选择了xcode-unittests")并将启动方法设置为通过 Java Web Start 启动从代理).
Create a new slave node on the Jenkins master configured with a unique label (I chose "xcode-unittests") and launch method set to "Launch slave agents via Java Web Start).
通过屏幕共享 (VNC) 登录到 Mac 从站并启动从站代理.就我而言,我无法从浏览器启动从属程序,可能是因为我的浏览器没有运行小程序所需的 Java 插件.因此,我使用了命令行 javaws http://{jenkins-host}/computer/{slave-name}/slave-agent.jnlp
.为了使它更健壮,我将此命令配置为每次我以交互方式登录计算机时自动运行,在系统偏好设置、用户和用户下;组、登录项.
Login via screen sharing (VNC) to the Mac slave and start the slave agent. In my case, I could not get the slave to launch from the browser, probably because my browser did not have the necessary Java plug-in for running applets. I therefore used the command line javaws http://{jenkins-host}/computer/{slave-name}/slave-agent.jnlp
. To make this a bit more robust, I configured this command to automatically run every time I login to the machine interactively, under System Preferences, Users & Groups, Login Items.
退出屏幕共享而不退出 Mac 从属设备.这使运行从代理的交互式会话保持活动状态,即使实际上没有人在使用机器.
Quit Screen Sharing without logging out of the Mac slave. This keeps the interactive session running the slave agent alive, even though nobody is actually using the machine.
为了在不提示用户的情况下运行单元测试,我还必须在 Mac 从设备上运行 sudo DevToolsSecurity -enable
.这允许 Xcode 与 iOS 模拟器交互,而无需每次都交互请求许可.
In order for the unit tests to run without prompting a user, I also had to run sudo DevToolsSecurity -enable
on the Mac slave. This allows Xcode to interact with the iOS Simulator without interactively asking for permission to do so each time.
如果从机重新启动,则必须有人登录到 Mac 从机才能让从机代理再次运行.出于这个原因,我也让我的基于 SSH 的从站保持活动状态.我将我的 Jenkins 作业拆分为单独的作业,用于构建应用程序和运行单元测试.用于构建应用程序的作业被配置为在基于 SSH 的从节点上运行,用于运行单元测试的作业被配置为在上述交互式从节点上运行.这样,如果交互式从站宕机,只会影响单元测试,而不影响产品构建.
If the slave machine is ever rebooted, someone must login to the Mac slave to get the slave agent to run again. For that reason, I also left my SSH-based slave active as well. I split my Jenkins jobs into separate jobs for building the apps and running the unit tests. The jobs for building the apps are configured to run on the SSH-based slave, and the jobs for running the unit tests are configured to run on the interactive slave node described above. That way, if the interactive slave goes down, only the unit tests are affected, not the product builds.
这篇关于如何让 Xcode 5 在 Jenkins slave 上运行 iOS 单元测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!