Меняем работу с RecyclerView в Espresso-тестах
Продолжаем нашу серию расшифровок выступлений спикеров на VK Tech Talks | QA, состоявшемся 9 сентября 2019 года. Сегодня мы рассмотрим доклад Алексея Тюрина, занимающегося автоматизацией тестирования, на тему «Меняем работу с RecyclerView в Espresso-тестах».
О чем пойдет речь в докладе:
- UI-тест на Espresso и как его улучшить.
- Проблема RecyclerView.
- Что получаем в итоге?
Вводная часть для тех, кто не писал на Espresso. Разберём простой пример.
Скелет типичного теста на Espresso:


Но это была разминка. Реальный тест на Espresso выглядит примерно вот так:
В целом, какие проблемы у такого теста?
- Тяжело читаемый тест.
- Изменение локаторов элементов.
- Изменение пользовательского сценария.
Что мы сделали?
Первоначально мы хотели улучшить синтаксис Espresso. В Kotlin есть extension-функции.



Да, тесты стало приятнее читать, но глобально проблема не решена.
Мы пошли дальше. Что же такое Matcher<View>? — это описание элемента на экране, что идеально ложится в паттерн PageObject.
Проблема в том, что мы до сих пор не решили нашу третью проблему.
Далее мы применили ещё один паттерн — Steps. Все логические действия пользователя заворачиваем в отдельные функции.
Мы молодцы, всё работает, решили проблемы.
Далее мы смотрим на RecyclerView. Это не укладывается в нашу концепцию. Далее разберёмся почему.
Рассмотрим понятия, которые будут использоваться далее:





Скелет RecycleView:
Нам всё же хочется сократить синтаксис.
Далее мы заглянем «под капот» Espresso. Сфокусируйтесь, это будет тяжелая часть.
Разберёмся по-порядку, что принимает метод actionOnItem.







Проваливаемся чуть глубже.
Подведём промежуточный итог. Так как это работает?
- Поиск позиции совпадающих элементов внутри RecyclerView.
- Получение view, который находится по найденной позиции.
- Выполнение переданного действия на найденный view.
Давайте попробуем изменить эту логику. Мы создали новый класс RecyclerViewMatсher.



Посмотрим, как это реализуется внутри. Espresso мониторит динамические иерархии элементов в Android. Когда вы вызываете проверку или поиск элемента, метод matchesSafely работает над каждым элементов в иерархии.
Что мы только что реализовали? Теперь мы спокойно можем вызывать такие действия и они будут работать. Просто так работать с этим неудобно, но мы можем добавить на наши страницы вот такие методы getListItem и getListItemChild.
Так дело не пойдёт. Идём дальше.


Давайте подумаем, что же мы можем с этим сделать. Создаём новый класс RecyclerViewItem для работы с отдельным Item в RecyclerView.
Init вызывается, когда вы создаёте инстанцию какого-либо класса.
С этим понятно. Как же теперь пользоваться этим?




Идём дальше. У нас есть метод friendItemCheck и advancedSendMessageWithSteps.
Чего мы добились за всё это время?
У нас имеется библиотека с открытым кодом, которую вы можете легко подключить:
Схема подключения:
И ещё полезные ссылки:
1) Библиотека c Espresso DSL и RecyclerViewItem: github.com/alex-tiurin/espresso-page-object
2) Примеры кода: github.com/alex-tiurin/espresso-guide
На этом доклад Алексея подходит к концу. Полную версию его выступления можно посмотреть ниже:
The Brown Room — независимое интернет-издание про социальные сети и современные технологии.
Автор: Сергей Котов
Корректор: Арсений Метелев
Изображения, код и слайды: Алексей Тюрин / VK Tech
