Ответ 1
Вы должны определить правильное значение для "Макросы препроцессора" в настройках цели.
Во время выполнения вы можете проверить его с предложением ifdef
.
Есть ли какой-либо способ программно определить, запущен ли код в целевой тесте против обычной целевой задачи запуска при разработке приложений iOS?
У меня есть проверка проверки, является ли эта переменная нулевой или нет, поскольку она только в моей тестовой цели, но это кажется довольно взломанным.
[[[NSProcessInfo processInfo] environment] objectForKey:@"XCInjectBundle"]
Вы должны определить правильное значение для "Макросы препроцессора" в настройках цели.
Во время выполнения вы можете проверить его с предложением ifdef
.
Ни один из этих ответов не помог мне. Я хотел, чтобы мое приложение узнало, когда я запускал тесты с единственной целью ограничить регистрацию в моих тестовых целях. Тесты выполняются быстрее, когда я не регистрирую кучу вещей. Итак, я сделал это, добавив настраиваемый аргумент в тестовую часть моей схемы:
В моем коде приложения теперь я могу проверить, тестирую ли я или нет:
- (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
Протестировано на Xcode 7.3
Создайте категорию на NSProcessInfo
.
@implementation NSProcessInfo (RunningTests)
- (BOOL)ag_isRunningTests {
return ([self.environment objectForKey:@"XCTestConfigurationFilePath"] != nil);
}
@end
Теперь мы можем просто проверить это с помощью одной строки кода для " UITesting".
[[[NSProcessInfo processInfo] arguments] containsObject:@"-ui_testing"]
-ui_testing появится только при тестировании приложения.
Спасибо! Помогает. Вот пример для быстрого:
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
}
В Xcode 6 вы можете проверить значение XPC_SERVICE_NAME
в переменных среды, чтобы проверить, не работает ли Simulator тесты или приложение.
При прямом запуске переменная будет иметь что-то вроде 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;
}
В настройках проекта на вкладке "Информация" создайте новую конфигурацию (в дополнение к "Debug" по умолчанию и "Release" ). Затем вы сможете определить различные макросы препроцессора в целевых настройках (на вкладке "Настройки сборки" ) для каждой конфигурации. XCode уже использует это, чтобы добавить "DEBUG = 1" для конфигурации Debug, которая позволяет вам использовать "#ifdef DEBUG" в вашем коде. Вы можете добавить любые другие макросы, которые вам нравятся, например "TESTING = 1".
Спасибо @steven-hepting, ваш ответ помог мне указывать в правильном направлении, чтобы решить мою проблему.
Но при использовании "Host Application" в ваших модульных тестах "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;
}