Worldwide-биллинг Badoo глазами QA
Привет, Хабр! Вот уже больше четырех лет я занимаюсь ручным и автоматизированным тестированием биллинговых систем Badoo. А биллинг Badoo — один из самых развитых (и сложных) в мире, и тестировать его — чаще всего интересная и неординарная задача. Сегодня я хочу вам рассказать, почему эти системы такие интересные и могучие, чему я научился за все эти годы и почему тестировать биллинг — это не (очень) страшно. И заодно поделюсь с вами очередной партией интересных историй (да, я это дело очень люблю). Большинство вещей будет применимо не только к нашему конкретному случаю, но и к любой другой сложной платежной системе (и не только платежной, если честно).
Что же такое наш биллинг? Это система обработки платежей в социальной сети, в которой более 330 миллионов зарегистрированных и более 20 миллионов активных пользователей в сутки. Мы принимаем платежи во всех странах мира, поддерживаем свыше тридцати активных платежных методов (а за все время их было имплементировано около ста) и обрабатываем порядка 1500 запросов в секунду. Биллинг Badoo является самостоятельным выделенным сервисом, работающим с десятком разных клиентов (разные платформы, разные приложения). Достаточно любопытная база для развития тестирования, не так ли? :)
Объект тестирования
Итак, для начала вкратце расскажу, что именно нам приходится тестировать. Все наши клиенты (веб, мобильные приложения и некоторые back-end сервисы) общаются с биллингом с помощью API. Сам же биллинг располагается на отдельном кластере в каждом из наших дата-центров и ведет общение с различными платежными системами (посылает запросы на оплату, получает нотификации с результатом обработки запросов и т.д.). В кластере располагаются машины для обработки обращений клиентов и платежных систем, машины для запуска CLI-скриптов (например, для обновления истекающих подписных сервисов), наш собственный сервер обработки платежей банковскими картами и базы данных.
Разработчики биллинга занимаются решением задач нескольких видов:
- разработка нового функционала: новые платные сервисы, промо-кампании, различные фичи для подписчиков;
- разработка новых интеграций с платежными сервисами (всегда можно найти кого-то с более низкими комиссиями или более высокой конверсией);
- актуализация имеющихся интеграций (наши партнеры тоже развиваются);
- исправление багов (давайте признаем — у всех они бывают! );
- задачи по оптимизации и решению технического долга (всегда можно сделать сервис чуть-чуть лучше);
- решение задач технической поддержки (очень любим самых хитрых пользователей, которые умудряются создать десяток подписок на разных платежных сервисах в разных странах и потом путаются, как же отменить ненужные).
И все это «добро» в конечном счете приходит на тестирование нашей небольшой команде. Кроме задач непосредственно от биллинговых разработчиков, мы получаем задачи и от других команд, если они как-либо касаются платежей: например, изменения и новые фичи на клиентах или сервере мобильных приложений.
Что же именно мы тестируем? Можно разбить это все на три категории:
- пользовательские интерфейсы: всевозможные платежные окна (мы называем их «визардами») на разных платформах, окна настроек, рекламные баннеры, промо-окошки и т.д.;
- «админку» и конфигурационные инструменты: настройки цен, промо-кампаний, экспериментов и инструменты для техподдержки (которыми мы еще и очень активно пользуемся при тестировании);
- биллинговый back end: обработка платежей, очереди оказания услуг и проведение различных отложенных операций (самая сложная и «сочная» часть).
Постараюсь вам обо всем этом рассказать по порядку.
Пользовательские интерфейсы
Итак, самая главная часть здесь — платежные визарды. Выполняя одну и ту же функцию (получение от пользователя информации о том, сколько сервиса он хочет купить и каким способом он хочет это сделать), визарды выглядят по-разному на разных платформах. Зависит это в первую очередь от особенностей платформы, но также и от различных требований регуляторов и от бесчисленных A/B тестов, которые проводятся на наших приложениях.
Что же здесь можно протестировать? Да море всего! Каждый платежный метод должен отображаться корректно при любом выбранном варианте сервиса. Список самих вариантов должен соответствовать желаемому, на каждом из них должна быть указана заданная в настройках биллинга цена, при этом формат цены и валюты должен соответствовать принятому в стране стандарту: например $6,49, 125,00 MXN или 17.64BYN.
Каждое платежное окно должно сопровождаться подробными условиям оказания сервиса. Каждое промо-окошко тоже должно содержать все необходимое или вести к следующему шагу с полным описанием условий (вот это, кстати, одна из самых частых проблем, про которую так легко забыть).
Любое действие пользователя в таких окнах должно сопровождаться корректными сообщениями, причем не только об успешных платежах, но и об ошибках (нужно уметь отличать ситуации, когда пользователь отменил платеж на стороне партнера, а когда реально ввел некорректную информацию).
Казалось бы, можно составить для всего этого свод базовых проверок и ограничиться им. Не тут-то было! В каждой стране имеются свои обязательные к исполнению требования, которые необходимо соблюдать, чтобы иметь возможность вести бизнес. Например, при оплате через СМС в Бельгии короткий номер для оплаты нужно обязательно отрисовывать крупными белыми цифрами в черном прямоугольнике (я не шучу). Во Франции одно время на КАЖДОЙ странице сайта должна была находиться кнопка на отписку от имеющегося подписного сервиса, а сама отписка до сих пор должна производиться в один клик, без каких-либо подтверждающих шагов. В некоторых странах нужно обязательно сообщать, что цена включает в себя налоги, а в некоторых других даже отдельно указывать стоимость услуги и дополнительные налоги (и нигде не писать их в сумме).
Как же проверять такой «зоопарк» платежных методов? Ездить по всем странам мира для максимально честного тестирования не получится (а так хотелось бы потестировать платежи в Бразилии, хнык), ровно как и заводить аккаунты во всех существующих платежных системах. Поэтому приходится довольствоваться различными «песочницами». Некоторые партнеры предоставляют нам собственные очень удобные песочницы, например, агрегаторы банковских карт или PayPal. Некоторые из них не так функциональны: у одного из партнеров она представляет собой скриншот их обычного платежного окна с наложенной на него кнопкой «Заплатить».
В остальных случаях строить песочницы нам приходится самим, эмулируя различные ответы и нотификации. Но даже это получается не везде, и приходится руками собирать нотификации, делать какие-то подмены в коде и отправлять их себе https-запросами.
Совсем отдельной головной болью являются визарды в мобильных приложениях. Здесь пользователь общается с биллингом еще более опосредованно. Приложение шлет запрос к платежной системе (AppleStore или GoogleWallet, например), полученный ответ сразу же отсылает на сервер мобильных приложений, тот в свою очередь обрабатывает информацию и посылает новый запрос на биллинговый кластер, а ответ биллинга проходит весь этот путь обратно в платежную систему. «Юзер-экспириенс» может сломаться в любом месте этой цепочки! Облачко об ошибке может означать, что запрос не дошел до биллинга и платеж не совершен, а вполне может обозначать и то, что все прошло прекрасно, но сервер мобильных приложений ответил платежной системе не совсем в том формате, который она ожидала. Бардак!
И давайте даже не будем здесь говорить о том, какие неудобные песочницы у Apple и Google, особенно при попытках тестировать подписки.
Между прочим, сам факт работы со внешними партнерами приносит с собой немало проблем. Их платежные окна могут открываться долго и тормозить тестирование, они могут содержать в себе самые обычные баги (которые ты, как уважающий себя тестировщик, первым делом приписываешь собственным разработчикам). Любые действия, требующие сотрудничества с их стороны (фиксы тех же багов, расширение протокола) тоже зачастую затягиваются, причем они могут самостоятельно делать какие-то изменения, не поставив нас в известность (о чем мы узнаём только по возросшим графикам ошибок), и предоставлять нам неполную или даже некорректную документацию.
Админка
Ничуть не менее важная составляющая биллинга полностью скрыта от глаз наших пользователей. Это все то, что позволяет нашему менеджменту регулировать цены и доступность сервисов и запускать промо-кампании, а труженикам службы технической поддержки — выявлять причины проблем пользователя (и убеждаться в том, что они не пытаются просто получить сервис «на халяву») и максимально простым и безопасным способом их решать. К тому же все эти средства помогают нам в тестировании (воспроизводить многие кейсы исключительно действиями в интерфейсе пользователя либо достаточно сложно, либо очень долго).
Помимо непосредственной проверки работоспособности тут нужно много времени уделять тому, чтобы разработчики и менеджеры воспринимали реализованный функционал одинаково (очень часто только мы справляемся с тем, чтобы установить между ними контакт и полное взаимопонимание). Все конфигурационные системы достаточно сложны из-за широкого спектра возможностей (у нас постоянно проводятся десятки A/B тестов дизайна, платежных методов и промо-кампаний), и малейшие детали могут привести к тому, что система будет вести себя совсем не так, как ожидает менеджмент. В наши обязанности входит удостовериться в том, что разработчик правильно понял задание, а менеджер смог разобраться в предоставленной документации (коли такая вообще есть). Ну и конечно, очень здорово после каждого изменения конфигураторов следить за результатами их работы и несколько раз уточнять, на самом ли деле все хотели сделать вот ЭТО вот.
А еще тут надо похвалиться, что один из разработанных (и конечно же протестированных!) нами инструментов для роутинга платежей картами на нужные банки и аккаунты принес нам нам престижную награду Merchant Spotlight Award.
Back end
А вот тут как раз начинается самое интересное. То, что скрыто от глаз обычных пользователей; то, о чем даже не хотят ничего знать менеджеры; то место, где воплощаются самые чудовищные фантазии наших разработчиков — внутренняя логика обработки платежей и оказания сервисов
Здесь тестируется просто уйма всевозможных вещей.
- Обращения к партнерским системам: проверка статусов подписок (иногда мы никак не можем управлять ими со своей стороны, и остается только проверять, что они всё еще активны), запросы на обновления и отмены подписок и многое другое.
- Обработка нотификаций от партнеров: мы должны правильно обработать каждую нотификацию (а ведь у каждого партнера свой собственный формат и протокол!), определить юзера, сервис и все возможные параметры, чтобы ничего не перепутать. Иногда нотификации вообще ничего не значат:»Смотрите, мы всё еще не смогли списать деньги с пользователя!»;, иногда они противоречат сами себе:»Пользователь отменил платеж :(А нет, вот и деньги пришли! »; иногда они совершенно не актуальны:»Помните ту подписку три года назад? Так вот, она все еще истекла! » — и мы должны придумать правильный «флоу» для каждого возможного случая.
- Оказание услуг: чтобы не потерять в случае проблем заказы пользователей, услуги оказываются через очереди. Если что-то пошло не так — событие откладывается, и любая услуга в любом случае должна быть доставлена до пользователя. Вот это «в любом случае» мы и должны гарантировать при тестировании.
- Обновление подписок: если пользователь подписан на определенные услуги, он должен их получать вовремя. Мы не должны «чарджить» его раньше (или позже) времени, с него всегда должна списываться именно та сумма, на которую он подписывался. Кроме того, у нас существует много разной логики выбора времени обновления подписок в разных странах (либо это наши эксперименты, либо требования регуляторов). Например, где-то мы «чарджим» пользователей только в рабочее время, где-то только в определенные дни недели.
- Платежи по имеющимся данным: как и в любой уважающей себя платежной системе, у нас пользователь может сохранить детали своего платежного метода для того и в следующий раз платить быстрее. Мы должны проверять, что детали хранятся безопасно (для банковских карт, например, нам нужно соблюдать PCI DSS), что платежи проходят и корректно обрабатываются случаи, когда детали более не валидны (например, карточка пользователя заблокирована).
- И так далее, и тому подобное.
Количество различной логики в серверном коде просто безгранично. Каждая новая задачка превращается в занимательный квест вида «Разберись, как оно работает => Разберись, как оно ДОЛЖНО работать => Разберись, как заставить систему так работать». Какими способами этого нужно добиваться?
Во-первых, нужно читать код. Тестировать биллинг как черный ящик практически невозможно: только имея представление о том, как работает система, можно понять, какие кейсы здесь можно протестировать. Кроме того, очень часто для успешного тестирования нужно делать изменения в коде: убирать обращения к агрегаторам (чтобы мы не спрашивали у них статус несуществующей тестовой подписки), подменять проверку подписи для нотификаций (чтобы не нужно было каждый раз ее генерировать) или «хардкодить» выбор определенного варианта в A/B тесте (чтобы не регистрировать десятки пользователей, попадающих в нужные группы). К счастью, мы всеми силами развиваем тестировочные утилиты, чтобы эти процессы упростить.
Во-вторых, нужно не бояться тестировать вещи неочевидными способами. Нельзя наверняка воспроизвести кейс из интерфейса? Можно написать функциональный тест! Можно полезть в тестовую базу «ручками» и заполнить нужные данные! Можно собрать нотификацию от партнера вручную и отправить ее на собственный адрес! Главное — не бояться забираться в дебри.
В-третьих, разработчик — ваш друг. Совместный занимательный дебаг — увлекательное (не всегда) и сплачивающее команду (кроме случаев, когда ты хочешь придушить девелопера) дело. Вместе разобраться с неожиданным поведением куда проще. И вы либо поймете свои ошибки и оправдаете задачу, либо найдете настоящую проблему и позволите девелоперу вернуться к ее доработке, уже имея какое-то представление о ситуации (или разобраться в ситуации новому девелоперу, если старый отправился в отпуск).
Автоматическое тестирование
Автотесты — это очень классная вещь. И на самом деле перетестировать тут куда лучше, чем недотестировать. Непосредственно у нас все автотесты можно поделить на четыре группы:
- юнит-тесты: пишутся разработчиками во время работы над задачей. В нашем процессе задача не считается решенной, пока она не покрыта тестами;
- интеграционные тесты: пишутся разработчиками (и иногда тестировщиками) на этапе тестирования для проверки трудновоспроизводимых мест. Продолжают подменять часть кода, как и юнит-тесты, но работают с гораздо более широким пластом сущностей одновременно;
- системные Selenium- и Calabash-тесты: тестируют клиент так, как его видит пользователь. Не идеально стабильные, достаточно медленные, но очень полезные, так как позволяют находить еще и проблемы, вызванные задачами других отделов;
- системные curl-тесты: достаточно новое направление. Они проверяют общую работоспособность системы на тысячах различных кейсов: мы получаем платежные визарды всех сервисов, всех их вариантов, в каждой стране мира, на каждом платежном методе. Перетестирование как оно есть.
Когда эти тесты запускаются? В разных комбинациях это происходит постоянно:
- разработчики запускают тесты вручную при работе над задачей;
- они автоматически запускаются при переходе задачи в статус «Готово»;
- QA-инженеры запускают их вручную при тестировании;
- они запускаются каждый раз при сборке каждой новой версии билда;
- в конечном счете они постоянно и регулярно запускаются на препродакшене.
Конечно, все эти автотесты занимают существенное время, и потому мы всегда стремимся максимально оптимизировать этот процесс. Для интеграционных и юнит-тестов (а с недавних пор и для curl-тестов) у нас применяется облачная «пускалка» тестов (уже более 73 тысяч тестов за 4 минуты! ). Для Selenium-тестов у нас трудится «большая ферма» кластера SeleniumGrid. Да и в целом работа по улучшению и оптимизации тестов никогда не прекращается.
Мониторинг
Работа тестировщика над задачей не прекращается сразу же в тот момент, как задача отправляется на продакшен. Убедиться в том, что она выдерживает напряжение работы в боевом окружении, можно только путем внимательного мониторинга. Не появились ли в логах новые неожиданные ошибки (да, ожидаемые ошибки бывают, это нормально)? Не выросла ли нагрузка на биллинговый кластер? Не начала ли падать (или резко расти, что тоже обычно странно) прибыль в какой-нибудь стране или в каком-нибудь платежном методе? В Badoo есть замечательный отдел мониторинга, который круглосуточно следит за всеми метриками в ручном и автоматическом режимах. Однако им в любом случае понадобится какое-то время для того, чтобы самостоятельно выяснить причины тех или иных аномалий. Поэтому QA-инженер обязан внимательно проводить свою задачу в (последний) бой.
Для этих целей мы используем несколько различных систем, важнейшими из которых являются три:
- RRD Tool: в RRD мы храним логи ошибок и дебага, графики огромного множества основных метрик (прибыль, количество платежей, количество оказанных сервисов, размеры очередей);
- Splunk: восхитительная система, с помощью который мы в реальном времени анализируем все биллинговые события, можем строить различные графики о количестве тех или иных запросов к биллингу по времени и многое-многое другое;
- Anomaly Detection: наша собственная система для обнаружения аномалий, автоматически сообщающая о неожиданном поведении той или иной метрики. В отличие от первых двух систем эта работает в полностью автоматическом режиме.
Что же можно считать аномалиями на биллинговых графиках? Давайте посмотрим вот на этот график в Польше. Каждая точка показывает суммарную прибыль за последние сутки, масштаб графика — тоже сутки.
Кошмар, жуткое падение прибыли, надо бить во все колокола! Но что это такое? Открываем график за месяц…
Что за безобразие? Оказывается, так работают мобильные агрегаторы в Польше. Они проводят все обновления подписок только в конкретный день недели, например, во вторник. Если юзер подписался в понедельник на неделю, то… его все равно «зачарджат» во вторник! Такие уж в Польше порядки. И каждый пик — «заветный» день недели того или иного агрегатора.
Смотрим дальше. Аналогичный график прибыли от AppleStore за неделю c 24 числа по 1 число следующего месяца:
Начинаем сразу же пугаться? Конечно! Такое падение, никакого роста за сутки — однозначная проблема! Пока мы сломя голову носимся по офису и вопим, проходят сутки. И что же мы видим?
График восстановился сам собой! Магия? Катастрофические ошибки? Заговор рептилоидов? Вовсе нет, это политика Apple. Они всегда совершают обновления подписок в тот же день месяца, в который подписка была заведена. Но что же происходит в феврале с теми, кто начинал подписки 30 или 31 числа: они счастливо сидят целый месяц бесплатно? Конечно, нет, их «чарджат» 28 февраля. И с тех пор начинают чарджить только 28 числа. Потому на конец месяца приходятся вот эти два пика (28 число для февраля и 30 число для всех остальных «коротких» месяцев), а 31 числа не обновляются вообще никакие подписки со сроком более месяца.
Как видите, мониторить тоже нужно с умом. Как я уже говорил, перетестировать — это не так плохо, но наловить тумаков от разработчиков за излишнее паникерство тоже можно.
Вместо заключения
Тестирование биллинга — интересное и занимательное дело. В нем есть много неординарных вещей, подводных камней и никому толком не известных закоулков, но решение почти каждой задачи — настоящий квест, по завершению которого испытываешь абсолютное ощущение триумфа. Очень жаль, что про эту сферу тестирования говорится не так много (а на конференциях я неоднократно слышал вещи типа «А биллинг мы тестируем на продакшене»). Рассчитываю, что моя статья поможет кому-нибудь иначе взглянуть на процессы тестирования в своей компании и, быть может, решить чуть плотнее тестировать свои платежные системы. Да и вообще любые низкоуровневые вещи. Поверьте мне, это действительно не скучно!
Кудинов Илья, Sr. QA Engineer