UI-tests in Android. Часть 3. Более сложные примеры.

В предыдущей статье мы посмотрели на более менее простые примеры юай тестов. Теперь же мы пойдем дальше по проекту и посмотрим на примеры более сложных юайтестов.

Ранее мы тестировали функционал добавления элементов, теперь же перейдем к следующему экрану — списку категорий и списку самих элементов. Здесь у нас есть такой функционал как swipe to remove — смахнуть чтобы удалить. И он касается как отдельного элемента так и целой категории. Я не хотел делать как сейчас принято — после свайпа (зачсатую случайного) отображать снекбар для отмены. Ведь зачем отменять действие, когда лучше подтвердить его?

Так же на экране списка у нас есть фунцкионал мануальной сортировки элементов. Т.е. можно нажать на элемент, держать его и перетащить вверх или вниз по списку. Увы я не нашел пока что способ для тестирования этого с помощью Espresso (если вы знаете как это сделать, напишите мне в телеграм @JohnnySC). В предыдущей статье я обещал рассказать о том, какие юайтесты неавтоматизируемы. Так вот — этот не то, чтобы не автоматизируем, я просто не нашел решения. А вот действительно неавтоматизируемый юай тест — это когда нужно мануально что-то сделать. Например на главном экране есть кнопка синхронизации — когда ты сохраняешь всю базу данных в файл. Написать юай тест можно например на такой кейс — создать элемент, сохранить базу в файл, удалить элемент из приложения и потом восстановить базу данных на экране синхронизации, после чего проверить, что элемент вернулся на место, хотя здесь нам понадобится рестартнуть приложение, т.е. закрыть его полностью и открыть заново. Вероятно это возможно, нужно посмореть на возможности UI-Automator. Но что на мой взгляд неавтоматизируемо, так это такой кейс — сохранить базу в файл, после чего удалить файлик из хранилища и попытаться восстановить. Мы все понимаем, что на разных устройствах стоит разный софт для доступа к дереву файлов, так что написать какой-то единый юай тест для этого будет затруднительно. Опять же, нужно смотреть на возможности UI-Automator.

Ладно, вернемся к юай тестам наших списков. Для этого посмотрим на пакет — ссылка. Так как у нас есть RecyclerView, а каждый элемент этого списка является иерархией вьюх, то нам нужен матчер, которого не существует в библиотеке Espresso. Например для того, чтобы на элементе списка нажать конкретно на нужную кнопку или проверить нужный текст. Для этого я написал такой вот матчер — ссылка. Суть в том, что мы можем добраться до нужной вью тем же способом что и делаем это в котлин коде. Т.е. берем и находим вью по айди, обратите внимание на второй класс — ListItemRecyclerViewMatcher. Мы передаем список иерархии нужных айди и добираемся до нужной вью на конкретной позиции. Теоретически вы можете написать свой матчер для любого случая, если его не существует в библиотеке. Точно так же вы можете написать свой кастомный ViewInteraction/ViewAction для взаимодействия с вью, но это уже сложнее.

Итак, вот так выглядят наши экраны списков. На карточке категории есть кнопка чтобы перейти к изучению. А на карточке элемента есть кнопки детальной инфорамации (отображение перевода) и кнопка редактирования.

Список категорий
Список элементов внутри категории

Итак, в пакете списка у нас есть следующие юай тесты (коротко пробежимся по каждому):

CategoryDetailsListTest — здесь мы создаем 3 категории, по 1, 2 и 3 элемента для каждого и просто проверяем контент, т.е. проверяем что в списках наши элементы отображаются верно.

CategoryListSwipeToRemoveTest — здесь мы удаляем полностью категорию с помощью свайпа и внутри 2 теста, первый простой, второй сложный. И если суть первого просто удалить и проверить что элемент после удаления не существует на экране, то суть второго проверить, что мы действительно удалили не только категорию, но и внутренний элемент. Ведь если мы попробуем после удаления добавить этот элемент снова, то в случае если он не удалился (элемент), то будет диалог о том, что такой элемент уже существует. Немного подробностей — мы используем библиотеку Realm для хранения базы данных и неопытный человек мог бы например при удалении категории забыть удалить вложеные элементы, не зная, что это необходимо делать самостоятельно (да да да, в реалме до сих пор нет автоматического удаления вложенных элементов).

LearningPairListSwipeToRemoveTest — здесь мы точно так же проверяем, что элемент действительно удалился, ведь если бы мы просто проверяли юай (это же юай тест, надо проверяеть юай — ничего подобного, нужно проверять функционал!), то нам бы хватило одного раза. А так мы удалим элемент, после этого попробуем его добавить еще раз, если не будет диалога о том, что такой элемент существует, значит наше удаление прошло действительно удачно.

EditLearningPairTest — также со списка элементов мы можем перейти на экран редактирования. Значит нужно проверить, что после редактирования элемента его перевод поменялся.

Более менее сложными юай тестами я называю такие, где для его проверки затрагиваются несколько экранов. На моем ноутбуке тест для проверки функционала редактирования занял чуть больше чем 7 секунд. 2 теста для проверки функционала удаления категорий — 14 секунд. 18 секунд ушло на проверку удаления элемента. Как видите, все эти тесты довольно-таки короткие и они стоят того, чтобы их написать. Ведь вы один раз написали эти тесты и можете каждый раз проверять ваш функционал.

Теперь перейдем к самому важному функционалу — кроме того, что мы создаем какие-то вещи и удаляем, их первоочередной целью было изучение. Для этого заглянем в пакет study.

Экран для изучения выглядит примерно так.

Экран изучения

Как видим здесь есть статистика по конкретному элементу — количество правильных ответов и количество ошибок. Также в тулбаре у нас имя категории, которую изучаем. Есть кнопка пропуска, если например вы не помните перевод элемента, тогда в статистику добавляется 1 ошибка и переходит вперед. Если нет элементов или же вы закончили изучение, на экране будет диалог с результатами. После этого вся статистика для категории обновится. Т.е. для категории количество правильных и неправильных ответов это сумма по каждому элементу внутри. И конечно же нам нужно понимание на каком мы элементе находимся и сколько еще осталось. Как видите, здесь действительно много функционала, который нужно протестировать. И да, если вы случайно нажали назад, то вам нужно будет подтвердить действие. Итак, рассмотрим все тесты в пакете.

StudyCancelTest — мы открываем экран изучения и просто уходим назад. Значит нам нужно проверить, что статистика ни элемента ни категории не изменилась.

StudyCorrectTest — простой тест на проверку функционала правильного ответа. После того, как мы дали правильный ответ, мы должны увидеть сообщение что был дан верный ответ, после чего увидим диалог с результатом.

StudyIncorrectTest — то же самое, только теперь мы введем неправильный ответ и проверим что видели сообщение об ошибке, после чего покинем экран изучения и проверим, что теперь в статистике элемента 1 ошибка как и в статистике категории.

StudySkipTest — простой тест на проверку функционала пропуска. Значит нам нужно проверить, что видели сообщение, которое содержит верный ответ и диалог с результатом. После проверить статистику элемента и категории.

Теперь, когда мы проверили каждый функционал экрана по отдельности мы должны написать действительно сложный юай тест, который бы имитировал некий настоящий опыт пользователя. Ведь никто не будет создавать 1 элемент и заучивать его. Нам нужен тест, где мы создадим несколько категорий, в каждой несколько элементов. И будем изучать элементы по разному.

StudyComplexTest — там есть джавадок(котлиндок?), можно прочитать и понять что там происходит. У нас 3 категории по 3 элемента. Мы проходим первый правильно весь, после чего второй полностью с ошибками и третий комбинируем верные и неверные ответы. После чего проходим по каждой категории еще раз но уже с другими ответами/действиями. И в конце проверяем статистику после смерти процесса. Весьма логично, что в классе юай теста так много строк — 469. Посмотрите сами — ссылка.

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

Запись юай теста StudyComplexTest на эмулаторе

Итак, давайте подытожим. Все юай тесты, которые я написал — заняли не так много времени, они проверяют функционал моего приложения и сами занимают менее 10 минут в целом на прохождение. Теперь самый важный момент — я написал код приложения не сильно придерживаясь принципов CLEAN Architecture, плюс я использовал библиотеку Realm для хранения данных. И знаете что? Я могу со спокойной душой рефакторить свой проект, ведь у меня весь важный функционал покрыт юай тестами и я могу легко и просто понять, не задел ли я функциональность приложения своим рефакторингом.

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

И да, есть еще такой функционал как чатбот, я просто пока что не написал юай тесты на него.

Чат бот

Здесь можно просмотреть все категории, посмотреть каждую, также детально (т.е. вместе с переводами каждого элемента). Можно отсюда перейти прямо на экран деталей категории, а можно начать изучение прямо здесь. Для этого можете посмотреть список команд чатбота здесь. Сам класс вьюмодели я написал быстренько, поэтому там очень много кода. Но я так же могу написать спокойно десяток другой юай тестов, котроый покроет весь функционал чат бота и спокойно порефакторить.

п.с. это был мой первый опыт написания чатбота, так что не судите строго код.

Запись опубликована в рубрике Программирование Java. Добавьте в закладки постоянную ссылку.