Xcode UITest иногда не находит свойства XCUIElement

В моих тестах пользовательского интерфейса свойство frame некоторых XCUIElement найдены, но не других.
Используемые ниже идентификаторы доступности устанавливаются в раскадровке, и app инициализируется в setUp() как XCUIApplication(),

Вот схема раскадровки:

В тесте используются два элемента пользовательского интерфейса: текстовое поле и кнопка добавления.

Вот соответствующий код:

func test() {
    // given
    let mainViewNavigationBar = app.navigationBars[„NavBar“]
    let navBarHeight = mainViewNavigationBar.frame.size.height
    print("navBarHeight: \(navBarHeight)") // is printed out correctly

    let addShoppingItemTextField = app.textFields["TextField"]
    let textFieldHeight = addShoppingItemTextField.frame.size.height // error breakpoint here
    print("textFieldHeight: \(textFieldHeight)")
}

Тест останавливается на контрольной точке ошибки во второй последней строке со следующим сообщением:

No matches found for Find: Descendants matching type TextField from input {(
    Application, 0x60000019f070, pid: 13114, label: ‚xxx‘
)}

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

РЕДАКТИРОВАТЬ

Олета указала ниже, что моя постоянная addShoppingItemTextField является XCUIElementQuery это должно быть решено, когда я пытаюсь прочитать frame собственность textField,
Действительно, когда программа останавливается на контрольной точке ошибки и я печатаю ее описание, я получаю

Printing description of addShoppingItemTextField:
Query chain:
 →Find: Target Application 0x6080000a6ea0
  ↪︎Find: Descendants matching type TextField
    ↪︎Find: Elements matching predicate '"TextField" IN identifiers'  

Но найти не удается, хотя Accessibility включен, и Accessibility Identifier установлен на TextField:

Я тоже вставил в приложение

print(textField.accessibilityIdentifier!)

в viewDidLoad()и распечатал TextField правильно.

В качестве обходного пути я установил тест на запись и нажал textField, Этот созданный код для доступа к textField, Я тогда заменил пусть addShoppingItemTextField = app.textFields["TextField"] по (правая сторона была сгенерирована записью):

let addShoppingItemTextField = app.otherElements.containing(.navigationBar, identifier:"WatchNotOK")
.children(matching: .other).element.children(matching: .other).element
.children(matching: .other).element

И теперь код работает без ошибок.

Так что мне кажется, что запрос идентификатора доступности textField не работает правильно.

РЕДАКТИРОВАТЬ 2

Я сдаюсь: не изменяя ничего в раскадровке, тест теперь останавливается с той же самой ошибкой теста (не найдено совпадений для Find: совпадения элементов с предикатом "Идентификаторы WatchNotOK IN") в строке let navBarHeight = mainViewNavigationBar.frame.size.height, Это работало все время.
Это указывает на то, что тесты Xcode UI не работают.

2 ответа

Решение

Я связался с Apple, и они нашли мою ошибку:
Вид моего основного контроллера видимости accessibility свойство установлено в true, Это было неправильно; должно быть установлено false:

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

Объяснение можно найти в документации к isAccessibilityElement:

Значение по умолчанию для этого свойства равно false, если только получатель не является стандартным элементом управления UIKit, в этом случае значение равно true.
Вспомогательные приложения могут получать информацию только об объектах, представленных элементами доступности. Поэтому, если вы реализуете пользовательский элемент управления или представление, которое должно быть доступно пользователям с ограниченными возможностями, установите для этого свойства значение true. Единственным исключением из этой практики является представление, которое просто служит контейнером для других элементов, которые должны быть доступны. Такое представление должно реализовывать протокол UIAccessibilityContainer и устанавливать для этого свойства значение false.

Как только я установил доступность основного представления на false, тест пользовательского интерфейса прошел успешно.

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

Проблема не в том, что frame свойство не найдено для элемента, так как сам элемент не может быть найден.

каждый XCUIElement происходит от XCUIElementQuery, Первая попытка выполнить запрос, как и следовало ожидать, не при назначении значения addShoppingItemTextField, но при первом обращении к собственности (кроме exists) на addShoppingItemTextField,

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

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