Как мой тест XCode UI обнаруживает, что экран изменился?

Я пытаюсь создать пешеход с помощью XCode 7 XCTest UI, который систематически исследует детерминированное дерево табличных представлений на заданную глубину. Он почти работает, за исключением того, что я не могу надежно определить, действительно ли нажатие на какой-либо данный элемент вызвало переход на новый экран. У меня есть хакерский метод, который работает большую часть времени, чтобы обнаружить, что либо наклейка навигационной панели изменилась, либо изменилось количество элементов меню.

Первый тест имеет ложные негативы, потому что на последовательных экранах могут быть одинаковые ярлыки навигационных баров (кодовая база, которую я хожу, не моя). Второй тест имеет ложные срабатывания, потому что иногда нажатие на элемент таблицы не переходит на другую таблицу/экран, а вместо этого добавляет дополнительные элементы к текущему экрану.

После некоторого чтения казалось, что использование меток доступности может быть способом. Поэтому я устанавливаю идентификатор UID для метки доступности навигационной панели в коде приложения (в viewDidAppear), а затем тестирую его в тестовом коде UI. Кажется, что это должно работать, но я только когда-либо возвращаю значение nil в тестовом коде.

Я буду свободно признаваться, что я - noob, когда речь заходит о тестировании пользовательского интерфейса, и в основном это сокращение/вставка/адаптация кода других людей без четкого понимания того, что я делаю. Поэтому я, вероятно, делаю какую-то наивную ошибку, в самом коде метки доступности и, возможно, на концептуальном уровне для обнаружения того, что экран изменился; возможно, там что-то гораздо более простое/более идиоматическое, чем я мог бы делать.

В приложении:

- (void)viewDidAppear: (BOOL)animated {

    [super viewDidAppear: animated];

    //...

    UINavigationBar* navBar = self.navigationController.navigationBar;
    if( navBar )
    {
        static NSInteger s_UID = 0;
        navBar.topItem.accessibilityLabel = [NSString stringWithFormat:@"UID-%ld", s_UID++];
    }
}

В тесте XCTest UI:

- (NSString*) navBarAccessibilityLabel: (XCUIApplication*) app
{
    NSString* result = NULL;

    XCUIElementQuery *navBars = app.navigationBars;
    XCUIElement* firstElem = [navBars.staticTexts elementBoundByIndex:0];
    if( firstElem )
    {
        result = (NSString*)firstElem.accessibilityLabel; // This is always nil
    }

    return result;
}

Обратите внимание, что firstElem IS найден, и что я могу извлечь, например. firstElem.label от него очень счастливо.

Любая помощь была оценена.

Ответы

Ответ 1

Вы можете проверить, доступны ли элементы:

Щелкните левой кнопкой мыши внутри теста пользовательского интерфейса и начните запись, начнется симулятор, и вы можете щелкнуть элемент внутри симулятора, если элемент будет доступен. Xcode будет писать тестовый код для вас внутри метода testExample.

введите описание изображения здесь

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

введите описание изображения здесь

Кроме того, я думаю, что в вашем случае вы можете проверить это, добавив заголовок пункта навигации для каждого экрана, т.е. self.navigationItem.title = @"myScreen";

И затем проверьте экран с утверждением i.e.

// let app = XCUIApplication() // Swift

UIApplication *app = [UIApplication alloc] init]; // Objective-C

XCTAssertEqual(app.navigationBars.element.identifier, "myScreen") // Don't forget to import class XCTest

Ответ 2

Я бы использовал проверку моментальных снимков, используя библиотеку скриншотов Facebook.

Тестирование на основе просмотра означает, что то, что видит пользователь, - это то, что вы хотите, чтобы пользователь увидел. Это означает возможность обеспечить, чтобы разные версии ваших взглядов или разные состояния ваших взглядов, продолжают выглядеть одинаково. Тестирование на основе просмотра может быть использовано для обеспечения высокоуровневый тест, охватывающий множество случаев использования объекта.

Вы можете найти замечательную статью с более подробной информацией здесь.

Ответ 3

Предполагая, что вы указали правильные идентификаторы ваших контроллеров (чтобы их можно было различить), вы можете добавить это к используемым контроллерам вида:

#ifdef UITESTING
- (void) viewDidAppear: animated
{
  [super viewDidAppear: animated];
  // do your checking here
}
#endif

В вашем тестовом целевом проекте в настройках сборки есть раздел Proprocessor. Там вы можете установить макросы препроцессора. Просто добавьте 'UITESTING = 1' в настройку Debug и/или Release. Эффект заключается в том, что в вашей тестовой сборке будет определен UITESTING, поэтому весь код под #ifdef UITESTING будет включен препроцессором.