【问题标题】:Xcode project how to detect target programmatically or how to use env varsXcode 项目如何以编程方式检测目标或如何使用环境变量
【发布时间】:2011-10-21 08:00:21
【问题描述】:

我想做一个应用程序测试,解析一些 json,存储到核心数据,并读出一些对象。

我的代码如何知道它是作为测试的一部分运行还是作为正常运行的一部分运行?只是某种方式知道“我们在测试目标中”吗?因为应用程序现在启动时会启动一堆请求,用来自服务器的信息填充我的核心数据。我不希望它在我的测试期间这样做。我想启动应用程序,从文件中读取 HARDCODED json 并使用与其他方法相同的方法将其存储到 coredata 中,然后验证结果。

如果有人可以解释如何根据每个目标传递特定的键值对,并且可以从应用程序中读取,我会更加高兴。

【问题讨论】:

    标签: objective-c configuration xcode4 integration-testing


    【解决方案1】:

    通常在单元测试中,程序员使用模拟类和功能。 您可以为测试目标创建一个具有目标成员资格的类。

    @interface MockClass : NSObject
    
    @end
    

    然后在应用程序代码中,您可以使用 NSClassFromString 函数检查类是否存在(该函数将返回 Nil 用于未包含在类的目标成员中的目标,在这种情况下 - 非测试目标。

    if (NSClassFromString(@"MockClass")) {
        //Test Target
    } else {
        //App Target
    }
    

    你可以诅咒它的功能

    BOOL isUnitTest(){
        return NSClassFromString(@"MockClass") != Nil;
    }
    

    【讨论】:

      【解决方案2】:

      没关系...发现它是在“方案”中设置的。

      例如,如果您希望 TARGET=TEST 在测试期间可用,而 TARGET=RUN 在运行期间显示,只需在您的方案 > 环境变量 > 名称/值中进行设置。

      然后你可以在你的应用中做:

      [[[NSProcessInfo processInfo] environment] objectForKey:@"TARGET"]
      

      使用带有预处理器宏的构建设置对我不起作用 b/c 我的测试目标(用于应用程序/集成测试)取决于我的主要(非测试)目标,因此首先构建主要目标,然后运行,即使您在运行的目标中定义的宏之后,您也会得到主要的目标预处理器宏。如果我在这里遗漏了什么,请随时解释。

      【讨论】:

      • 很好的答案!次要补充:如果你把它设为isTargetTest=YES,那么你可以从[[[NSProcessInfo processInfo] environment] objectForKey:@"isTargetTest"] 读回一个布尔值。 BOOL 可以直接在if-statement 中使用,无需比较字符串
      • 这为我返回 null
      【解决方案3】:

      有两种情况需要处理:

      1. 如果选择了某个目标,例如Tests,则运行一些代码,并且
      2. 有条件地#import某些文件用于特定目标,例如Tests

      测试目标的目标代码:

      在您的ProjectName-Prefix.pch 文件中创建一个宏,如下所示:

      #define IsTestTarget [[[[NSProcessInfo processInfo] environment][@"XCInjectBundle"] pathExtension] isEqualToString:@"xctest"]
      

      然后在应用程序的任何地方调用它:

      if (IsTestTarget) {
          //Do something specific for test target;
      } else {
          //Otherwise do something else
      }
      

      有条件的#import:

      #import某些文件选择Tests target时,您需要在Test target中添加Preprocessor Macro target并使用它为:

      #ifdef APPTESTS
          #import "TestSpecificFile.h"
      #else
          #import "SomeOtherFile.h"
      #endif 
      

      以下是添加Preprocessor Macro的方法:

      【讨论】:

      • 不幸的是,条件导入对我不起作用。测试目标的预处理器宏只会影响测试源文件。 “生产”类将使用主要目标设置构建。
      • 您的应用程序始终使用应用程序目标构建,这旨在向您展示一种以编程方式找出正在运行的测试的方法。如果你没有运行测试,那么无论如何你都不需要这个。
      【解决方案4】:

      您可以使用以下功能。

      +(BOOL)  isRunningTests
      {
          NSDictionary* environment = [[NSProcessInfo processInfo] environment];
          NSString* injectBundle = environment[@"XCInjectBundle"];
          return [[injectBundle pathExtension] isEqualToString:@"xctest"];
      }
      

      【讨论】:

        【解决方案5】:

        如果“测试目标”是指您的单元测试(即Product > Test⌘U),您可以将预处理器宏添加到目标并在代码中检查该宏。这允许执行以下操作:

        #ifdef TEST
          // Load the hard-coded data.
        #else
          // Load data from the server.
        #endif
        

        为此,请在项目导航器中单击您的项目文件,选择您的测试目标,单击Build Settings 选项卡,搜索“宏”,双击Preprocessor Macros 选项,然后添加一个!

        【讨论】:

          猜你喜欢
          • 2018-12-22
          • 1970-01-01
          • 1970-01-01
          • 2011-09-05
          • 1970-01-01
          • 2011-11-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多