Как определить, работает ли приложение iOS в режиме тестирования пользовательского интерфейса
Я хочу, чтобы мое приложение запускало специальный код (например, сбросив его состояние) при работе в режиме тестирования пользовательского интерфейса. Я посмотрел на переменные среды, которые устанавливаются, когда приложение запускается из UI Testing, и нет никаких очевидных параметров для разграничения между обычным приложением, используемым при тестировании пользовательского интерфейса. Есть ли способ узнать?
Два обходных решения, которые меня не устраивают:
- Установите
XCUIApplication.launchEnvironment
с некоторой переменной, которую я позже проверю в приложении. Это не хорошо, потому что вы должны установить его в методе setUp
для каждого тестового файла. Я попробовал установить переменную окружения из параметров схемы, но не распространяется на приложение непосредственно при запуске тестов тестирования пользовательского интерфейса.
- Проверьте отсутствие существования переменной окружения
__XPC_DYLD_LIBRARY_PATH
. Это кажется очень взломанным и может работать только сейчас из-за совпадения в том, как у нас установлены настройки целевой настройки.
Ответы
Ответ 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, тогда это установит пользовательскую настройку или переменную окружения или что-то другое, что впоследствии можно будет проверить в приложении. Это похоже на хакерство, но я не мог понять, как это сделать.
Два процесса имеют свои собственные переменные среды, пользовательские значения по умолчанию и параметры запуска.