运行unittests时不要启动模拟器

一些背景:

我有iOS应用程序,目标configuration为运行unitTests。 我正在MacBook上运行构build自动化工具jenkins,它会自动构build这个应用程序并运行所有testing(使用命令行xcodebuild工具)。

一切工作正常与Xcode 4.这个生成自动化工具运行在不同的用户和运行所有这些testing。

我最近切换到Xcode 5,它开始失败,因为它无法启动模拟器。

问题

我有一个schemeUnitTests被configuration为运行testing(逻辑testing)。 AI使用以下两种方法之一运行这些testing:

  • 在Xcode中的命令U

  • 或命令行“/ usr / bin / xcodebuild -scheme UnitTests -sdk iphonesimulator -configuration发布干净的构buildTEST_AFTER_BUILD = YES”

在这两种情况下,它都试图启动模拟器。 但是,根据我的理解,它不需要它。 无论如何,它运行在顶部的x86,它看起来不像任何应用程序安装在模拟器上。

有没有办法摆脱这个讨厌的模拟器开始(因为它打破了我的编译自动化)?

更新1

似乎find非常类似的问题,但不能得到它的工作: 在Xcode 4中运行逻辑testing,而无需启动模拟器

更新2

我发现非常相关和有趣的问题/答案: 苹果CI / Xcode服务和jenkins

使用xCode 7和xCtool。

xctool能够在没有模拟器的情况下执行unit testing。

为了得到这个工作,

1。 更新目标设置以在没有主机应用的情况下运行

select您的项目 – >然后testing目标 – >将主机应用程序设置为无。

在这里输入图像说明

2.安装xctool,如果你没有的话。

brew install xctool 

3.使用xctool使用terminal运行testing。

 xctool -workspace yourWorkspace.xcworkspace -scheme yourScheme run-tests -sdk iphonesimulator 

我向苹果工程师提出了同样的问题。 不幸的是,似乎你可以做到这一点,并与iOS保持同步。 有一些技巧,你可以做检查,如果testing。 你可以把这个代码片段放在你的AppDelegate.h或者其他一些全局类中,说不加载一个根视图控制器,并且防止所有的东西来破坏你的unit testing:

 static BOOL isTesting() { BOOL isTesting = !isEmpty([[[NSProcessInfo processInfo] environment] objectForKey:@"XCInjectBundle"]); return isTesting; } 

我也有一个苹果工程师validation这是一个合法的检查。 在信贷到期时给予贷款,这是来自:以编程方式确定iOS项目中的当前目标(运行或testing)

编辑:我也有这个成功,这是一个更简单一点:

 static BOOL isTesting() { return [[[NSProcessInfo processInfo] processName] isEqualToString:@"xctest"]; } 

您可以创build一个Mac OSXunit testing,而不是iOSunit testing。 这要求你不要在unit testing中包含任何iOS特定的库。 你可以通过以下方式来做到这一点:

  1. select项目 – >目标下拉菜单 – >“添加目标…”
  2. select“Mac OSX” – >“其他” – >“cocoaunit testing包”
  3. 像正常项目一样创buildtesting包

您现在可以将源添加到unit testing,并像iOStesting一样运行,而无需启动模拟器。

一个osxtesting目标可能会变成一个巨大的麻烦,因为你必须pipe理自己要包含哪个源文件。 把@testable import YourAppName你的XCTest文件顶部的YourAppName方式更方便。 所以只要阻止你的应用程序在XCTest运行的情况下启动。

在你的AppDelegate中放入:(Swift 3解决scheme)

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { if ProcessInfo.processInfo.environment["XCInjectBundleInto"] != nil { return false } ... 

这不会阻止模拟器启动,但会为您节省很多时间。

解决方法:

应用程序仍然会启动,但您可以#if定义您不想运行的内容。

做法:

  1. 通过复制“ Debug (“项目”>“信息”>“创build新configuration”)创build名为Test的自定义生成configuration
  2. 在“ Build Settings >“ Test Active Compilation Conditions中添加“ TESTING
  3. 编辑scheme>信息>构buildconfiguration“,将构buildconfiguration设置为”testing“
  4. 围绕你不想在testing时执行的代码使用#if !TESTING #endif

构架:

如果您有embedded式框架,请在框架中创build相同的构buildconfiguration,以便框架二进制正确链接。