如何让 Xcode 5 在 Jenkins slave 上运行 iOS 单元测试?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18921078/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I get Xcode 5 to run iOS unit tests on a Jenkins slave?
提问by GBegen
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.
我们一直在使用 Jenkins 和 Xcode 插件来运行我们 iOS 应用程序的持续集成,包括单元测试的自动执行和报告。这在 Linux 机器上使用 Jenkins 和运行 Xcode 4.6.3 的 Mac slave 运行良好。
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 以支持定位到 iOS 7,但遇到了以下问题。
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.
首先,单元测试根本不会运行,因为我们使用的是 Xcode 5 中不再支持的 Xcode 4 中的 RunUnitTests 脚本。我按照 Xcode 的建议解决了这个问题,方法是使用单元设置适当的方案的工作区测试目标。
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.
然后,我使用设置为 的自定义 xcodebuild 参数配置 Jenkins 作业的 Xcode 步骤,test -destination platform=${DESTINATION_PLATFORM},name=${DESTINATION_NAME},OS=${DESTINATION_OS}
以使其运行单元测试。
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.
如果我在我自己的机器上运行 Jenkins 的 Xcode 插件在终端中运行的 xcodebuild 命令行,则单元测试会运行,但是当 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.
我怀疑这是因为使用 Xcode 5 和测试构建操作而不是 RunUnitTests 脚本,单元测试现在在需要交互式会话的 iOS 模拟器中运行,并且 Jenkins 从进程正在从 Jenkins 主机 (Linux) 通过 SSH 运行。如果我使用 Jenkins 用于 SSH 的帐户登录从机,我可以看到 iOS 模拟器在应该运行单元测试时启动,但测试似乎没有运行并且作业挂起。如果我没有登录到从机,Jenkins 作业将无法运行单元测试。
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?
有没有办法让 iOS 单元测试通过 SSH 在 Jenkins slave 上运行,如果没有,当项目必须使用 Xcode 5 构建时,关于如何保持单元测试自动化执行的任何建议?
采纳答案by GBegen
Based on coffeebreaks' answer, I've come up with a full solution.
根据coffeebreaks的回答,我想出了一个完整的解决方案。
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.
首先,Mac 从站不能通过 SSH 启动,必须使用交互式会话手动启动,然后始终保持登录状态。在我的情况下,奴隶实际上是无头的,所以这是一个更复杂的问题。
Here are the steps I used to get this all operational.
以下是我用来使这一切正常运行的步骤。
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).
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.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.
在配置了唯一标签的 Jenkins 主节点上创建一个新的从节点(我选择了“xcode-unittests”)并将启动方法设置为“通过 Java Web Start 启动从代理”。
通过屏幕共享 (VNC) 登录到 Mac 从站并启动从站代理。就我而言,我无法从浏览器启动从属程序,可能是因为我的浏览器没有运行小程序所需的 Java 插件。因此我使用了命令行
javaws http://{jenkins-host}/computer/{slave-name}/slave-agent.jnlp
。为了使它更健壮,我将此命令配置为每次我以交互方式登录计算机时自动运行,在系统偏好设置、用户和组、登录项下。退出屏幕共享而不退出 Mac 从属设备。这使运行从代理的交互式会话保持活动状态,即使实际上没有人在使用机器。
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.
为了在不提示用户的情况下运行单元测试,我还必须sudo DevToolsSecurity -enable
在 Mac 从设备上运行。这允许 Xcode 与 iOS 模拟器交互,而无需每次都交互请求许可。
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.
如果从机重新启动,则必须有人登录到 Mac 从机才能让从机代理再次运行。出于这个原因,我也让我的基于 SSH 的从站保持活动状态。我将我的 Jenkins 作业拆分为单独的作业,用于构建应用程序和运行单元测试。用于构建应用程序的作业被配置为在基于 SSH 的从节点上运行,用于运行单元测试的作业被配置为在上述交互式从节点上运行。这样,如果交互式从站出现故障,只会影响单元测试,而不影响产品构建。
回答by coffeebreaks
Try starting your jenkins slave from a standard terminal on your Mac slave, not from the master using SSH.
尝试从 Mac 从站上的标准终端启动 jenkins 从站,而不是从使用 SSH 的主站启动。
回答by Luke
See GBegenand coffeebreaks' answers. When the Jenkins is secured, use the alternative command line to start it from a screen share/VNC terminal session is
请参阅GBegen和咖啡休息时间的回答。当 Jenkins 受到保护时,使用替代命令行从屏幕共享/VNC 终端会话启动它
java -jar slave.jar -jnlpUrl http://jenkins-master:port/computer/jenkins-slave/slave-agent.jnlp -secret XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
回答by RPM
What @GBegen said is correct and I used to do that before as well - Run the simulator and exit VNC without logging out, but that was not reliable. What I do now is to have a script that actually launches the simulator if it is not running. With Xcode 5 that broke as well, but I fixed it by adding the jenkins user to the admin group.
@GBegen 所说的是正确的,我以前也这样做过 - 运行模拟器并退出 VNC 而不注销,但这并不可靠。我现在要做的是有一个脚本,如果模拟器没有运行,它会实际启动模拟器。Xcode 5 也坏了,但我通过将 jenkins 用户添加到管理员组来修复它。