Я пишу тесты пользовательского интерфейса с эспрессо. На самом деле это выглядит так:
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. Это многокод кипы
Итак, моей второй мыслью было генерирование кода на основе конкретного макета / Деятельности / Фрагмента
И я застрял здесь. Я не смог найти никакой библиотеки, которая позволила бы мне это сделать, и я понятия не имею, «как я могу написать сценарий».
Я слишком амбициозен с этой идеей? Есть ли другой способ написания масштабируемых и сложных тестов пользовательского интерфейса?