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

Как определить, работает ли приложение iOS в режиме тестирования пользовательского интерфейса

Я хочу, чтобы мое приложение запускало специальный код (например, сбросив его состояние) при работе в режиме тестирования пользовательского интерфейса. Я посмотрел на переменные среды, которые устанавливаются, когда приложение запускается из UI Testing, и нет никаких очевидных параметров для разграничения между обычным приложением, используемым при тестировании пользовательского интерфейса. Есть ли способ узнать?

Два обходных решения, которые меня не устраивают:

  • Установите XCUIApplication.launchEnvironment с некоторой переменной, которую я позже проверю в приложении. Это не хорошо, потому что вы должны установить его в методе setUp для каждого тестового файла. Я попробовал установить переменную окружения из параметров схемы, но не распространяется на приложение непосредственно при запуске тестов тестирования пользовательского интерфейса.
  • Проверьте отсутствие существования переменной окружения __XPC_DYLD_LIBRARY_PATH. Это кажется очень взломанным и может работать только сейчас из-за совпадения в том, как у нас установлены настройки целевой настройки.
4b9b3361

Ответ 1

Я сам изучал это и наткнулся на этот вопрос. Я закончил с первой попыткой @LironYahdav:

В вашем тесте пользовательского интерфейса:

- (void)setUp
{
    [super setUp];

    XCUIApplication *app = [[XCUIApplication alloc] init];
    app.launchEnvironment = @{@"isUITest": @YES};
    [app launch];
}

В вашем приложении:

NSDictionary *environment = [[NSProcessInfo processInfo] environment];
if (environment[@"isUITest"]) {
    // Running in a UI test
}
Решения

@JoeMasilotti полезны для модульных тестов, потому что они используют ту же среду выполнения, что и тестируемое приложение, но не имеют отношения к тестированию пользовательского интерфейса.

Ответ 2

Для этого вы можете использовать Макросы для препроцессора. Я обнаружил, что у вас есть несколько вариантов:

Новая цель

Сделайте копию целевого объекта приложения и используйте его как Целевая аудитория. Любой препроцессорный макрос в этой целевой копии доступен в коде.

Один недостаток - вам придется добавлять новые классы/ресурсы в цель копирования, а иногда очень легко забыть.

Конфигурация новой сборки

Сделайте дубликат конфигурации сборки Debug, установите для этой конфигурации любой макрос препроцессора и используйте его для своего теста (см. скриншоты ниже).

Небольшая информация: всякий раз, когда вы хотите записать сеанс тестирования пользовательского интерфейса, вам нужно изменить Run, чтобы использовать новую конфигурацию тестирования.

Добавьте дублируемую конфигурацию:

Добавить дубликат conf

Используйте его для своего Тест:

Использовать его для вашего * Test *

Ответ 3

Мне не удалось установить среду запуска, но она заставила его работать с аргументами запуска.

В ваших тестах функция setUp() добавляет:

  let app = XCUIApplication()
  app.launchArguments = ["testMode"]
  app.launch()

В своем производственном коде добавьте проверку как:

let testMode =  NSProcessInfo.processInfo().arguments.contains("testMode")
if testMode {
  // Do stuff
}

Проверено с использованием XCode 7.1.1.

Ответ 4

Я только что добавил это расширение

 @available(iOS 9, *)
 extension XCUIApplication {

 func test(){
   launchEnvironment = ["TEST":"true"]
   launch()
  }
 }

Поэтому я могу просто использовать test() вместо launch()

Ответ 5

В Swift 3 вы можете проверить ключ XCInjectBundleInto или что-то, начинающееся с XC.

let isInTestMode = ProcessInfo.processInfo.environment["XCInjectBundleInto"] != nil

Это также работает и в OS X.

Ответ 6

Swift 3 на основе предыдущих ответов.

class YourApplicationUITests: XCTestCase {

    override func setUp() {
        super.setUp()

        // Put setup code here. This method is called before the invocation of each test method in the class.

        // In UI tests it is usually best to stop immediately when a failure occurs.
        continueAfterFailure = false
        // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
        let app = XCUIApplication()
        app.launchArguments = ["testMode"]
        app.launch()

        // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
    }

    override func tearDown() {
        // Put teardown code here. This method is called after the invocation of each test method in the class.
        super.tearDown()
    }

    func testExample() {
        // Use recording to get started writing UI tests.
        // Use XCTAssert and related functions to verify your tests produce the correct results.
    }

}


extension UIApplication {
    public static var isRunningTest: Bool {
        return ProcessInfo().arguments.contains("testMode")
    }
}

Затем просто вызовите UIApplication.isRunningTest в вашем коде.

Ответ 7

Я думаю, что самое легкое, что нужно сделать, это положить какое-то пасхальное яйцо в свой пользовательский интерфейс сразу после запуска приложения, а затем проверить, что это пасхальное яйцо в приложении. Поэтому, если сначала нажать на определенную кнопку 10X, тогда это установит пользовательскую настройку или переменную окружения или что-то другое, что впоследствии можно будет проверить в приложении. Это похоже на хакерство, но я не мог понять, как это сделать.

Два процесса имеют свои собственные переменные среды, пользовательские значения по умолчанию и параметры запуска.