Подтвердить что ты не робот

Программно определить текущую цель (запуск или тест) в проекте iOS

Есть ли какой-либо способ программно определить, запущен ли код в целевой тесте против обычной целевой задачи запуска при разработке приложений iOS?

У меня есть проверка проверки, является ли эта переменная нулевой или нет, поскольку она только в моей тестовой цели, но это кажется довольно взломанным.

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

Ответ 1

Вы должны определить правильное значение для "Макросы препроцессора" в настройках цели.

Во время выполнения вы можете проверить его с предложением ifdef.

Ответ 2

Ни один из этих ответов не помог мне. Я хотел, чтобы мое приложение узнало, когда я запускал тесты с единственной целью ограничить регистрацию в моих тестовых целях. Тесты выполняются быстрее, когда я не регистрирую кучу вещей. Итак, я сделал это, добавив настраиваемый аргумент в тестовую часть моей схемы:

Scheme Screenshot

В моем коде приложения теперь я могу проверить, тестирую ли я или нет:

- (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

Ответ 3

Протестировано на Xcode 7.3

Создайте категорию на NSProcessInfo.

@implementation NSProcessInfo (RunningTests)

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

@end

Ответ 4

Теперь мы можем просто проверить это с помощью одной строки кода для " UITesting".

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

-ui_testing появится только при тестировании приложения.

Ответ 5

Спасибо! Помогает. Вот пример для быстрого:

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
}

Ответ 6

В 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;
}

Ответ 7

В настройках проекта на вкладке "Информация" создайте новую конфигурацию (в дополнение к "Debug" по умолчанию и "Release" ). Затем вы сможете определить различные макросы препроцессора в целевых настройках (на вкладке "Настройки сборки" ) для каждой конфигурации. XCode уже использует это, чтобы добавить "DEBUG = 1" для конфигурации Debug, которая позволяет вам использовать "#ifdef DEBUG" в вашем коде. Вы можете добавить любые другие макросы, которые вам нравятся, например "TESTING = 1".

Ответ 8

Спасибо @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;
}