Тесты пользовательского интерфейса-isSelected всегда возвращает false

недавно мы обновили проект Swift 2.3 до Swift 3 с помощью Xcode 8.2.1 (8C1002), и теперь большинство наших тестов пользовательского интерфейса, связанных с tableViews и isselected свойство не работают. Он всегда возвращает false, даже когда объект выбран (мы можем видеть его в симуляторе iOS).

кто-нибудь испытывал подобные проблемы? Наш код обычно работал в Swift 2.3 до преобразования. Вот как мы получаем tableView ячейка:

let cell = app.tables.cells.element(at: 4)

Примечание: app является XCUIApplication.

и вот как мы проверяем, выбран он или нет:

XCTAssert(cell.isSelected)

другое наблюдение заключается в том, что мы уверены, что объект существует, потому что waitForExpectations возвращается true:

let existsPredicate = NSPredicate(format: "exists = 1")
expectation(for: existsPredicate, evaluatedWith: cell, handler: nil)
waitForExpectations(timeout: 20, handler: nil)

EDIT: для того, чтобы заменить isSelected, Я пытался использовать NSPredicate с selected = 1 и isSelected = 1. Ничего не помогало. Я также попытался использовать acessibilityValue на основе других вопросов ответ, однако это было не так просто, так как иногда элементы в моем представлении таблицы выбираются/не выбираются программно. Кроме того, этот метод включал добавление тестового кода в приложение, что не является хорошей практикой.

РЕДАКТИРОВАТЬ ПОСЛЕ ОКОНЧАНИЯ BOUNTY: поскольку никто не мог найти решение этой проблемы, и это, очевидно, ошибка в Xcode, я отправил отчет об ошибке в Apple. Я прокомментирую здесь, когда они выпустят версию Xcode с исправлением.

4 ответов


Я сделал несколько тестов и провести небольшое исследование. Вы можете проверить приложение, созданное для этой цели >>здесь. Было бы здорово, если бы вы могли проверить это (это потребовало немного работы). Есть также тесты UI, чтобы доказать, что он работает. Кроме того, доступны два варианта: один-vanilla XCTest и одна библиотека с большим количеством помощников, которые я создаю со своими коллегами автоматизация. Но дело не в этом.

вот что я узнал:

1) isSelected собственность XCUIElement зависит от accessibilityTrait. Элемент для выбора в XCTest должен иметь UIAccessibilityTraitSelected set.

2) я не мог воспроизвести вашу проблему, но я смог контролировать isSelected собственность.

3) Да, для этого требуется немного кода, но он должен хорошо работать с VoiceOver, если это важно для вас.

весь необходимый код находится в вашем обычае UITableViewCell подкласс. И использует переопределение UIAccessibilityElement accessibilityTraits собственность.

private var traits: UIAccessibilityTraits = UIAccessibilityTraitNone

// MARK: UITableViewCell life cycle
override func awakeFromNib() {
    super.awakeFromNib()
    traits = super.accessibilityTraits
}

// MARK: UIAccessibilityElement
override var accessibilityTraits: UIAccessibilityTraits {
    get {
        if isSelected {
            return traits | UIAccessibilityTraitSelected
        }
        return traits
    }

    set {
        traits = newValue
    }
}

надеюсь, что это помогает.


вы пробовали сделать точку останова до и после нажатия и проверить значение ячейки? Как видео WWDC здесь:https://youtu.be/7zMGf-0OnoU (От 10 минут)


isSelected работает только на представлениях, которые наследуются от UIControl. UIControl.isSelected сообщает XCUIElement.isSelected.

С UITableViewCell не наследуется от UIControl, вы не видите значение в тестах, когда вы наблюдаете cell.isSelected.

Я предлагаю, если вы хотите, чтобы это можно было проверить с помощью тестов пользовательского интерфейса, которые вы подаете запрос функции с Apple, чтобы сделать UIControl протокол, который вы могли бы затем расширить свои ячейки, чтобы соответствовать, или добавить UITableViewCell.isSelected к свойствам которые сообщают XCUIElement.isSelected.


@dzoanb решение может работать без добавления частного var:

override var accessibilityTraits: UIAccessibilityTraits {
    get {
        if isSelected {
            return super.accessibilityTraits | UIAccessibilityTraitSelected
        }
        return super.accessibilityTraits
    }

    set {
        super.accessibilityTraits = newValue
    }
}