当我运行单元测试时,我想跳过一些代码(例如,我不希望[[UIApplication sharedApplication] openURL:..]
运行)。我正在寻找运行时检查我是否正在运行单位测试。
我知道如果单元测试正在运行但又找不到它,我已经看过检查Objective-C运行时的代码。
答案 0 :(得分:17)
您可以使用this method
中的google-toolbox-for-mac// Returns YES if we are currently being unittested.
+ (BOOL)areWeBeingUnitTested {
BOOL answer = NO;
Class testProbeClass;
#if GTM_USING_XCTEST // you may need to change this to reflect which framework are you using
testProbeClass = NSClassFromString(@"XCTestProbe");
#else
testProbeClass = NSClassFromString(@"SenTestProbe");
#endif
if (testProbeClass != Nil) {
// Doing this little dance so we don't actually have to link
// SenTestingKit in
SEL selector = NSSelectorFromString(@"isTesting");
NSMethodSignature *sig = [testProbeClass methodSignatureForSelector:selector];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig];
[invocation setSelector:selector];
[invocation invokeWithTarget:testProbeClass];
[invocation getReturnValue:&answer];
}
return answer;
}
使用NSClassFromString
和NSInvocation
的原因是允许代码编译而不链接到xctest或ocunit
答案 1 :(得分:12)
选择项目,然后选择测试目标:
选择Build Settings,然后选择All and Combined。输入' preproc'在搜索框中 - 您在预处理器宏之后。
将一个宏添加到名为TEST
的调试配置中,并将其设置为1
:
然后在您的代码中,您可以执行此操作:
#ifndef TEST
[[UIApplication sharedApplication] doEvilThingForTesting];
#endif
或者,如果您有仅在测试环境中运行的代码:
#ifdef TEST
[[UIApplication sharedApplication] doAwesomeTestOnlyThing];
#endif
它不完全是运行时,但是单元测试人员在运行测试IIRC之前编译代码,所以它应该是相同的效果 - 你实际上是在修改代码在运行测试之前。
答案 2 :(得分:12)
而是我正在测试?#34;在整个生产代码中的条件,我将支票隔离到一个地方:main
。在那里,我检查了一个备用应用程序委托进行测试。如果它可用,我使用它而不是常规应用程序委托。这完全绕过了常规的启动顺序:
int main(int argc, char *argv[])
{
@autoreleasepool {
Class appDelegateClass = NSClassFromString(@"TestingAppDelegate");
if (!appDelegateClass)
appDelegateClass = [AppDelegate class];
return UIApplicationMain(argc, argv, nil, NSStringFromClass(appDelegateClass));
}
}
您可以在此处详细了解此技术:How to Easily Switch Your iOS App Delegate for Testing
答案 3 :(得分:6)
我认为您可以像Xcode 7.3一样检查
-(BOOL) isRunningUnitTests
{
NSDictionary* environment = [ [ NSProcessInfo processInfo ] environment ];
NSString* theTestConfigPath = environment[ @"XCTestConfigurationFilePath" ];
return theTestConfigPath != nil;
}
答案 4 :(得分:3)
我不确定这会持续多久,但它现在适用于版本9.0 beta 6(9M214v)。
let isTesting = { () -> Bool in
if let _ = ProcessInfo.processInfo.environment["XCTestConfigurationFilePath"] {
return true
} else if let testingEnv = ProcessInfo.processInfo.environment["DYLD_INSERT_LIBRARIES"] {
return testingEnv.contains("libXCTTargetBootstrapInject.dylib")
} else {
return false
}
}()
不需要更改构建环境或方案。
根据您是运行单个测试用例还是整个测试套件,似乎有两个不同的环境变量。此外,变量值也会有所不同,具体取决于您是在模拟器中还是在真实设备上运行。
答案 5 :(得分:2)
最简单的方法(并在Xcode 7中使用XCTest!)检查方法是查看匹配的O(n^2)
包的进程信息:
xctest
来源:https://www.objc.io/issues/1-view-controllers/testing-view-controllers/#integration-with-xcode
答案 6 :(得分:1)
请使用:
+ (BOOL)isUnitTestRunning
{
Class testProbeClass;
testProbeClass = NSClassFromString(@"XCTestProbe");
return (testProbeClass != nil);
}