运行单元测试时不要启动模拟器

时间:2013-08-08 19:39:33

标签: ios xcode jenkins

某些背景:

我有iOS应用程序,其目标配置为运行unitTests。我在我的MacBook上运行构建自动化工具jenkins,它自动构建此应用程序并运行所有测试(使用命令行xcodebuild工具)。

Xcode 4的所有功能都运行良好。这个构建自动化工具在不同的用户下运行,并且正在运行所有这些测试。

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

问题

我有一个方案UnitTests,它被配置为运行测试(逻辑测试)。我使用以下两种方法之一运行这些测试:

  • Xcode中的命令U

  • 或命令行“/ usr / bin / xcodebuild -scheme UnitTests -sdk iphonesimulator -configuration Release clean build TEST_AFTER_BUILD = YES”

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

有没有办法摆脱这个讨厌的模拟器启动(因为它打破了我的构建自动化)?

更新1

似乎找到了非常相似的问题,但无法使其正常工作: Run logic tests in Xcode 4 without launching the simulator

更新2

我发现了非常相关且有趣的问题/答案:Apple CI / Xcode Service and Jenkins

6 个答案:

答案 0 :(得分:25)

使用xCode 7和xCtool。

xctool 能够在没有模拟器的情况下执行单元测试。

要实现这一目标,

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

选择您的项目 - >然后测试目标 - >将主机应用程序设置为none。

enter image description here

<强> 2。如果没有,请安装xctool。

brew install xctool

第3。使用带xctool的终端运行测试。

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

答案 1 :(得分:15)

您可以创建Mac OSX单元测试而不是iOS单元测试。这要求您不要在单元测试中包含任何iOS特定库。您可以通过以下方式执行此操作:

  1. 选择项目 - &gt;目标下拉 - &gt; “添加目标......”
  2. 选择“Mac OSX” - &gt; “其他” - &gt; “Cocoa Unit Testing Bundle”
  3. 像正常项目一样创建测试包
  4. 您现在可以在单元测试中添加源代码,并像iOS测试一样运行它,而无需启动模拟器。

答案 2 :(得分:14)

我向苹果工程师提出了同样的问题。不幸的是,似乎你无法实现这一点并同时与iOS保持联系。有一些技巧可以检查是否测试。您可以将此代码段放在AppDelegate.h或其他全局类中,以表示不加载根视图控制器并防止任何wierdo ui破坏您的单元测试:

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

我还有一位苹果工程师证实这是一张合法的支票。并且在信用到期时给予信用,这来自:Programmatically determine current target (run or test) in iOS project

修改 我也有这方面的成功,而且更直接:

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

答案 3 :(得分:3)

osx测试目标可能会成为一个巨大的麻烦,因为您必须自己管理要包含的源文件。将@testable import YourAppName置于XCTest文件之上更方便。因此,只有在XCTest运行时才阻止您的应用启动。

在你的AppDelegate中:( Swift 3解决方案)

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

...

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

答案 4 :(得分:0)

解决方法:

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

的方法:

  1. 通过复制Test创建名为Debug的自定义构建配置(项目&gt;信息&gt;创建新配置)
  2. Build Settings&gt; Active Compilation Conditions Test添加TESTING
  3. 编辑方案&gt;信息&gt;构建配置,将构建配置设置为测试
  4. 在测试时不想执行的代码周围使用#if !TESTING #endif
  5. 框架:

    如果您有嵌入式框架,请在框架中创建相同的构建配置,以便框架二进制文件正确链接。

答案 5 :(得分:0)

您可以使用 Xcode 9 和来自终端的命令以无头模式运行单元和ui测试。有关参考示例命令:

构建和测试工作区

xcrun xcodebuild -workspace "YOUR_WORKSPACE_NAME.xcworkspace" -scheme "YOUR_SCHEME" -sdk "iphonesimulator12.0" -destination "OS=12.0,name=iPhone X" -configuration Debug -enableCodeCoverage YES clean build test

对于项目

xcrun xcodebuild -project "YOUR_PROJECT_NAME.xcodeproj" -scheme "YOUR_SCHEME" -sdk "iphonesimulator12.0" -destination "OS=12.0,name=iPhone X" -configuration Debug -enableCodeCoverage YES clean build test