UITesting, XCTest текущий класс ViewController

Простая проблема. У меня есть кнопка, которая выполняет переход к следующему контроллеру представления. Я хочу написать UI XCTest, чтобы узнать, есть ли открытый контроллер представления, который я хотел.


person Dejan Zuza    schedule 23.11.2015    source источник


Ответы (2)


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

Однако, если вы подумаете о своем тесте немного иначе, вы можете сделать очень похожее утверждение. Напишите свои тесты, как если бы вы были пользователем. Пользователь не заботится о том, смотрит ли он / она на ItemDetailViewController или ItemListTableViewController, так что и ваши тесты тоже.

Пользователь заботится о том, что на экране. Какое название? Или как называются эти кнопки? Следуя этой логике, вы переписываете свой тест, чтобы утверждать, основываясь на этих элементах, а не на имени закодированного класса.

Например, если вы представляете свой контроллер в стеке навигации, вы можете подтвердить заголовок.

let app = XCUIApplication()
app.buttons["View Item"].tap()

XCTAssert(app.navigationBars["Some Item"].exists)

Или, если экран представлен модально, но вы знаете какой-то статический текст или кнопки, используйте их.

let app = XCUIApplication()
app.buttons["View Item"].tap()

XCTAssert(app.staticTexts["Item Detail"].exists)
XCTAssert(app.buttons["Remove Item"].exists)
person Joe Masilotti    schedule 23.11.2015
comment
В моем случае мне нужно sleep(1) перед app.buttons["View Item"].tap(), чтобы он заработал - person onmyway133; 04.04.2016
comment
Я чувствую, что должен быть лучший способ сделать это ... Что произойдет, если вы измените текст в приложении? Что произойдет, если у вас есть несколько локализаций текста в приложении? Кажется, что потребовалось бы довольно много тестов, если бы он был локализован, и потенциальная головная боль при обслуживании, если бы текст нужно было изменить. - person Matt Green; 12.10.2016
comment
@MattGreen, тогда вы должны назначить идентификаторы доступности таким меткам / текстовым полям и т. Д. Тогда это будет похоже на let button = app.buttons [accessId], XCTAssertEqual (button.label, EXPECTED LABEL) и / или button.tap () - person Hasaan Ali; 30.04.2018
comment
@JoeMasilotti с вашим методом, можно ли вызвать accessibilityCustomAction с помощью XCUITest, пожалуйста? - person XLE_22; 02.05.2019

Комментарий Мэтта Грина дал мне хорошую идею. Мы можем определить неиспользуемую метку / кнопку, в идеале внутри контроллера базового представления, и назначить ей метку доступности для выполнения запроса, чтобы узнать, какой контроллер представления представлен.

public class BaseViewController: UIViewController {

    let button = UIButton(frame: CGRect(x: 0, y: 0, width: 1, height: 1))

    public override func viewDidLoad() {
        super.viewDidLoad()
        if let identifier = self.theClassName.split(separator: ".").last {
            button.accessibilityIdentifier = String(identifier)
            view.addSubview(button)
        }
    }
}

public class DatePickerViewController: BaseViewController {
   ...
}

func testExample() {
    let app = XCUIApplication()
    app.launch()
    app.navigationBars.buttons["DateSelector"].tap()
    XCTAssertTrue(app.buttons["DatePickerViewController"].exists)
}

Обратите внимание, что для того, чтобы этот подход работал, вам необходимо добавить представление, которое вы используете для идентификации контроллера представления, в этом случае кнопку, следует добавить как вспомогательное представление и должно иметь ненулевой фрейм.

person Olcay Ertaş    schedule 21.02.2020