在 Xcode 4 中运行逻辑测试而不启动模拟器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7274711/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 21:51:28  来源:igfitidea点击:

Run logic tests in Xcode 4 without launching the simulator

objective-cxcodetddios-simulatorocunit

提问by Jez Humble

I want to run tests in Xcode 4 using OCUnit without launching the simulator. Please, don't try and convince me I am doing unit testing wrong or anything like that. I like to do TDD the traditional way: write the API for the class in the tests, then make the class pass the tests. I will write separate tests that are end-to-end that run in the simulator.

我想在不启动模拟器的情况下使用 OCUnit 在 Xcode 4 中运行测试。请不要试图说服我我正在做错误的单元测试或类似的事情。我喜欢以传统方式进行 TDD:在测试中为类编写 API,然后让类通过测试。我将编写在模拟器中运行的端到端的单独测试。

If there's no way to do this, then please can someone tell me how to have the test harness not instantiate the whole app? My app is event driven, and it sends a bunch of events through when it starts up that mess with my tests.

如果没有办法做到这一点,那么请有人告诉我如何让测试工具不实例化整个应用程序?我的应用程序是事件驱动的,它在启动时发送了一堆事件,这些事件与我的测试一团糟。

回答by Jon Reid

Please can someone tell me how to have the test harness not instantiate the whole app? My app is event driven, and it sends a bunch of events through when it starts up that mess with my tests.

请有人告诉我如何让测试工具不实例化整个应用程序?我的应用程序是事件驱动的,它在启动时发送了一堆事件,这些事件与我的测试一团糟。

I use Xcode 4's built-in testing. App instantiation may seem like a pain, but as I write on Xcode Unit Testing: The Good, the Bad, the Ugly, it makes it possible to write tests without distinguishing between logic tests and application tests. Specifically, it lets me write unit tests for view controllers.

我使用 Xcode 4 的内置测试。应用程序实例化可能看起来很痛苦,但正如我在Xcode 单元测试:好的、坏的、丑陋的中所写的那样,它可以在不区分逻辑测试和应用程序测试的情况下编写测试。具体来说,它让我为视图控制器编写单元测试。

Here's what I do to avoid my full startup sequence:

这是我为避免完整启动序列而采取的措施:

Edit the scheme

编辑方案

  • Select the Test action
  • In "Test" select the Arguments tab
  • Disable "Use the Run action's options"
  • Add an environment variable, setting runningTeststo YES
  • 选择测试操作
  • 在“测试”中选择参数选项卡
  • 禁用“使用运行操作的选项”
  • 添加环境变量,设置runningTestsYES

Edit your app delegate

编辑您的应用委托

  • Add the following to -application:didFinishLaunchingWithOptions:as soon as it makes sense to:

    #if DEBUG
        if (getenv("runningTests"))
            return YES;
    #endif
    
  • Do the same for -applicationDidBecomeActive:but simply return.

  • -application:didFinishLaunchingWithOptions:尽快将以下内容添加到:

    #if DEBUG
        if (getenv("runningTests"))
            return YES;
    #endif
    
  • -applicationDidBecomeActive:但简单地做同样的事情return

Update: I have changed my approach. See How to Easily Switch Your App Delegate for Testing.

更新:我改变了我的方法。请参阅如何轻松切换您的应用程序委托进行测试

回答by Igor

In the last xcode version (5.0.2) you can do this in very easy way. Choose your Test target, "General" tab. Set "None" in field "Target". Then tap on "Build phases" tab and remove your Main target from "Target dependencies".

在最新的 xcode 版本 (5.0.2) 中,您可以非常简单地做到这一点。选择您的测试目标,“常规”选项卡。在“目标”字段中设置“无”。然后点击“构建阶段”选项卡并从“目标依赖项”中删除您的主要目标。

回答by dtuckernet

In your situation, I am assuming that you have a separate Logic Tests and Application Tests target (if not - you need to). In your schemes configuration you define which targets are built for the 'Test' scheme. If your application tests are not running, the simulator will not launch.

在您的情况下,我假设您有一个单独的逻辑测试和应用程序测试目标(如果没有 - 您需要)。在您的方案配置中,您定义为“测试”方案构建哪些目标。如果您的应用程序测试未运行,模拟器将不会启动。

I suspect that you might be trying to run 'logic tests' in an 'Application tests' target (such as the one created by default by Xcode). See more about this difference here(and how to set ut up).

我怀疑您可能正在尝试在“应用程序测试”目标(例如 Xcode 默认创建的目标)中运行“逻辑测试”。在此处查看有关此差异的更多信息(以及如何设置)。

回答by Praveen Kumar

It was pointed out in an earlier answer that logic tests are the right thing to do for this scenario. I had very tough time in getting the logic tests working with XCode Version 4.3.2 (4E2002). Looking at Apple's sample unit test projecthelped me to understand how to do this with a clear separation. In that example, logic tests test files from the library target, not the application target. The model was encapsulated into a library which was then linked with the main target and logic tests target. The application target contained only views and controllers.

在较早的回答中指出,对于这种情况,逻辑测试是正确的做法。我在使用 XCode 版本 4.3.2 (4E2002) 进行逻辑测试时遇到了非常困难的时间。查看Apple 的示例单元测试项目帮助我了解如何通过清晰的分离来做到这一点。在该示例中,逻辑测试来自库目标的测试文件,而不是应用程序目标。该模型被封装到一个库中,然后与主要目标和逻辑测试目标链接。应用程序目标仅包含视图和控制器。

Based on this model, this is what I did to get my logic tests work correctly. Create a new target (Cocoa Touch Static Library) and move all files to be logic tested (typically all your models) to this new target. Under "Build Phases"settings add this new library in "Link Binary With Libraries"of your application target and logic tests target.

基于此模型,这就是我为使逻辑测试正常工作所做的工作。创建一个新目标(Cocoa Touch 静态库)并将所有要进行逻辑测试的文件(通常是您的所有模型)移动到这个新目标。在“构建阶段”设置下,在应用程序目标和逻辑测试目标的“链接二进制库”中添加这个新库。

I can imagine that these instructions are little confusing. If you dissect the sample project that is mentioned above you will get a better idea.

我可以想象这些说明有点令人困惑。如果您剖析上面提到的示例项目,您会得到一个更好的主意。

回答by mxcl

Note, untested on Xcode 5.

注意,未在 Xcode 5 上测试。

I used @jon-reid's answer, but found that Xcode adds environment-variables to the xcuserstatedpart of XcodeProjects, and these are user specific and not typically committed to the repository. Thus I swizzle my AppDelegateto override its loading:

我使用了@jon-reid 的回答,但发现 Xcode 将环境变量添加到xcuserstatedXcodeProjects 部分,这些是特定于用户的,通常不会提交到存储库。因此,我 swizzly 我AppDelegate覆盖它的加载:

@implementation MyAppDelegate (Testing)

+ (void)initialize {
    SEL new = @selector(application:didFinishLaunchingWithOptions:);
    SEL orig = @selector(swizzled_application:didFinishLaunchingWithOptions:);
    Class c = [self class];
    Method origMethod = class_getInstanceMethod(c, orig);
    Method newMethod = class_getInstanceMethod(c, new);

    if (class_addMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))) {
        class_replaceMethod(c, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
    } else {
        method_exchangeImplementations(origMethod, newMethod);
    }
}

- (BOOL)swizzled_application:(id)app didFinishLaunchingWithOptions:(id)opts {
    return YES;
}

@end

Note, that the following is simpler and still works, though I'm not sure it is reliable:

请注意,以下更简单并且仍然有效,但我不确定它是否可靠:

@implementation MyAppDelegate (Testing)

- (BOOL)application:(id)app didFinishLaunchingWithOptions:(id)opts {
    return YES;
}

@end

This works because categories of methods in dynamically loaded components (like the testing bundle) take precedence. Swizzling feels safer though.

这是有效的,因为动态加载的组件(如测试包)中的方法类别优先。不过,Swizzling 感觉更安全。

回答by rustylepord

Using xCode 7 and xctool

使用 xCode 7 和 xctool

xctoolis capable of executing unit tests without the simulator.

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

To get this working,

为了让这个工作,

1 . Update the target settings run without a host app.

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

Select your project --> then test target --> Set the host application to none.

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

enter image description here

在此处输入图片说明

2. Install xctool , if you don't have it.

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

brew install xctool

3. Run the tests using terminal with xctool.

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

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

回答by justin

i've used GHUnitto create osx/ios compatible test suites. there are a few issues, but i found it was more reliable/compatible/straightforward than OCUnit.

我已经使用GHUnit创建了 osx/ios 兼容的测试套件。有一些问题,但我发现它比 OCUnit 更可靠/兼容/直接。

GHUnit provides basic template projects for OS X and iOS, which makes initial setup simple.

GHUnit 为 OS X 和 iOS 提供了基本的模板项目,这使得初始设置变得简单。

Note: I generally just use my own kit for most of my testing.

注意:我通常只使用自己的套件进行大部分测试。