Как мне сбросить данные приложения после каждого теста с тестированием пользовательского интерфейса Xcode 7?

Apple представила в Xcode 7 новый UI Testing, но я испытываю трудности, когда тесты запускают приложение, оно начинается с данных, которые были у приложения раньше. Это означает, что тесты не могут быть независимыми и могут зависеть от других тестов.

Невозможно получить доступ к пользовательским настройкам по умолчанию и другим данным, потому что приложение, которое выполняет тесты, не имеет доступа к пакету тестируемого приложения. Сценарии также не подлежат сомнению, потому что они могут быть запущены до или после тестирования. И нет способа, как выполнить NSTask на iOS, чтобы запустить скрипт перед каждым набором тестов.

Есть ли способ как сбросить данные приложения перед каждым набором тестов?

4 ответа

Решение

Не прямым способом. Но есть некоторые обходные пути.

XCUIApplication Можно установить аргументы командной строки и переменные среды, которые могут изменить поведение вашего приложения.

Простой пример вашего main.m файл:

int main(int argc, char * argv[]) {
#if DEBUG
    // Reset all data for UI Testing
    @autoreleasepool {
        for (int i = 1; i < argc; ++i) {
            if (0 == strcmp("--reset-container", argv[i])) {
                NSArray *folders = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
                NSFileManager *fm = [[NSFileManager alloc] init];
                for (NSString *path in folders) {
                    [fm removeItemAtPath:path error:nil];
                }
                // Also remove documents folder if necessary...
            }
        }
    }
#endif
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil,
                                 NSStringFromClass([AppDelegate class]));
    }
}

И в -[XCTestCase setUp] добавлять:

XCUIApplication *app = [[XCUIApplication alloc] init];
app.launchArguments = @[@"--reset-container"];
[app launch];

Если подготовка приложения для UITests внутри application:didFinishLaunchingWithOptions: нормально в вашем случае, тогда вы можете сделать следующее:

В setUp() метод расширения вашего тестового класса XCTestCase добавьте следующий код:

let application = XCUIApplication()
application.launchEnvironment = ["UITESTS":"1"]
application.launch()

Затем в application:didFinishLaunchingWithOptions: Вы можете проверить флаг, используя следующий код:

func application(_ application: UIApplication,
                 didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {

    let env = ProcessInfo.processInfo.environment
    if let uiTests = env["UITESTS"], uiTests == "1" {
        // do anything you want
    }
    // further set up code
}

Конечно, если это вариант для вас.

ПРИМЕЧАНИЕ: вместо настройки "1" в качестве аргумента в пользу "UITESTS" флаг, вы можете указать разные значения для разных тестовых случаев - или даже методов тестирования (но в этом случае вы должны запускать приложение из метода тестирования, а не setUp())

ПРИМЕЧАНИЕ 2. Я предлагаю обернуть код, связанный с флагом, в #if DEBUG блок.

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

Сначала я добавил фазу Run script, чтобы удалить ее при запуске тестов:

/usr/bin/xcrun simctl uninstall booted com.mycompany.bundleId

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

В моем случае мне потребовалось также сбросить разрешения. И есть возможность удалить ваше приложение и сбросить системные разрешения, просто заставив тест удалить приложение и перейти к настройкам.

Уже ответил в этой теме: Есть ли способ перезагрузить приложение между тестами в Swift XCTest UI в Xcode 7?

Другие вопросы по тегам