- PVSM.RU - https://www.pvsm.ru -

Kakao — как сделать UI тестирование снова великим

image

В компании «Agoda» мы уделяем много внимания различным видам тестирования нашего кода. Это помогает нам гарантировать его стабильность и находить возможные проблемы продукта на раннем этапе.

В данный момент, тестирование пользовательского интерфейса на Android для нас является небольшим персональным филиалом ада. Google предоставляет нам Espresso вместе с несколькими расширениями, UI автоматор и так далее. И хоть инструменты отлично справляются c возложенной на них задачей, делают они это не очень красиво. Когда вам нужно протестировать кейс, отличающийся от простого клика по кнопке, ваш тестовый код превращается в месиво, сложно поддающееся чтению. Просто взгляните:

@Test
public void espressoTest() {
  onView(allOf(allOf(withId(R.id.label_bf_hotelname), 
        isDescendantOfA(withId(R.id.custom_view_trip_review))), 
        isDescendantOfA(withId(R.id.contentView))))
        .check(matches(withEffectiveVisibility(View.VISIBLE)));
}

Для меня этот код выглядит малочитаемым. Очень сложно поддерживать работу более чем 1000 UI тестов нашего Android приложения с подобным синтаксисом. Но Google объявила официальную поддержду языка Kotlin как языка для Android разработки на конференции Google I/O 2017. Тогда то мы и подумали: «А ведь мы можем попробовать мигрировать наши тесты на Kotlin!»

Но просто трансляция кода из Java в Kotlin не решает нашу проблему с читаемостью тестов, так как мы все еще зависим от Espresso. К счастью, Kotlin предоставляет нам множество инструментов для создания DSL. Имея это ввиду, мы представили как наши UI тесты должны выглядеть на Kotlin'е. Мы хотели, чтобы тест выше выглядел вот так:

@Test
fun espressoTest() {
  screen { hotelName { isVisible() } }
}

Выглядит здорово, вы так не считаете? Гораздо более читаемый и с легкостью понимаемый код, чем при использовании Espresso. И в большинстве ситуаций более компактный. Удалось ли нам добиться такого синтаксиса? Еще как!

image

Встречайте Kakao — простой Kotlin DSL для Android UI тестов с Espresso. Kakao предоставляет удобный синтаксис для создания UI тестов с помощью абстракции ваших Activity/Fragment или View через класс Screen.

open class TestActivityScreen: Screen<TestActivityScreen>() {
    val content: KView = KView { withId(R.id.content) }
    val map: KView = KView { withId(R.id.map) }
    val button: KButton = KButton { withId(R.id.button) }

    val textViewLarge: KTextView = KTextView { 
        withId(R.id.text_view_large) 
    }
    
    val textViewSmall: KTextView = KTextView { 
        withId(R.id.text_view_small) 
    }
}

Чтобы начать использовать Kakao, вы должны включить поддержку Kotlin'а в вашем проекте. Вы можете найти всю необходимую для этого информацию на developer.android.com [1]. Затем вам необходимо объявить вашу иерархию элементов интерфейса, используя классы, которые предоставляет библиотека. Все эти классы (KView, KTextView, KButton) — пустые классы, которые наследуют логику интерфейсов: действий (Actions) и утверждений (Assertions). Также библиотека предоставляет вспомогательные классы для создания matcher'ов в стиле DSL. Один из этих классов называется ViewBuilder и используется в конструкторах всех наследников KView.

class KTextView : KBaseView<KTextView>, TextViewAssertions {
    constructor(function: ViewBuilder.() -> Unit): super(function)
    constructor(parent: Matcher<View>, function: ViewBuilder.() -> Unit): super(parent, function)
    constructor(parent: DataInteraction, function: ViewBuilder.() -> Unit): super(parent, function)
}

После декларации иерархии пользовательского интерфейса, вы можете получить прямой доступ к объекту Screen и всем находящимся в нем объектам KView при помощи оператора invoke и совершать различные действия или утверждения в каскадном стиле:

@RunWith(AndroidJUnit4::class)
class TestActivityTest {
  @Rule
  @JvmField
  val rule = ActivityTestRule(TestActivity::class.java)

  val screen = TestActivityScreen()

  @Test
  fun test() {
    screen {
      content { isVisible() }
            
      textViewLarge {
          click()
          isVisible()
          hasAnyText()
      }

      textViewSmall {
          isVisible()
          hasAnyText()
      }

      map {
          click()
          hasAnyTag("test_tag", "non_test_tag")
      }

      button { hasText("BUTTON") }
    }
  }
}

Мы уже перевели большинство наших тестов на использование Kakao и очень довольны результатом. Библиотека также поддерживает более сложные конструкции, такие как RecyclerView, ListView, WebView и так далее. Также она обладает удобным подходом к кастомизации, позволяя легко создавать собственные имплементации KView с различным набором действий и утверждений, вложенными элементами и логикой.

Мы решили выпустить этот инструмент публично, чтобы другие разработчики могли начать писать UI тесты на Kotlin'е без нужды придерживаться синтаксиса Espresso, который на наш взгляд устарел.

Вы можете подключить Kakao в свой проект, просто добавив эту строчку в Ваш build.gradle:

androidTestCompile 'com.agoda.kakao:kakao:1.0.0'

Присоединяйтесь к нам на GitHub [2], оцените Kakao и давайте вместе сделаем UI тестирование снова великим! Счастливого тестирования!

Автор: Alviere

Источник [3]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/android/265222

Ссылки в тексте:

[1] developer.android.com: https://developer.android.com/kotlin/get-started.html?gclid=Cj0KCQjw9afOBRDWARIsAJW4nvzd9KDNKB8LF3wc2Qp5g6nAfy3qbZjedQaAt_mGge5avDeHcVpZ6GIaAi-KEALw_wcB

[2] GitHub: https://www.github.com/agoda-com/Kakao

[3] Источник: https://habrahabr.ru/post/339664/