18

在开发 iOS 应用程序时,有没有办法以编程方式确定您是在 Test 目标中运行代码还是在常规 Run 目标中运行代码?

我有检查这个变量是否为 nil 的技巧,因为它只在我的测试目标中,但这看起来很 hacky。

[[[NSProcessInfo processInfo] environment] objectForKey:@"XCInjectBundle"]
4

10 回答 10

15

这些答案都没有真正帮助我。我希望我的应用程序知道我何时运行测试,其唯一目的是限制我的测试目标中的日志记录。当我不记录一堆东西时,测试运行得更快。所以,我通过在我的方案的测试部分添加一个自定义参数来做到这一点:

方案截图

在我的应用程序代码中,我现在可以检查我是否正在测试:

- (void)logError:(NSError*)error{
    if([[[NSProcessInfo processInfo] arguments] containsObject:@"-FNTesting"])
        return;

    NSLog(@"LOG THE ERROR");
}

感谢@cameronspickert 是我唯一能真正找到如何使用自定义参数的地方之一

http://cameronspickert.com/2014/02/18/custom-launch-arguments-and-environment-variables.html

于 2015-03-13T19:36:52.730 回答
11

您应该在目标设置中为“预处理器宏”定义适当的值。

在运行时,您可以用ifdef句子检查它​​。

于 2013-01-11T04:45:13.423 回答
4

在 Xcode 7.3 上测试

在 上创建一个类别NSProcessInfo

@implementation NSProcessInfo (RunningTests)

- (BOOL)ag_isRunningTests {
  return ([self.environment objectForKey:@"XCTestConfigurationFilePath"] != nil);
}

@end
于 2016-05-19T11:18:17.537 回答
4

现在我们可以简单地用一行代码来检查“ UITesting ”。

[[[NSProcessInfo processInfo] arguments] containsObject:@"-ui_testing"]

-ui_testing仅在测试应用程序时出现。

于 2016-10-26T07:19:39.227 回答
3

谢谢!它有助于。这里有一些关于 swift 的例子:

func isRunningTests() -> Bool {

    var arguments = NSProcessInfo.processInfo().arguments as! [String]
    println("arguments ===\(arguments)")

    let testArgs = arguments.filter({ $0 == "-FNTesting" })
    if !testArgs.isEmpty {
        return true
    }

     return false
}
于 2015-04-14T17:22:11.033 回答
2

在 Xcode 6 中,您可以检查XPC_SERVICE_NAME环境变量中的值,以查看模拟器是在运行测试还是直接运行应用程序。

直接运行时,变量将具有类似UIKitApplication:com.twitter.FabricSampleApp[0xb9f8]

运行单元测试时,它将如下所示:com.apple.xpc.launchd.oneshot.0x10000008.xctest

+ (BOOL)isRunningUnitTests {
    NSString *XPCServiceName = [NSProcessInfo processInfo].environment[@"XPC_SERVICE_NAME"];
    BOOL isTesting = ([XPCServiceName rangeOfString:@"xctest"].location != NSNotFound);

    return isTesting;
}
于 2015-07-16T23:50:21.773 回答
1

感谢@steven-hepting,您的回答帮助我指出了解决问题的正确方向。

但是在单元测试中使用“主机应用程序”时,“XPC_SERVICE_NAME”将返回与正常应用程序启动相同的字符串(显然)。因此,仅凭您的支票并不总是有效。这就是为什么我还要检查TestBundleLocation的原因。使用 Xcode 7.2 (7C68) 对此进行了测试。

+ (BOOL)isRunningUnitTests {
    NSDictionary<NSString *, NSString *> *env = [NSProcessInfo processInfo].environment;

    // Library tests
    NSString *envValue = env[@"XPC_SERVICE_NAME"];
    BOOL isTesting = (envValue && [envValue rangeOfString:@"xctest"].location != NSNotFound);
    if (isTesting) {
        return YES;
    }

    // App tests
    // XPC_SERVICE_NAME will return the same string as normal app start when unit test is executed using "Host Application"
    // --> check for "TestBundleLocation" instead
    envValue = env[@"TestBundleLocation"];
    isTesting = (envValue && [envValue rangeOfString:@"xctest"].location != NSNotFound);
    return isTesting;
}
于 2016-02-04T15:30:42.640 回答
0

在项目设置中,在 Info 选项卡上,创建一个新配置(除了默认的“Debug”和“Release”)。然后,您将能够根据每个配置在目标设置(在“构建设置”选项卡上)中定义不同的预处理器宏。XCode 已经使用它为调试配置添加“DEBUG=1”,这允许您在代码中使用“#ifdef DEBUG”。您可以通过这种方式添加您喜欢的任何其他宏,例如“TESTING=1”。

于 2013-01-11T04:49:19.650 回答
0

这对我有用

  #if Debug_MyTarget_Shortcut_name
    //My_Target_Codes
  #else
    //My_Other_Target_Codes
  #endif

在 Build setting -> Custom Flags 中,您应该为您的目标添加快捷方式名称

于 2018-04-08T06:15:03.083 回答
0

Xcode 13. Swift 版本只需检查是否environment包含XCTestConfigurationFilePath密钥

    func isTestRunning() -> Bool { ProcessInfo.processInfo.environment.keys.contains("XCTestConfigurationFilePath")}
于 2021-10-28T16:34:25.190 回答