Open source: CI/CD и тестовая инфраструктура Авито для Android

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!

Мы вынесли в open source инфраструктуру Авито для Android: Gradle плагины, эмуляторы и библиотеки для тестов. Наш код будет полезен при автоматизации CI/CD, а также облегчит написание и поддержку автотестов.

В этой обзорной статье мы расскажем, почему решили сделать свою работу открытой, о наиболее значимых библиотеках проекта и сориентируем, куда идти с возникающими вопросами. Детально разберём отдельные библиотеки, Gradle-плагины и наши подходы к разработке в следующих материалах.



Кто мы такие и чем занимаемся


Мы работаем на Android-направлении в платформенной команде Speed. Нас четыре человека:
Серёжа Боиштян
Senior engineer
Твиттер-аккаунт


Дима Воронин
Lead engineer
Твиттер-аккаунт


Женя Кривобоков
Senior engineer
Твиттер-аккаунт


Даниил Попов
Senior engineer
Твиттер-аккаунт


Мы отвечаем за то, чтобы быстрее доставлять изменения во всех Android-приложениях Авито до пользователей. В нашу зону ответственности входят:

  • Локальная работа с проектом: чтобы всё быстро собиралось и IDE не тормозила.
  • CI pipeline: тесты, все возможные проверки.
  • CD: инструменты для релиз-инженеров.

Зачем нам нужен open source


Мы хотели не просто отзеркалить код в открытом репозитории на Гитхабе, а сделать это с пользой для себя и инженерного сообщества. Основных причин вынести проект в open source — пять:

  • Получить обратную связь.
  • Влиять на стандарты в индустрии.
  • Научиться новому.
  • Влиять на сторонние библиотеки.
  • Прокачать личный бренд.

Давайте коротко по ним пройдёмся.

Получить обратную связь и сделать код проще для повторного использования


Мы делаем тулинг для инженеров Авито, и нашим пользователям нужно, чтобы все решения просто работали. Нам не хватает взгляда со стороны от разработчиков, которые решают похожие задачи. Будет круто, если нам укажут на проблемы во внутренней реализации и удобстве подключения к нашему проекту.

Мы уже увидели, как перенос кода в Гитхаб подсветил проблемы переиспользования. Когда понимаешь, что этим могут пользоваться другие компании, то по-другому смотришь на архитектуру. Переиспользование кода — не самоцель. Но этот внешний критерий многое говорит о качестве архитектуры и её гибкости.

Влиять на стандарты в индустрии


Мы развиваем инфраструктуру для мобильных приложений c 2017 года и регулярно рассказываем об этом на конференциях и митапах:

  • Алексей Шпирко «Релизы мобильных приложений в Авито» — Mobius 2018 Piter.
  • Дмитрий Меркурьев «Impact Analysis» — AppsConf: QualityApps 2018.
  • Николай Нестеров «Эволюция CI в команде мобильной разработки» — Saint AppsConf 2018.
  • Алексей Шпирко «Автотесты в Авито. Зачем они, как помогают, сколько стоят» — Apps Conf Moscow 2019.
  • Евгений Кривобоков «Ускорение сборки многомодульного Android-приложения» — Apps Conf Moscow 2019.

Помимо рассказов, мы всегда хотели поделиться кодом и дать возможность его переиспользовать. Ведь многие Android-разработчики сталкиваются с похожими вызовами:

  • Как писать автотесты, чтобы они приносили пользу.
  • Как запускать их в pull request’ах.
  • Как дешевле поддерживать инфраструктуру.

Для этих задач нет общепринятых и устоявшихся решений — каждая компания действует по-своему. Мы делимся своими наработками, чтобы в новых проектах разработчикам не приходилось собирать по крупицам информацию о тестировании мобильных приложений и построении CI/CD. Хочется, чтобы вместо написания своего велосипеда можно было взять готовые решения для рутинных проблем. И, даже если кодом проекта в исходном виде никто не воспользуется, разработчики смогут подсмотреть наши подходы и улучшить собственные библиотеки.

Научиться, объясняя другим


Просто вынести код в open source — недостаточно. Важны практики, подходы, пути поиска проблем и принятия решений. Показывая их, мы проверяем, насколько наши идеи и готовые предложения работают вне Авито.

Влиять на сторонние библиотеки и быстрее исправлять их проблемы


Представьте, что вы столкнулись с проблемой в Android или библиотеке и не можете найти обходной путь. Вам нужна помощь сообщества или авторов кода. Вы задали вопрос на Stack Overflow, создали баг в Google IssueTracker, всё подробно описали, но проблема не воспроизводится. У вас просят тестовый пример. На всё это уходит дополнительное время.

Open source помогает быстрее создать воспроизводимый пример. У нас есть тестовое приложение, в котором используется часть инфраструктуры. Главная его задача — dogfooding, то есть как можно раньше проверить на простом и изолированном примере, что всё работает. Но это же приложение позволяет проще показывать баги. Когда мы даём воспроизводимый пример в чужой библиотеке, её автору проще понять, в чём дело. Это повышает шансы, что он возьмётся за доработки.

Популярность open source проекта тоже повышает вероятность, что на вас обратят внимание. Указание на проблему в библиотеке с кучей звёздочек и пользователей повышает давление, её сложнее игнорировать. Получить такой результат без open source сложнее — твоё приложение должно быть суперпопулярным или тебя должны знать лично.

Пиар и личная мотивация


Последняя, но не по значимости, причина — это личная выгода. От публичности ежедневной работы выигрывают все. Компания привлекает внимание за счёт полезного продукта, а мы прокачиваем личный бренд как инженеры и получаем дополнительную мотивацию для работы. Больше не нужно выискивать по вечерам время на собственные проекты или коммиты в сторонние open source библиотеки.

Что вынесли в open source


Мы вынесли в репозиторий на Гитхабе почти всю нашу инфраструктуру тестирования Android и CI/CD. Чтобы другим разработчикам проще было сориентироваться в проекте, все модули сгруппированы по назначению:

  • Gradle плагины.
  • Библиотеки для Android тестов.
  • Emulators.



Отмечу парочку наиболее значимых библиотек.

Test runner


Это gradle плагин для запуска instrumentation тестов. Ближайший аналог — Marathon, но наш написан только под Android.

Test runner:

  • Описывает, какие тесты запускать. Есть фильтрация по аннотациям, по пакетам, по результатам прошлого запуска.
  • Описывает, на каких эмуляторах прогонять тесты. Резервирует их в Kubernetes или подключается к локальным эмуляторам.
  • Задаёт условия перезапуска тестов.
  • Отправляет итоговый отчет с результатами прогона тестов.

Результаты хранятся в кастомной TMS (test management system), её нет в open source. Мы работаем над тем, чтобы можно было подключить другую реализацию.



Impact analysis


У нас около 1600 instrumentation тестов и 10K unit-тестов. Мы хотели бы запускать все тесты на любое изменение кода, но это невозможно — прогон займёт слишком много времени.

Простое решение — вручную разделить тесты на разные наборы, например, smoke-тесты, быстрые, медленные, и запускать только часть. Но при таком подходе всегда есть шанс пропустить ошибку, потому что непонятно, какой набор тестов оптимальнее. Идеальное решение — понять, какой минимальный набор тестов проверит все изменения. Это называется test impact analysis.

Мы написали Gradle plugin, который ищет изменения в модулях, парсит тесты и определяет, какие из них запустить.



Более подробно основные модули и подходы описаны в документации проекта.
Сейчас она не очень хороша, да ещё и не вся переведена. Мы хотим сделать документацию понятнее, и нам нужна ваша помощь. Расскажите, что доработать и поправить в тексте в нашем телеграм-чате.



Чем могут быть полезны наши библиотеки


Поскольку в проекте много составляющих, его использование зависит от ваших потребностей. Если вы решаете похожую задачу или просто хотите разобраться в технологии — смело пишите нам в телеграм-чат на русском или на английском. Расскажем, что знаем, постараемся помочь и показать релевантные примеры.

Можно спрашивать что угодно:

  • А как вы работаете с нестабильными тестами?
  • Зачем так много кода? Он же бесполезный.
  • Почему весь код в Gradle плагинах, а не в Python скриптах?

Если вы хотите использовать какой-то конкретный модуль, то можно попробовать его в тестовом приложении. Сейчас в нём показан пример использования test runner.

К сожалению, у нас пока мало примеров переиспользования в других проектах, поэтому при интеграции могут проявиться ещё неизвестные ограничения. Напишите нам, если такое произойдет, и мы посмотрим, что нужно доработать.

Заключение


В следующих статьях мы планируем рассказать про:

  • Наш test runner.
  • Анатомию теста — что происходит от нажатия кнопки “Run” в IDE до получения результата.
  • Как мы боремся c нестабильностью тестов и инфраструктуры.
  • Наши подходы к написанию инфраструктуры.
  • Как мы сократили время релизов с месяца до недели.

Есть идеи и по более общим темам:

  • Как начать писать тесты.
  • Основы тестирования для новичков — про общие подходы и технологии.

Расскажите в комментариях, о чём вам будет интереснее узнать. Так мы поймём, какой текст писать в первую очередь.
Источник: https://habr.com/ru/company/avito/blog/496036/


Интересные статьи

Интересные статьи

Мы уже публиковали свои внутренние документы с ожиданиями от инженеров и менеджеров продукта в плейбуке на Гитхабе. Пришло время поделиться ещё одним &m...
Четвертая версия OpenShift вышла сравнительно недавно. Актуальная на текущий момент версия 4.3 доступна с конца января и все изменения в ней — это или нечто совершенно новое, чего в третьей вер...
В мире информационной безопасности часто задаются вопросом об исследовании открытых источников на получение личной информации — будь то защищающая сторона (например, для контроля периметра, выя...
Большой зоопарк опенсорсных лицензий неизбежно приводит к тому, что приходится нередко задаваться вопросами касательно их совместимости, тех или иных применимых лицензионных условий в зависимости...
Некоторое время назад мне довелось пройти больше десятка собеседований на позицию php-программиста (битрикс). К удивлению, требования в различных организациях отличаются совсем незначительно и...