Создать класс на основе макета для теста пользовательского интерфейса - PullRequest
0 голосов
/ 10 октября 2019

Я пишу тесты пользовательского интерфейса с эспрессо. На самом деле это выглядит так:

Scenario Outline: Successful login

    Given I start the application
    When I click email field
    And I enter valid email <email>
    And I click password field
    And I enter valid password <password>
    And I click sign in button
    Then I should see the end of synchronisation

private val robot = LoginScreenRobot()

    private val activityRule = ActivityTestRule(LoginActivity::class.java, false, false)


    @Given("^I start the application$")
    fun i_start_app() {
        robot.launchLoginScreen(activityRule)
    }

    @When("^I click email field$")
    fun i_click_email_field() {
        robot.selectEmailField()
    }

    @And("^I enter valid email (\\S+)$")
    fun i_enter_valid_email(email: String) {
        robot.enterEmail(email)
    }

    @And("^I click password field$")
    fun i_click_password_field() {
        robot.selectPasswordField()
    }

    @And("^I enter valid password (\\S+)$")
    fun i_enter_valid_password(password: String) {
        robot.enterPassword(password)
    }

    //...
    fun launchLoginScreen(testRule: ActivityTestRule<LoginActivity>) {
        testRule.launchActivity(null)
        uiDevice.waitForWindowUpdate(null, 2000)
    }

    fun selectEmailField() {
        onView(withId(R.id.login_edit_text)).perform(click())
    }

    fun selectPasswordField() {
        onView(withId(R.id.password_edit_text)).perform(click())
    }

    fun enterEmail(email: String) {
        onView(withId(R.id.login_edit_text))
            .perform(typeText(email), closeSoftKeyboard())
    }

    fun enterPassword(password: String) {
        onView(withId(R.id.password_edit_text))
            .perform(typeText(password), closeSoftKeyboard())
    }

    //...

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

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

class LoginHelper {
    val loginEditText = R.id.fragment_login_email_edit_text
    val passwordEditText = R.id.fragment_login_password_edit_text
    val signInButton = R.id.fragment_login_login_button
}

и изменить тест следующим образом:

 private val helper = LoginHelper()

    fun launchLoginScreen(testRule: ActivityTestRule<LoginActivity>) {
        testRule.launchActivity(null)
        uiDevice.waitForWindowUpdate(null, 2000)
    }

    fun selectEmailField() {
        onView(withId(helper.loginEditText)).perform(click())
    }

    fun selectPasswordField() {
        onView(withId(helper.passwordEditText)).perform(click())
    }

    fun enterEmail(email: String) {
        onView(withId(helper.loginEditText))
            .perform(typeText(email), closeSoftKeyboard())
    }

    fun enterPassword(password: String) {
        onView(withId(helper.passwordEditText))
            .perform(typeText(password), closeSoftKeyboard())
    }

Но 3 вещи: 1. Если один идентификатор меняется, я должен изменить класс помощника (это проще, но не идеально) 2. Мне все еще нужно смотреть на код для создания помощника, но мне нужно сделать это один раз 3. Это многокод кипы

Итак, моей второй мыслью было генерирование кода на основе конкретного макета / Деятельности / Фрагмента

И я застрял здесь. Я не смог найти никакой библиотеки, которая позволила бы мне это сделать, и я понятия не имею, «как я могу написать сценарий».

Я слишком амбициозен с этой идеей? Есть ли другой способ написания масштабируемых и сложных тестов пользовательского интерфейса?

...