Your browser is not supported anymore. Please update to a more recent one.


Download Chrome

Download Firefox

Download
Internet Explorer

Download Safari

Процесс разработки и выкатка релизов в Badoo. Автоматическое тестирование. Девелоперское окружение


В июле мы вместе с ведущими IT-Kompot и релиз-инженерами Badoo Владиславом Черновым и Олегом Оямяэ записали выпуск подкаста «Процесс разработки и выкатка релизов в Badoo. Автоматическое тестирование. Девелоперское окружение».
Так как прошлый подкаст вызвал интерес у слушателей и читателей, то этот подкаст мы тоже превратили в статью.

О чем говорили:
Процесс разработки и выкатки релизов в компании Badoo. Используемые инструменты.
  • GIT Workflow. Каждая задача в отдельной ветке;
  • Использование JIRA, TeamCity и AIDA;
  • Формирование релиза и выкатка двух релизов в день. Проблемы и их решения (откат, патчи и т.д.).
Автоматическое тестирование. Рецепт быстрого прогона большого количества тестов.
  • Что мы используем;
  • Как гоняем тесты;
  • Code Coverage;
  • Пускалка. 18000 тестов за 3,5 минуты.
Девелоперское окружение в команде, разрабатывающей сложную распределенную систему
И рекомендации от ребят: полезные книги, статьи и т.д.


Антон Сергеев: Всем привет, вы слушаете 48 выпуск подкаста «IT-компот», и с вами его ведущие Антон Копылов.

Антон Копылов: И Антон Сергеев, привет.

Антон Сергеев: Сегодня у нас в гостях бравые ребята ― релиз-инженеры компании Badoo Олег Оямяэ и Владислав Чернов. Ребята, привет!

Владислав Чернов: Привет.

Олег Оямяэ: Привет.

Антон Сергеев: У нас получается цикл подкастов с компанией Badoo. Сегодня мы решили более подробно поговорить про область, которая является если не гордостью компании Badoo, то уж точно очень важным достижением и явным успехом. Это то, что компания делает успешно выкатку новых релизов, используя при этом полностью автоматизированные средства. Плюс в компании очень интересно сделан и настроен процесс тестирования. Он позволяет эффективно проводить большое количество тестов. Все, кто слушал прошлый выпуск подкаста, уже знают про 2 релиза в день ― про это говорил Алексей Рыбак.
Ну что, давайте начнём. Влад и Олег, я вам предлагаю рассказать коротко о себе и о том, чем вы занимаетесь в Badoo.


Владислав Чернов: Здравствуйте ещё раз. Мы с Олегом занимаемся в Badoo конфигурационным управлением и релиз-инжинирингом. Если говорить про себя, то я почти всю свою трудовую карьеру занимаюсь именно релиз-инжинирингом: начинал как обычный релиз-инженер, делал очень много руками, мы выкатывали простые релизы, а потом я ушёл в автоматизацию и всё больше и больше автоматизировал, накручивая этот процесс. Сейчас занимаюсь автоматизацией всего бизнес-процесса разработки и тестирования в Badoo.

Антон Сергеев: Понятно, круто. А Олег ― твой коллега и тебе в этом помогает, правильно?

Олег Оямяэ: На самом деле у меня немного другая история. Я был разработчиком и тимлидом в других компаниях, а в Badoo решил попробовать себя в новой для меня сфере ― в релиз-инжиниринге. Но я занимаюсь больше программированием, а не автоматизацией. Давайте я расскажу немного о том, как всё было устроено в Badoo с начала и до наших дней.

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

Олег Оямяэ: Довольно длительное время в Badoo в качестве системы контроля версий использовался SVN. То есть большую часть существования Badoo использовался SVN, и он даже до сих пор в некоторых частях используется. (Примечание: в далеких-далеких годах, конечно, был CVS).

Антон Сергеев: Сейчас некоторые слушатели, наверное, начинают «писать кипятком»: как же так, subversion! Но, насколько я знаю, SVN, он больше свойственен проектам типа enterprise всякого. У вас был с ним большой опыт работы ещё начиная с Mamba, то есть это исторически так сложилось, правильно?

Олег Оямяэ: Переход на Git начался года два с половиной назад: в это время как раз пошёл какой-то бум и все начали переходить на него. Но в Badoo это был запланированный процесс, как часть внедрения тестирования в компании.

Антон Копылов: А вы не рассматривали Mercurial как альтернативу Git?

Владислав Чернов: Насколько я знаю, мы не рассматривали альтернативу Mercurial, потому что на тот период количество плагинов, ПО для управления репозиториями и так далее больше было на Git. Плюс сообщество уже тогда сформировалось, а на Mercurial только начинало. Для меня, например, особый плюс ― это то, что Git использует любые языки, а с Mercurial все сложней.(Примечание от руководителя тестирования Ильи Агеева: Mercurial мы пробовали вводить много лет назад, но он у нас не прижился и мы вернулись обратно на SVN).

Антон Копылов: Угу, хорошо.

Олег Оямяэ: Вот так вот. Соответственно, два с половиной года назад начался процесс по внедрению контроля качества. Был создан отдел, который растёт и развивается до сих пор. Как раз в тот период было разработано новое workflow, в котором каждая задача делалась в отдельной ветке, но по-прежнему собиралось всё руками, не было ни автоматизации, ни, по большому счёту, ничего. Выкладка происходила, можно сказать, совсем руками. Была утилита, которую написали очень-очень давно, посредством неё всё выкладывалось, и никакого мониторинга не было. Со временем было много написано вокруг этой утилиты ― dashboards и прочие вещи, она стала своего рода ядром. Это если вкратце.

Антон Копылов: А процесс выкладывания и тестирования, он у вас был вместе собран или это были разные процессы?

Олег Оямяэ: Раньше это были не совсем связанные между собой процессы. Сейчас же это полноценная непрерывная интеграция, когда после каждого коммита прогоняются тесты, и это непосредственно влияет на выкладку и на staging. Эти два процесса сейчас связаны между собой и влияют друг на друга.

Антон Сергеев: Кстати, ребят, хотел спросить ваше мнение. Понятно, что многие проекты при старте чаще всего используют только систему контроля версий и, допустим, какие-то хуки, чтобы это контролировать. Обычно никто сразу не ставит мощные средства для continuous integration, для деплоя. Как считаете, что может являться переходной точкой, насколько проект должен разрастись, чтобы стало понятно, что невозможно дальше обходиться без нормального continuous integration и без тестов?

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

Антон Сергеев: То есть если бы вы сейчас делали Badoo заново, то вы сразу взяли бы такую систему и самый первый коммит попал бы уже через continuous integration и прошел бы все тесты?

Олег Оямяэ: Ну я бы ― да.

Владислав Чернов: Я бы сказал немножко по-другому. Если мы говорим о «попсовом» слове start-up, то понятно, что никто не будет делать такую сложную систему, потому что неизвестно, взлетит ли start-up, а ресурсы на тесты тратятся немаленькие, плюс у нас всегда есть ограниченные сроки, за которые мы должны выдать продукт на рынок. Соответственно, говорить об автоматическом тестировании с начала проекта, наверное, не нужно. Но говорить и думать про автоматические сборки и, возможно, какое-то «версионирование» и автоматическое развертывание надо с самого начала, потому что это не займёт очень много времени у команды проекта и это небольшие ресурсы по сравнению с теми же автоматическими тестами.

Антон Сергеев: Понятно. А давайте вы ещё вкратце нам расскажите по поводу того, как у вас проходят 2 релиза в день, про несколько этапов тестирования, n-ое количество тестов и как это работает. Про откаты, патчи, хотфиксы.

Владислав Чернов: Давайте я сначала немножко вернусь к истории: 2 релиза в день ― это действительно так, у нас уезжает порядка 50-60 задач в день. Всем, наверно, будет интересно узнать, почему именно 2 релиза. Всё очень просто. Понятно, что сначала был один релиз в неделю или один релиз в несколько дней, потом был релиз каждый день, а потом стало два релиза в день. Почему два?
Мы перешли в какой-то момент на flow, где каждая задача делается в отдельной ветке, и, соответственно, когда мы формируем релиз, мы сливаем эти задачи в релизную ветку, проверяем повторно каждую из задач и плюс мы проверяем смерженность кода (интеграционное тестирование). Когда это от 10 до 30-40 задач максимум ― это сделать достаточно легко. Когда вам нужно разгребать 100 задач в этом релизе, то это уже сделать сильно сложнее. И поэтому мы деплоим два раза в день, мы можем деплоить и чаще, но в этом нет большого смысла. Почему каждая задача в отдельной ветке, наверно, тоже ясно. У нас есть несколько этапов тестирования, их где-то около 5. Каждая задача в отдельной ветке, потому что мы её можем откатить и проверить. Получается, что у нас есть код с production плюс эта задачка. И мы её проверяем на нескольких этапах тестирования. Первый этап стандартный ― это code review, и смотрится только эта задача. Сделанная задача проверяется на девелоперском окружении. Девелоперское окружение ― это наша мини-серверная с виртуальными машинами, с базами и так далее. На ней можно проверять такие вещи, которые нельзя проверить в production. Задачи там тестируются, потом мы создаём мини-стейджинг для каждой задачи, он называется shot, база используется из production, и мы проверяем задачу ещё раз. Потом задача уезжает в релиз и проверяется на смерженность кода уже в релизной ветке, не ломает ли она другие задачи. И так далее и так далее. Там задача проверяется в четвёртый раз. И есть опциональные тестирования на post-production, когда мы тестируем эту задачу по какому-то запросу от product-менеджера, либо это очень важная задача и тестировщики повторно её проверяют на production, но это опциональные вещи.

Антон Сергеев: А как у вас происходит code review? Его делают какие-то специальные люди, либо разработчики случайным образом делают review кода других разработчиков?

Владислав Чернов: В каждом отделе всё проходит по-разному. Когда задача попадает на review, выбирается разработчик или группа разработчиков. В одних группах review делают руководители команд по компонентам. В других ― задачи просто ротируются внутри группы. Это зависит и от численности отдела, и от опыта людей, и от традиций.

Антон Сергеев: Ребята, давайте я задам вопросы, которые прислали слушатели. Например, Станислав прислал нам много вопросов всяких-разных. Я их разбил на несколько групп. Например, он спрашивает, кто принимает конечное решение о выкате релиза ― бездушная машина или какой-то аналог Сергея Дидыка.

Олег Оямяэ: Нет, у нас нету Сергея Дидыка, он есть в другой компании (примечание: речь идет о компании Бегун). У нас релиз идёт два раза в день в определённое время утром и вечером и, соответственно, мы собираем из задач релиз до этого времени, потом автомерж останавливается и мы начинаем тестировать эти задачи. Когда задачи протестированы и приходит момент выкатки релиза, релиз-инженер принимает решение и мы уезжаем на production.

Антон Сергеев: Чем выкатываете? И как закатываете назад, если не выкатилось? На какой промежуток времени можете откатиться назад, если что?

Владислав Чернов: Для выкатки у нас есть своя утилита для деплоя, она написана нашим разработчиком Юрием Насретдиновым. Утилита очень быстро выкатывает тысячу серверов, буквально за 2-3 минуты. Это наша система деплоя, и мы её постоянно улучшаем.
(Примечание: откат ― это такая же выкатка, только номер версии другой. Таким образом и выкатиться, и откатиться мы можем за несколько минут. Откатиться даже быстрее, т.к. предыдущая версия на серверах остается. Нужно просто перекинуть линк, а это несколько ssh-команд для переключения и сброса кэша).

Антон Сергеев: А она есть где-нибудь на GitHub, её можно обычным людям пощупать?

Владислав Чернов: Нет, её нет, а почему ― это, наверное, вопрос к Юрию Насретдинову.

Антон Сергеев: Понятно, будем надеяться, что выложите. Было бы интересно пощупать, конечно.

Владислав Чернов: Да.

Антон Копылов: А у меня такой ещё вопрос, вы говорите, что у вас есть стадия тестирования, когда на стейджинге с production-базой проверяется код. А каким образом вы данные переносите с production в стейджинг? Если обнаруживается проблема, то что вы с этим делаете?

Олег Оямяэ: А что вы имеете в виду под этой проблемой?

Антон Копылов: Могу ли я проверить на стейджинге, например, не на ста миллионах пользователях, а на одном миллионе? Или вы переносите целиком всю базу и на полном объёме проверяете этот код?

Олег Оямяэ: Нет, там используется не копия, а полноценный настоящий production.

Антон Копылов: Ааа.

Олег Оямяэ: И только код с некоторыми новыми изменениями, а база используется именно от production.

Антон Копылов: Угу. А не страшно на стейджинге коннектиться к production-базе?

Олег Оямяэ: Нет, потому что тестирование происходит на тестовых пользователях, то есть даже если там что-то случится, это никак не «зааффектит» и не потревожит настоящих пользователей (плюс до этого задача тестируется дважды).

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


Владислав Чернов: Я могу так ответить на этот вопрос: мы можем выкатить на любую машину и на любой кластер. Мы используем порядка 10 кластеров. И можем выкатить этот код с помощью утилиты на любую из частей кластера. По поводу интереса того, что куда-то выкатить и потестить, то мы в основном выкатываем для тестирования новой фичи и нам хочется посмотреть на результаты. Мы выкатываем отдельную страну, а не какой-то набор машин, потому что это гораздо удобнее.

Антон Сергеев: Понятно. А как у вас происходит откат? Допустим, у вас какая-то фича попала в релизную ветку и что-то пошло не так в процессе тестирования на стейджинге. Например, вы обнаруживаете, что есть какая-то серьёзная проблема и желательно её пока что откатить. То есть расскажите, как вы работаете с системой контроля версий (Git), используете ли вы git rebase или git revert. И если да, то расскажите, как.

Владислав Чернов: Мы используем git rebase, мы именно его используем, потому что git revert нас не устраивает, так как мы разрабатываем каждую задачу в отдельной ветке. Если мы откатываем с помощью revert после сливания ветки релиза и ветки мастера, то разработчику придётся делать revert на revert, поэтому мы используем git rebase. Мы моментально откатываемся, соответственно, собираем новую сборку и выкладываемся на стейджинг.

Антон Сергеев: А у вас не было проблем с git rebase? Насколько я знаю, штука эта довольно капризная, её нужно уметь правильно использовать. Какой у вас тут рецепт?

Владислав Чернов: На самом деле она не такая уж и капризная и рецепт очень прост: мы вмерживаем в релизную ветку другие ветки, и у нас дерево релизной ветки очень простое, и откатить задачу очень просто, так как это смерженный коммит. И мы понимаем, что git rebase ― это полностью ручная операция. Но у нас есть алгоритм и небольшой скрипт, который выполняет это в автоматическом, ну почти в автоматическом режиме.

Антон Сергеев: Мы уже знаем, что вы используете Git, но помимо этого вы ещё используете такой замечательный инструмент от компании JetBrains, как TeamCity ― это continuous integration server, а ещё у вас это всё заинтегрировано с баг-трекером JIRA, я так понимаю ― и постановка задач, и автоматические смены статусов. Как у вас всё это появлялось и интегрировалось, и как вы с этим работаете?

Олег Оямяэ: Да, как уже было сказано, мы используем Git, а также JIRA и TeamCity. TeamCity мы используем для прогона тестов и выкладки кода на стейджинг при успешном прогоне. На самом деле, flow в JIRA у нас сильно проработан и структурирован, и заинтегрированы все компоненты системы JIRA, Git и TeamCity. У нас очень большой workflow который мы регулярно оптимизируем, чтоб было удобно и разработчикам, и тестировщикам, и менеджерам продукта.

Антон Сергеев: Кстати, на последней конференции DevConf был доклад про проблемы в архитектуре, и спикер говорил, что JIRA ни в коем случае не нужно использовать, потому что там нельзя раздавать права разным пользователям на уровне просмотра задач, чтобы, допустим, разработчики не видели какую-то там дополнительную метаинфу, которая нужна проект-менеджеру, а проект-менеджер не видел каких-то деталей, которые могут быть полезны только разработчикам. Насколько это вообще, по-вашему, критично и с какими вы сталкивались проблемами с JIRA? Были какие-то действительно серьёзные вещи, которые вы как раз допилили?

Владислав Чернов: Эта проблема с проект-менеджером и с разработчиком, она какого-то очень закрытого плана, мы на самом деле все дружим и у нас нет скрытой информации, и нет такой проблемы по филдам, например, ― скрывать их или нет. По поводу того, использовать JIRA как баг-трекер или нет ― это каждый выбирает сам, но это как минимум самая распространённая система в мире, именно как баг-трекер. В чём-то она нас устраивает, в чём-то ― нет. Там, где она нас не устраивает, мы автоматизируем работу с ней. На самом деле, у нас сложный workflow, но в JIRA два уровня вложенности таска и сабтаска, и из-за этого мы получаем больше плюсов, чем минусов, т.к. не можем усложнить процесс.

Антон Сергеев: Угу. А Вы используете confluence? Если слушатели наши не знают, я просто сейчас скажу, что confluence ― это wiki, где можно хранить документацию и не только.

Владислав Чернов: Да, конечно, мы используем его. И я вот боюсь ошибиться, но насколько я знаю, мы даже пользуемся GreenHopper. Но мы не используем FishEye для просмотра кода, потому что это очень громоздкий инструмент, и мы для review кода используем GitPHP, который, опять же, сами допиливали, и он достаточно быстр по сравнению с тем же FishEye, который индексирует огромное количество наших веток несколько суток.

Антон Сергеев: А какое у вас впечатление от работы с TeamCity? Пользовались ли чем-то ещё, пробовали ли Jenkins, например?

Владислав Чернов: Да, я работал со многими серверами непрерывной интеграции: и с Jenkins, и с TeamCity, и с Bamboo. Но TeamCity нас устраивает в большей степени, чем остальные сервера непрерывной интеграции, в данный момент представленные на рынке.

Антон Сергеев: А можете поподробнее рассказать, с чем это связано? С вашим текущим процессом, с выкаткой релизов или там есть какие-то особенности, которые другие разработчики тоже могли бы учесть. Допустим, сейчас нас слушает разработчик и думает, что ему выбрать. Есть ли какие-то важные факторы, по которым стоит выбрать TeamCity?

Владислав Чернов: Одно из преимуществ TeamCity в том, что его бесплатного функционала достаточно для того, чтобы его могли использовать маленькие компании. С другой стороны, у него есть платные функции, он поддерживает платный support и сделан качественно. Все говорят, что Jenkins хорош тем, что для него очень много плагинов. Это действительно так, но получается, что если вы рассчитываете на какой-то плагин, а потом выходит новая версия Jenkins, бывает, что плагин не переписывается, и вы сталкиваетесь с проблемами, и вам нужно опять всё перестраивать.
TeamCity нас подкупил как минимум тем, что он достаточно прост в использовании и удобен не только релиз-инженерам, но и тестировщикам, и девелоперам. Плюс на тот момент у них выходили определённые фичи, которые нам отлично подходили. Это, например, ловля ветки по маске, а у нас огромное количество веток, и мы не перестраиваем билды. Потом эти фичи были добавлены в другие серверы непрерывной интеграции, но это уже было потом. Ну и, конечно, support нас отлично поддерживает и помогает, они дорабатывают продукт и некоторые вещи доделывают под нас.

Антон Копылов: Я ещё хотел добавить, что в TeamCity одна из фич, которая мне кажется killer-фичей, ― это наследование конфигурации. Можно сделать шаблон конфигурации и потом от него уже создавать какие-то клоны. Это сильно упрощает процесс добавления подпроектов в систему.

Владислав Чернов: Да. Это как если вы, допустим, используете один репозиторий и у вас нет кастомных конфигураций, и какие-то вещи вы можете настроить как шаблон и либо передать параметры, либо ещё что-то. Это тоже интересная особенность.

Антон Копылов: Это как раз то, чего нет у конкурентов ― наследование конфигурации, такая вот фишка TeamCity.

Антон Сергеев: А у меня ещё вопрос по поводу Git. Все знают или по крайней мере слышали про так называемый git-flow. Это такой стандартный подход к использованию Git. Данный подход был разработан достаточно давно, и это удачная модель бранчинга. Ваше flow основано на этом стандартном подходе, где используются feature branch, release branch, hot-fix branch, master, developer branch, или у вас есть свои фишечки, какие-то хорошие рецепты ― как лучше создавать ветки, как лучше сливать ветки ― что про это можете рассказать?

Владислав Чернов: Да, конечно. На самом деле мы далеки от git-flow. У нас всё просто: есть мастер, в котором содержится копия кода на production, туда никто не имеет право пушить, туда могут применять патчи, у нас есть специальный для этого инструмент, он называется Deploy Dashboard. Релиз-инженер смотрит этот патч: если всё хорошо, он его применяет в полуавтоматическом режиме в веб-интерфейсе, и, соответственно, код разложится на production и что-то там пофиксится. Это бывает достаточно редко, но бывает, конечно. И у нас есть релизная ветка, которая создаётся два раза в день полностью в автоматическом режиме, плюс есть ветки задач. В ветке задачи нумеруются по тикетам JIRA: номер тикета и какое-то описание ветки. И вот тикет создается, эта ветка вместе с тикетом идёт по flow, она разрабатывается, идёт на review, проверяется в несколько этапов тестирования, потом автоматически мержится в релизную ветку, и здесь включается сервер непрерывной интеграции, который собирает этот билд. И хотя у нас PHP-код, он у нас действительно собирается. Например, гоняются переводы, которые автоматически генерятся более чем на 40 языков и, соответственно, выкатываются на стейджинг и к окружению, и всё это делается в автоматическом режиме. Релиз заканчивается, он мержится в мастер и создаётся автоматически новый релиз.

Антон Копылов: У меня вопрос возник: а нумерацию вы какую-нибудь ведёте? Если у вас 2 релиза в день, то у вас, наверное, очень много релизов уже набралось, или не так быстро растёт этот номер?

Олег Оямяэ: Не совсем так. Да, в TeamCity есть внутренний инкремент, но он больше используется для работы непосредственно с TeamCity, а так сами имена релизов носят более «человекопонятный» формат, то есть там присутствует дата, время и проект, потому что мы выкладываем не только для web ― с недавних пор и для iOS, и для других проектов. Так что у нас нет такой проблемы, как, например, «релиз 365», и никто не понимает, что это вообще такое и откуда.

Антон Сергеев: Да, бывает такая проблема. Я сталкивался с ситуацией, когда есть у тебя задача, допустим, в Redmine, и ты пишешь, что фича такая-то, таск такой-то. Потом смотришь в релиз, а там куча фич. Ты говоришь: «Да что ж такое-то, какая из них моя?» И приходится в браузер лезть, чтобы там смотреть.
Я считаю, что несмотря на то, что каждый из инструментов, который вы используете, будь то JIRA, TeamCity или Git, сам по себе хорош, но лучше всего и эффективней всего они себя показывают, как мы видим, на вашем примере ― в интеграции. И вот для этого вы используете такой инструмент, как AIDA, правильно? Расскажите, как вы это делаете, как к этому пришли и какие профиты получаете?


Олег Оямяэ: Да, мы используем AIDA. Это такой виртуальный пользователь, от лица которого происходят все автоматические действия, какие-то скрипты запускаются, рассылаются нотификации в Jabber, в почту, обновляется информация в dashboard, то есть весь процесс автоматизирован, вся информация доступна как в TeamCity, так и в JIRA. Также у нас есть определенный формат commit message, когда мы просматриваем Git log, тоже всё видно и понятно. Также в JIRA присутствуют ссылки на GitPHP в конкретной задаче: всегда можно посмотреть как полный diff, так и все коммиты по отдельности. Так что да, наверно, использование этих трёх инструментов вместе действительно удобно и оправдано.

Антон Сергеев: А насколько сложно начать работать с AIDA, или это очень простой инструмент, не какой-то там rocket science?

Олег Оямяэ: Скажем так: там есть простые части, но есть и достаточно витиеватые.

Антон Сергеев: Какие у вас были самые серьёзные проблемы, с которыми вы столкнулись, используя AIDA и при интеграции с TeamCity, JIRA, Git?

Олег Оямяэ: Ну смотрите, на самом деле AIDA во многих случаях использует API к JIRA, TeamCity, с Git она работает как обычный пользователь. Первая часть, с которой мы столкнулись, это, конечно же, API. Оно меняется от версии к версии, и нельзя сказать, что оно всегда стабильно. И это была первая ситуация, когда мы столкнулись с трудностями. По поводу реализации AIDA, вопрос в том, как грамотно настроить бизнес-процесс: например, в какой момент создать ветку релиза, в какой момент запустить automerge и так далее. Правильно выстроить нотификации, потому что люди должны понимать как идёт этот процесс, и если мы что-то упустим, то AIDA будет работать без нас, и это будет неконтролируемый процесс. Выстраивание этого процесса ― это и есть самая большая сложность.

Антон Сергеев: Получается, это всё отлаживается, пишется, прогоняется, смотрится и так далее до тех пор, пока более-менее не войдёт в нормальный рабочий ритм, правильно?

Олег Оямяэ: Да. У нас есть специальное окружение, в котором мы пишем и тестируем AIDA, так что в большинстве случаев какие-то доработки и изменения проходят гладко и ничего не ломается. В этом плане всё хорошо.

Антон Сергеев: Ясно. А есть планы на будущее, может быть, какие-то интересные технологии в плане выкатки, деплоя, автоматизации, на которые вы смотрите, либо которые вы видите сейчас на рынке? Или вы пока более чем довольны вашими инструментами и не хотели бы что-либо менять?

Олег Оямяэ: Да, пока нас всё устраивает, мы дорабатываем AIDA и всё хорошо.

Антон Сергеев: Супер. Предлагаю тогда перейти к следующей большой теме. Давайте поговорим про тестирование и про то, как вы делаете автоматическое тестирование, что для этого используете, как это всё происходит и каких показателей вам удалось добиться?

Владислав Чернов: Да, мы используем автоматическое тестирование. Если начинать с самого начала, то стоит сказать, что unit-тесты у нас пишут разработчики. На данном этапе времени задача не принимается в релиз, если она не покрыта unit-тестами. Соответственно, мы используем Selenium для PHP-кода, считаем code coverage, это достаточно стандартно. У нас в какой-то момент возникла достаточно большая проблема из-за двух релизов в день: это ограниченное время, это буквально несколько часов на тестирование и сейчас, соответственно, у нас нет последовательного процесса, у нас всё идёт параллельно. Например, идёт push в релизную ветку, автоматически запускается сборка, автоматически запускаются unit-тесты и selenium-тесты ― параллельно, и, может быть, опционально отдельные какие-то тесты, которые очень важны. И мы столкнулись с такой проблемой, что у нас было порядка 18 000 тестов (примечание: сейчас 20000), и они проходили очень большое количество времени.

Наш замечательный коллега Илья Кудинов написал утилиту, которую мы называем «Пускалка», которая делит эти тесты на 11 потоков, при том она их полностью формирует по времени, так чтобы каждый поток проходил за равные промежутки времени, и сейчас у нас тесты гоняются где-то порядка 3,5 минут ― это 18 тысяч юнитов. И тесты гоняются не только на релизной ветке ― они гоняются также после того, как разработчик завершил свою задачу в ветке. Также в автоматическом режиме. Там существует отчёт, который пишется в JIRA, и разработчик либо тестировщик сразу же может посмотреть результат прогона этих тестов: что упало, что не упало и так далее.

Антон Сергеев: Ага. А по поводу Selenium, есть опять же от Станислава вопрос, большая ли ферма под Selenium?

Владислав Чернов: Я могу ошибаться, но насколько я знаю, ферма достаточно большая. Это связано с тем, что мы поддерживаем довольно большое количество браузеров и мы только недавно отказались от Explorer 6, то есть мы тестируем почти на всём: это и Chrome, и Firefox, и Explorer. И сама ферма достаточно большая. Мы также «распараллеливаем» тесты, пускаем их по параллели по причине того, что они проходят довольно продолжительное количество времени. Мы пробуем использовать браузеры и движки без GUI, но я не могу похвастаться и сказать, что это очень успешно проходит.

Антон Сергеев: Ага. Кстати, мне вспоминается знаете что: я был на Форуме Технологий Mail.ru, и там был доклад или от Яндекса, или от Mail.ru (честное слово, забыл) о том как они используют Selenium. И там был смысл примерно в том, что они сначала запускали для каждого браузера отдельную ноду ― я так понимаю, что это какая-то виртуальная машина типа Xen'а, и это всё получается довольно «ресурсозатратно» и не очень хорошо, и Selenium бил по рукам, что нельзя на одной это ноде запускать тесты одновременно для разных браузеров, потому что будет ломаться, будут глюки, в общем, будут проблемы. И они полезли в сорцы, что-то там подпилили, поняли какие-то особенности того же Explorer’а, когда ему, не знаю, фокус принудительно вернуть, что-нибудь ещё сделать, чтобы все тесты параллельно не падали. И они об этом рассказывали и говорили, что это вообще мегакруто, что мы смогли так и заставили так работать всю эту систему, что всё стало быстро проходить. Вы подобными вещами вообще баловались, сталкивались с этим? И как вы смотрите на подробного рода «костыли»?

Владислав Чернов: Я не знаю, что на самом деле происходит в браузерах, мы все-таки не пишем selenium-тесты и не знаем таких подробностей. Но на мой взгляд, есть браузеры, которые обновляются довольно часто, и тогда эти костыли надо переносить от одного браузера к другому как минимум. По поводу упавших тестов: selenium-тесты ― это такие тесты, которые всё равно падают, и самый распространённый способ это устранить ― это прогнать эти тесты повторно и посмотреть, упадут они или нет. По поводу того, кто что делает, например, по поводу отдельных виртуальных машин, мы это не используем, и для каждого отдельного браузера принимать свою машину слишком ресурсозатратно. Но, что интересно, Google, например, гоняет selenium-тесты на своем дата-центре.

Антон Сергеев: Ничего себе.

Владислав Чернов: Да, при этом машины ― это production-площадки, комовская площадка. Он берёт те же машины, которые используют пользователи, и гоняет там selenium-тесты, так что ресурсы у всех разные. Мы стараемся всё-таки менее ресурснозатратно всё делать.

Антон Сергеев: У нас еще остались вопросы от слушателей. Какие типы тестов вами пишутся?

Владислав Чернов: Смотрите, у нас как минимум есть unit-тесты и, понятное дело, функциональные тесты. То есть мы лезем в базы, мы смотрим там базы на devel. У нас есть Selenium, который работает на devel, на обоих площадках. У нас два дата-центра, и инфраструктура devel полностью повторяет инфраструктуру площадки. У нас здесь две площадки, и репликация баз на devel такая же, как на площадках. То есть всё, что есть на production, есть сейчас и в девелоперском окружении. Но мы гоняем selenium-тесты и на девелоперской площадке, и на стейджинг, и на какие-то критические моменты на production. Для PHP это, наверное, и всё.

Антон Сергеев: Ещё тогда такой вопрос: unit-тесты совсем unit? Без БД? Если да, то как тестируется связка хитрых SQL-запросов с парой джоинов и тем, что это обрабатывает?

Олег Оямяэ: Мы стараемся писать unit-тесты как unit-тесты, а хитрые запросы ― для этого есть функциональные тесты, которые как раз для этого и нужны. Unit должен быть Unit’ом и проверять только одну конкретную часть.

Антон Сергеев: Есть ещё вопрос от Стаса (он задал очень много вопросов, и я не могу удержаться ― надо же ответить человеку, раз ему интересно). Используете ли вы A/B-тестирование и как тестируете производительность?

Олег Оямяэ: Да, мы используем A/B-тесты. Правда это делается средствами другого отдела, но в Badoo используется A/B-тестирование, чтобы понять, какой вариант дизайна текста или, например, кнопки, лучше и приятней пользователю, чтобы сервис становился ещё более удобным и понятным. Для этого тоже есть специальные инструменты автоматизации.

Антон Сергеев: А производительность как тестируете? Я так понимаю, что здесь имеется в виду производительность не самих тестов, потому что вы сказали, что у вас 18 тысяч тестов проходят за 3,5 минуты, да?

Олег Оямяэ: Да. Всё верно.

Антон Сергеев: А производительность, не знаю, допустим, response на production, на какой-то конкретный запрос.

Олег Оямяэ: Не уверен, правильно ли я понял вопрос. Но у нас есть отдел мониторинга, который непрерывно ―24 часа в сутки 7 дней в неделю и так далее ― мониторит состояние всей системы, всех, абсолютно всех частей, а также время ответа страниц, насколько быстро отдаётся статика. Если что-то пошло не так, тут же эскалируется проблема ответственному лицу и проблема в кратчайший срок локализуется и исправляется.

Антон Сергеев: Давайте ещё поговорим по поводу code coverage: какие у вас требования есть к покрытию кода, как вы с этим работаете, насколько покрываете. Как я понял, самое главное это то, что код без покрытия не попадает в релиз. Но а дальше как вы это мониторите, насколько много стараетесь писать тестов?

Олег Оямяэ: Тестами должен покрываться весь новый функционал, то есть когда разработчик отдаёт какую-то задачу в тестирование, все методы, новые или изменённые, он обязан покрыть unit-тестами. Соответственно, потом задача уходит в QA, QA пишет selenium-тесты, функциональные тесты и затем считается coverage раз в сутки, и дальше руководители отделов, тестировщики и все заинтересованные лица в специальном веб-интерфейсе могут посмотреть, у какой группы насколько хорошее покрытие, и сделать соответствующие выводы, поставить какие-то задачи на дописывание unit-тестов, или отдел тестирования поставит задачу на дописывание Selenium’а. Всё это непрерывный процесс улучшения кода и покрытия.

Антон Сергеев: А давайте ещё тогда поговорим про вашу «пускалку», о которой вы только вскользь упомянули. Мне интересно подробнее узнать, насколько всё-таки у вас улучшилась производительность, сколько было, сколько стало, и поподробней расскажите про архитектурно-философские подходы, которые использовались при разработке «пускалки»?

Владислав Чернов: Мы там рассматривали несколько схем, даже самые простые, например, разделение какими-то suites на n-ое количество тестов и запуск их, и разные другие варианты. Они тоже все описаны, и про них можно почитать. По поводу профита и того, как это было реализовано, расскажу сейчас поподробнее. Профит мы получили, так как, если я не ошибаюсь, тесты гонялись где-то в районе 20 минут, может быть, даже больше. Но сейчас это 3,5 минуты, то есть мы получили огромный выигрыш по времени. По поводу реализации, мы разбиваем запуск на 11 потоков, при этом suites формируются так, что они берут время из определённой базы, которая сформирована на основе базы TeamCity-сервера. Мы знаем, сколько гоняется каждый тест, мы собираем эту информацию, если я не ошибаюсь, за 7 дней, берём какое-то среднее значение и, соответственно, знаем, сколько этот тест в средне