[Тестирование IT-систем, Разработка под Android] Тестирование From Zero to Hero. Часть 1

Автор Сообщение
news_bot ®

Стаж: 6 лет 9 месяцев
Сообщений: 27286

Создавать темы news_bot ® написал(а)
28-Янв-2021 16:31


Всем привет! Меня зовут Сергей, я работаю в команде Тинькофф. Сегодня я хочу рассказать, как мы в Тинькофф приходили к классической пирамиде тестирования. 
Рассказ будет в трех частях:
  • Трудности, с которыми нам пришлось столкнуться, и как мы их преодолевали.
  • Конкретные решения по некоторым распространенным кейсам при написании интеграционных тестов.
  • Подход к написанию E2E-тестов (тестов, покрывающих взаимодействие всех систем приложения, включая back-end и пользовательский интерфейс) с использованием паттерна PageObject, пришедшего к нам из мира веб-разработки.
Вместо предисловияБыло время, когда солнце светило ярче, орки были зеленее, а мобильный банк Тинькофф писали восемь человек. Тогда почти все фичи катились без какого-либо тестового покрытия. В лучшем случае основные компоненты бизнес-логики могли быть покрыты Unit-тестами.Те времена давно прошли, Тинькофф уже далеко не маленький стартап, и количество разработчиков на одной платформе перевалило за полсотни. Количество кода, который вливается ежедневно, — огромно. И сейчас уже не стоит вопрос о необходимости полноценного покрытия тестами.Этап принятия
Ранее E2E-тесты писали только автоматизаторы, которых было несколько человек. Тестами покрывалась только малая часть основного функционала. Регресс-тестирование начало затягиваться, и выкатывать фичи в прод стало труднее с учетом роста команды. Первый шаг, который мы сделали, — передали написание E2E-тестов разработчикам, причем на обязательной основе. Ни одна фича не может перейти в статус Ready если она не покрыта E2E-тестами. Поскольку критерии приемки задачи описывают QA-специалисты, то они и писали тест-кейсы для каждой фичи.Тест-кейсыТест-кейсы — это шаги, по которым QA-специалист проходит во время тестирования фичи. Сюда входят всевозможные проверки пользовательского флоу, реакция приложения на разного рода corner-case-проверки наличия UI-элементов на экране и так далее.
Пример тест кейсаТут мы столкнулись с несколькими проблемами:
  • Мы стали писать тест-кейсы на каждый чих. То есть у нас были проверки в E2E-тесте для проверки того, что при нажатом чек-боксе отображается некоторый текст, а в выключенном состоянии текст — другой. QA хотели проверить все кейсы и максимально обезопасить себя на стадии приемки, поэтому E2E-тесты начали походить на Unit-тесты с той лишь разницей, что на прогон таких тестов тратилось значительно больше времени и ресурсов.
  • Появилось большое количество тестов с повторяющимся флоу. Например, есть фича, в которой пользователь может заказывать справки. Пользователь попадал на экран «Списка справок», выбирал справку, после чего открывался экран «Настроек справки» (выбор языка, даты и так далее). После мы попадали на экран «Превью», где мы могли посмотреть PDF-файл нашей справки. Мы имели три кейса, каждый из которых проверял отдельно каждый экран и не проверял пользовательский флоу. 
  • В E2E-тестах мы проверяли кейсы, которые в принципе не должны проверяться на этом уровне пирамиды. Например, факт отправки запроса и его составляющих или роутинг между экранами, который, по сути, спрятан в одной сущности.
По итогу мы получали пирамиду тестирования в виде песочных часов. Мы делали много Unit- и E2E-тестов и практически не писали интеграционных тестов. 
Почему это не круто?Unit-тесты — быстрые и дешевые. Их достаточно легко писать и поддерживать. Но они проверяют работоспособность элементов в изоляции от других сущностей. У нас есть шанс построить приложение, в котором все элементы работают корректно, но не могут взаимодействовать друг с другом, и тесты нам об этом не скажут.Е2Е-тесты хорошо проверяют интеграцию между всеми компонентами приложения, но обходятся они достаточно дорого по следующим причинам: 
  • Тесты запускаются на эмуляторах. Сам тест проходит долго, потому как он имитирует реальные действия пользователя (одна только авторизация длится около 30 секунд на каждом запуске теста).
  • Прогон Е2Е-тестов занимает много времени. Чтобы запускать такие тесты на пул-реквестах, нужно иметь достаточно мощностей. На данном этапе мы не можем этого делать. Это значит, что обратную связь о том, что что-то сломалось, мы получаем значительно позже. Но для нас это одна из приоритетных целей в области тестирования!
  • Из-за того, что прогоны тестов проводятся на CI, иногда достаточно трудно понять, по какой именно причине сломался тест.
  • Е2Е-тесты имеют свойство падать без каких-либо изменений в коде (нестабильность интернета, нестабильность тестового фреймворка, проблемы на реальном устройстве и другие причины), именно поэтому их еще называют flaky tests.
По итогу мы пришли к выводу, что нам не хватает более дешевой и быстрой проверки интеграции компонентов приложения. Того самого среднего уровня пирамиды — интеграционных тестов, которые можно было бы запускать на пул-реквестах и не ждать длительных прогонов. Почему так?Казалось бы, все эти разговоры о пирамидах тестирования давно затерты и пройдены много лет назад. Так почему разработчики по-прежнему делают одно и то же?Для E2E-тестов понятно, что на тестовом окружении должно быть поднято все, а для интеграционного — только часть и не всегда понятно какая. Это приводило к тому, что всем было проще не разбираться и писать E2E тесты. Это негативно сказывалось на времени прогона тестов в целом.Еще одной причиной была архитектура приложения. Она была не готова для комфортного написания интеграционных тестов. Поэтому, когда вставал вопрос — написать ли интеграционный тест на проверку корректности отправленного запроса в сеть с помощью E2E-теста или же написать тест, который это проверит на JVM, — выбор почти всегда был в пользу E2E. Что мы сделалиКомандный тренинг
Первое, что мы сделали, — командный курс. Выделили несколько команд-добровольцев, которые готовы были первыми попробовать на себе новые подходы к написанию тестов. Внутри компании провели несколько лекций и воркшопов, где разработчики вместе с QA могли разобрать какие-то тестовые кейсы, обсудить, какие кейсы и как лучше покрывать. Так мы смогли больше понять проблемы друг друга и настроиться на одну волну. Мы пришли к пониманию, какие кейсы покрывать стоит, а какие нет. Мы поняли, в каком направлении нам двигаться в написании тестов, чтобы это не превращалось в кошмар для обеих сторон. Пользовательские историиУ нас было много обсуждений с QA, пока мы не пришли к формату тест-кейса, который должен показывать какую-то пользовательскуюисторию. Небольшой примерУ нас есть фича, в которой пользователь заказывает себе справку по счету. Здесь имеется три экрана:
  • Экран списка справок.
  • Экран настроек справки (язык, период и так далее).
  • Экран превью справки.
Как бы это выглядело раньше?Мы бы проверили Экран списка справок: UI-элементы, отправляемые запросы. После чего аналогичные проверки были бы на другие два экрана. Здесь было две проблемы:
  • Можно было покрыть тестами все, и при этом не было гарантии, что пользователь получит ожидаемый результат.
  • Было много запусков тестов на реальном устройстве, которые во многом дублировали себя.
Как это сделано сейчас?Тест-кейс != Е2Е-тест. Есть тест-кейсы, в которых описана пользовательская история. К примеру, есть фича, в которой пользователь может заказать справку. Мы проверяем в тесте, что с точки входа внутрь фичи до конечного результата пользователь не встречает никаких проблем.Сам тест разделяется на шаги (steps). Обычно шаг — это один экран внутри всего флоу (но бывают и другие ситуации). Мы пишем в description название этого шага, делаем скриншот и все проверки, которые касаются этого шага. По итогу если у нас что-то ломается — мы видим, на каком шаге был сломан тест, и понимаем, где находится проблема. Мы минимизируем количество запусков приложения на устройстве. Мы видим, что весь пользовательский флоу прошел успешно, а не только его отдельные компоненты. И есть кейсы, в которых проверяется какое-то конкретное действие, например отправка запроса при нажатии на кнопку. Для таких тестов достаточно написать Unit-тест либо интеграционный тест. Такие ошибки мы можем отлавливать на стадии пул-реквестов и исправлять их до того, как они попадут к QA.ПирамидаАрхитектура приложения не была готова к тому, чтобы мы могли полноценно писать интеграционные тесты. Используемые подходы были хороши для команды из восьми человек, но стали сильно стрелять в ногу, когда количество людей в команде перевалило за полсотни. При попытке написать какой-либо тест мы постоянно упирались в то, что где-то не хватает какой-то зависимости, а эта зависимость тянет еще несколько. Очень трудно было что-то замокировать: приходилось либо мокировать весь DI-модуль, либо пытаться мокировать большие и сложные запросы. Все это вызывало боль и полное нежелание писать такие тесты.Мы с ребятами начали разбивать монолитные компоненты на фича-модули. Наша задача — вынести компоненты приложения, которыми пользовались все фича-команды (сетевые слои, работа с базами данных, аналитика и другие). После чего внутри фича-команд создали задачи на рефакторинг своих фича-модулей и бизнес-сущностей, многие из которых рефакторятся в процессе написания тестов. Также мы смогли показать остальным разработчикам примеры, как стоит писать такие тесты. Было подготовлено базовое окружение для написания интеграционных тестов: 
  • Выделили отдельные Аndroid-модули для тестовых компонентов.
  • Подготовили базовые моки (сущности хранения сессий, базы данных и так далее).
  • Написали документацию по основным принципам тестирования с примерами.
ИтогиМы пришли к осмысленной, правильной пирамиде тестирования.
  • Начали более сбалансированно распределять тесты по слоям.
  • Задали направление для всей команды, написали несколько тестов, которые можно брать за пример и не бояться потратить три дня на написание одного теста (да, поначалу было и такое).
  • Смогли задать направление для архитектурных изменений и упростить написание окружения вокруг тестов. 
Во второй части я постараюсь описать конкретные тест-кейсы и сложности, с которыми нам пришлось столкнуться при написании интеграционных тестов, а также разберу решения, которые были приняты в нашей команде.
===========
Источник:
habr.com
===========

Похожие новости: Теги для поиска: #_testirovanie_itsistem (Тестирование IT-систем), #_razrabotka_pod_android (Разработка под Android), #_android, #_automation, #_kotlin, #_testing, #_tinkoff, #_blog_kompanii_tinkoff (
Блог компании Tinkoff
)
, #_testirovanie_itsistem (
Тестирование IT-систем
)
, #_razrabotka_pod_android (
Разработка под Android
)
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 22-Ноя 20:41
Часовой пояс: UTC + 5