Проверка платных сервисов — один из ключевых инженерных вопросов в тестировании Badoo. Наше приложение интегрировано с 70 платёжными провайдерами в 250 странах мира, и баг хотя бы в одном из них может привести к непредсказуемым последствиям.
В этой статье я расскажу о методах тестирования, которые мы используем в Badoo, и о границах применимости этих методов — этапах тестирования, на которых они максимально эффективны.
Статья будет полезна тестировщикам, разработчикам и продакт-менеджерам, чьи проекты уже интегрированы с платёжными провайдерами, или процесс интеграции только начинается. Если в своей работе вы сталкиваетесь с проблемой выбора методов тестирования таких интеграций, добро пожаловать под кат!
![](https://habrastorage.org/r/w780q1/webt/u0/dg/6k/u0dg6kdremnwjnqjqiabc_wq1m8.jpeg)
Меня зовут Владимир Солодов, я Billing QA Engineer в Badoo: занимаюсь проверкой тестовых интеграций и процессинга платежей. В подготовке текста мне помогал мой коллега Виктор Короневич: вместе с ним мы делали доклад на конференции Heisenbug (видео). В статье мы расширили область описания на все интеграции с платёжными провайдерами, которые используются в Badoo, подробнее классифицировали и описали практики удаления внешних зависимостей.
На примере бизнес-кейсов я расскажу, почему следует внимательнее относиться к тестированию платных сервисов и как не усугубить проблемы, если они всё-таки возникли. А затем перейдем к описанию технических проблем тестирования интеграций и путям их решения.
Вторая часть статьи, в которой мы рассказываем подробнее об автоматизации тестирования платных сервисов в iOS-приложениях — здесь.
Поехали!
Обычно целью бизнеса является получение дохода. В Badoo, социальной сети для знакомств, доход приносят кредиты и премиум-подписки. Кредиты — это внутренняя валюта Badoo. С их помощью, например, можно поднять свой профиль в результатах поиска на первое место, сделать подарок другому пользователю и прочее. Премиум-подписка действует определённый период времени и даёт сразу несколько возможностей: включить режим «невидимки», видеть людей, проявивших к тебе интерес, подтвердить подлинность своего аккаунта и многое другое.
Чтобы эти платные сервисы работали, мы используем интеграции с более чем 70 платёжными провайдерами. Выбор провайдера зависит от платформы, страны, девайса, мобильного оператора и других факторов. Поэтому вопрос тестирования платных сервисов у нас стоит очень остро.
Для начала рассмотрим, почему к тестированию платных сервисов необходимо подходить с особым вниманием. Причины две.
Первая проблема — репутационная. Пользователь, заплативший деньги за сервис, становится более чувствительным (и менее терпимым) к багам в приложении. Любой отзыв в публичном пространстве, будь то обзор приложения в блоге или комментарий в App Store или Google Play, от пользователя, столкнувшегося с багом в платном сервисе, будет более эмоциональным — это фактор, который приводит к репутационным потерям.
Вторая проблема заключается в том, что, как только вы начинаете получать деньги от пользователя за сервис, вы становитесь объектом права, защищающего потребителя услуг. И репутационные потери легко могут превратиться в финансовые.
Компании теряют деньги тремя путями.
Путь первый — рефанды (refunds). Предположим, пользователь обнаружил, что вы продали ему сервис, который не совсем соответствует его ожиданиям. В этом случае он обращается в вашу службу поддержки. Её сотрудники проводят расследование и выясняют, что ожидания пользователя действительно не оправдались из-за бага в приложении. Вы инициируете возврат денег. В этом случае имеет место рефанд: в результате компания сталкивается с недополученной прибылью, и это самый безобидный способ потери денег.
Путь второй — чарджбеки (chargebacks). Предположим, произошла та же ситуация, только пользователь обратился не в вашу службу поддержки, а в банк, который выдал ему карту, или к платёжному провайдеру. Банк/провайдер инициирует возврат денег. В этом случае мы имеем дело с чарджбеком. Опасность для бизнеса здесь не только в недополученной прибыли. После определённого количества чарджбеков компания получает штраф, а также снижается её рисковый рейтинг. Снижение рейтинга, в свою очередь, приводит к удорожанию стоимости услуг провайдеров платежей.
Путь третий — судебные иски (claims). В самых запущенных случаях могут иметь место судебные иски (в том числе и коллективные), приводящие к самым серьёзным последствиям. Так, в 2015 году после судебного иска регулятора Ofgem компания British Gas вынуждена была выплатить многомиллионную компенсацию пользователям, с которых взимала повышенную плату вследствие ошибки в системе начисления оплаты. Подробнее об этом можно прочитать здесь.
Команды, только начинающие процесс интеграции с платёжными провайдерами, часто сталкиваются с этой проблемой. Не зная всех возможных кейсов биллинга, они упускают важные нюансы, когда реализуют реакцию системы на нотификации платёжных провайдеров.
Это может привести к непредсказуемым последствиям — от упущенной прибыли до недовольных пользователей.
Давайте обратимся к схеме, на которой перечислены виды платных сервисов, и рассмотрим проблему внимательнее.
![](https://habrastorage.org/r/w780q1/webt/k0/qu/he/k0quhers6cgrorlijjpdjb8pex4.jpeg)
Рисунок 1. Возможные кейсы биллинга
Есть три основных кейса: ошибка, успешный платёж и возврат денег пользователю. Но у каждого кейса есть детали, каждый случай ваша система должна обрабатывать по-разному.
Ошибки могут быть критичными и некритичными. К некритичным можно отнести ошибку нотификации — когда платёжный провайдер информирует о недостатке средств на счёте пользователя, а к критичным — блокировку платёжного метода пользователя. И если в первом случае вы можете попробовать произвести оплату позже, то во втором — неплохо бы разобраться, почему метод заблокирован. Возможно, пользователь был замечен в мошенничестве и вам стоит более внимательно относиться к его транзакциям.
Возвраты. Вы уже знаете, что есть два типа возвратов: рефанды и чарджбеки. Ваша система должна по-разному на них реагировать. Например, после чарджбека имеет смысл задуматься о блокировке для пользователя некоторых функций вашего приложения, потому что чарджбек является одним из популярных методов мошенничества.
Успешный платёж может быть одноразовым, а может быть подпиской.
Одноразовые платежи (one-off payments) могут быть расходуемыми (consumable) и нерасходуемыми (non-consumable). Пример расходуемого платежа мы рассмотрели в самом начале статьи — это кредиты в Badoo. Пример нерасходуемого платежа можно привести из игр. Предположим, у вас есть персонаж, которым вы играете. Вы хотите купить для него суперспособности, которые действуют в течение некоторого времени. В этом случае покупка относится к классу нерасходуемых платежей.
Подписки (subscriptions). Здесь самое большое разнообразие кейсов. Помимо первичной покупки подписки, у вас может быть:
Также нужно принимать во внимание две характеристики, которые полностью зависят от платёжного провайдера: подписка может контролироваться вашим приложением или управляться внешне.
На рисунке фиолетовым цветом выделены наиболее очевидные области, реакция на которые обычно реализуется в первую очередь. Все остальные начинают приниматься во внимание значительно позже, по мере накопления экспертизы. Этому во многом способствует некорректное применение итеративных методологий разработки в области биллинга.
![](https://habrastorage.org/r/w780q1/webt/7x/kf/bj/7xkfbjf-z3shfhzuftrl3p0tms4.jpeg)
Рисунок 2. Кейсы биллинга, которые в первую очередь реализуют в системах
Такая поэтапная реализация может привести к непредсказуемым последствиям. Например, в одном из проектов, которым я занимался до Badoo, не была учтена возможность осуществления возврата денег. В результате все возвраты делались не через рефанды, а через чарджбеки, что негативно отражалось на рисковом рейтинге компании и приводило к сбоям в сборе статистики о доходе. Незнание всего многообразия кейсов биллинга может привести к упущенной прибыли или к уязвимости компании перед пользователями, чувствующими себя обманутыми.
Итак, с одной стороны, баги в процессинге платежей должны быть найдены до релиза, потому что они могут приводить к самым негативным последствиям. Если сделать это не удалось, то важно максимально быстро понять, что баг попал в релизную версию приложения, исправить его и — самое важное, о чём многие забывают, — «успокоить» пользователей, которые столкнулись с этим багом.
С другой стороны, ситуация осложняется тем, что интеграции с платёжными провайдерами — это всегда взаимодействие с «чёрным ящиком», которое добавляет в процесс тестирования множество переменных.
Рассмотрим их на примере интеграции Badoo c App Store.
Подписки на App Store относятся к классу управляемых внешне, то есть управление ими в полном объёме осуществляется на стороне провайдера, а наша система может только запросить актуальное состояние или получить нотификацию о его изменении.
Мы специально выбрали именно эту интеграцию, поскольку она наиболее сложная и содержит всё многообразие кейсов, которые можно встретить в процессе интеграции сервиса с другими платёжными провайдерами.
Для начала обратимся к одноразовой расходуемой покупке.
![](https://habrastorage.org/r/w1560/webt/ob/xi/rd/obxirdlzjhofj6uvioqwixp-r2k.png)
Рисунок 3. Процесс осуществления одноразового расходуемого платежа
На шаге 1 пользователь делает запрос на покупку сервиса. Приложение решает, что должна быть произведена оплата, и на шаге 2 управление передаётся платёжному провайдеру (App Store). Шаг 3: пользователю предоставляется форма для совершения платежа. Шаг 4: пользователь предоставляет данные для оплаты. Шаг 5: провайдер выполняет транзакцию и сообщает о результате приложению, возвращая чек (receipt), содержащий полную информацию о покупке (дата, сервис, статус и прочее). Шаг 6: чек, дополненный данными о пользователе, отправляется на сервер для обработки. Сервер обрабатывает данные чека и формирует пуш-уведомление для приложения на седьмом шаге. На восьмом шаге уведомление показывается пользователю.
Проблема в том, что шаги 3, 4 и 5 выполняются на стороне платёжного провайдера, практически не контролируются нами и могут иметь различные вариации. Таким образом, процесс имеет на самом деле не линейную структуру, как показано на рисунке 2, а ветвящуюся (см. рис. 4), и каждая ветка должна быть обработана приложением по-разному.
![](https://habrastorage.org/r/w1560/webt/8h/ur/mv/8hurmv5_d6mact7vy90jcdb9s_i.png)
Рисунок 4. Ветвление схемы состояний одноразового платежа
Покупка подписок начинается так же, как одноразовый платёж, но дальнейшее управление процессом проконтролировать довольно трудно.
![](https://habrastorage.org/r/w1560/webt/lj/di/eb/ljdiebqce8tfo236xv8gir0jaa4.png)
Рисунок 5. Состояния управляемой внешне подписки
Напомню, что подписка Apple, которую мы рассматриваем в качестве примера, является управляемой внешне. Это означает, что пользователь после покупки может управлять ею асинхронно: закрыть, изменить срок действия, запросить возврат средств. Мы видим это на шаге 9. Поскольку действие происходит вне нашей системы, на рисунке я обозначил его пунктиром.
На шаге 10 App Store может изменить статус подписки: продлить, закрыть, ввести в окно грейс-периода.
Чтобы мы могли узнать, в каком состоянии находится подписка, есть шаг 11, который специфичен для таких агрегаторов, как App Store и Google Wallet. На этом шаге система отправляет токен, в качестве которого используется чек (receipt), полученный в самом начале при покупке подписки или после её предыдущего продления.
Шаг 12 — это ответ провайдера. Мы получаем чек с актуальным состоянием подписки. Результат на этом шаге зависит от асинхронных шагов 9 и 10.
Осенью 2018 года Apple для всех реализовала механизм межсерверных (server-to-server) нотификаций, который позволяет уведомлять об изменениях, произошедших с подпиской. Получение такой нотификации отображено на шаге 13. Для большинства других провайдеров механизм нотификаций server-to-server является единственным, поэтому можно утверждать, что пример с Apple покрывает всё многообразие кейсов. В случае с другими провайдерами шаг 13 позволяет исключить из схемы шаги 11 и 12.
На шаге 14 сервер формирует реакцию для приложения на изменение состояния подписки.
Таким образом, мы получили полный граф состояний, которые необходимо пройти, чтобы проверить платные сервисы.
![](https://habrastorage.org/r/w1560/webt/tg/he/vx/tghevxtlppxvc9xuqt4wczbav0s.png)
Рисунок 6. Полный процесс изменения состояний платежей (на примере управляемой внешне подписки)
Оранжевым цветом окрашены части, которые мы не контролируем в нашей системе, и они являются черными ящиками для нас.
Итак, основной технической проблемой при тестировании платных сервисов является наличие «чёрных ящиков», состояния которых мы очень слабо контролируем. Это определяет набор методов, которыми можно покрыть всё многообразие кейсов.
Этих методов не так много, и мы разделили их на три категории: реальные платежи, песочницы и устранение внешних зависимостей от «чёрных ящиков».
Реальные платежи в качестве тестового метода хороши тем, что они дают чёткое представление о состоянии интеграции. Ошибка при совершении реального платежа — это безусловное свидетельство наличия бага.
В остальном реальные платежи плохи. Во-первых, это дорого: очевидно, что для того чтобы совершить реальный платёж, нужно потратить реальные деньги. Вы ошибаетесь, если думаете, что в конечном итоге вся сумма вернётся в компанию: во-первых, провайдеры берут комиссию с каждой транзакции, размер которой, как было описано выше, зависит от рискового рейтинга организации и может достигать 40% (и даже больше); во-вторых, вы можете потерять деньги при тестировании платежей в других странах из-за валютного спреда — разницы между курсами покупки и продажи валюты (покупку вы будете делать по курсу банка на продажу валюты, а возврат придёт по курсу покупки).
Кроме того, этот способ может занять продолжительное время, потому что вам придётся ждать окончания срока обновления подписок, завершения грейс-периодов, а это могут быть месяцы.
Песочницы прекрасны. Это, по сути, та же функциональность, которую нам даёт платёжный провайдер в случае с реальным платежом, но без траты реальных денег. Она полностью поддерживается провайдером, а это означает, что интеграция с песочницей обходится дешево.
Проблема растянутости тестирования во времени решается, как правило, использованием различных ухищрений. Например, в песочнице App Store используется следующее преобразование срока действия подписок.
Таблица 1. Соотношение сроков действия реальной подписки и подписки в песочнице Apple
Срок действия подписок в песочнице Google Wallet, принятый по умолчанию, приведён в таблице 2, и он может настраиваться в консоли продавца.
Таблица 2. Настройка срока действия подписки в песочнице Google
В отличие от песочницы Apple, в песочнице Google можно также проверить триал, грейс-период и т. д., используя соотношение из таблицы 3.
Таблица 3. Срок действия дополнительных функций подписки в песочнице Google
Закрытие подписки тоже может быть реализовано по-разному: в песочнице App Store закрытие выполняется после пятого продления, а в Google Wallet оно выполняется из консоли продавца или на девайсе из Play Store.
Проблема песочниц в том, что провайдеры по-разному относятся к их качеству. Наш опыт показывает, что из более чем 70 платёжных провайдеров, которые интегрированы в Badoo, только две песочницы могут похвастаться полной функциональностью и стабильной работой. Это песочницы Adyen и PayPal. Остальные провайдеры имеют либо стабильные, но урезанные в плане функциональности песочницы (как Google Wallet), либо нестабильные и сильно урезанные в функциональности (как App Store и Fortumo). А есть провайдеры, которые вообще не имеют и не собираются иметь песочницу.
![](https://habrastorage.org/r/w1560/webt/iz/as/im/izasimha0d95e0w214ym9kyfhcy.png)
Рисунок 7. Классификация песочниц по стабильности и функциональности
Если мы убедили вас в том, что тестирование с использованием реальных платежей — это дорого и неэффективно, а платёжные провайдеры не предоставляют песочницы должного качества, то остаётся обратиться к различным способам устранения внешних зависимостей. Их всего три: моки, фейки и стабы.
Моки в биллинге — это формирование реакций вашей системы на запросы с заранее определёнными параметрами без реального обращения к платёжному провайдеру (см. рис. 8). Например, запрос к провайдеру СМС-платежей на номер +7111-111-11-11 перехватывается на этапе отправки запроса к провайдеру и формирует реакцию системы в виде успешного платежа. Запрос на номер +7111-111-11-12 также перехватывается, но приводит к реакции на ошибку с кодом «Не хватает средств для проведения транзакции».
![](https://habrastorage.org/r/w1560/webt/cb/zi/xy/cbzixy8v5c16-fjdnobzksxoij4.png)
Рисунок 8. Схема мока
Фейки в биллинге — это подделки нотификаций (как будто они приходят от реального провайдера) (см. рис. 9). Интеграция с каждым провайдером предполагает ограниченный набор реакций системы на ограниченный набор типов нотификаций или реситов. На основе этой информации для каждого отдельного платежа можно сформировать набор нотификаций (с подписями и прочими фейковыми атрибутами безопасности), которые наша система будет считать реальными нотификациями от платёжного провайдера.
![](https://habrastorage.org/r/w1560/webt/t5/nz/_h/t5nz_hwuq-49im9ow_csqennjh4.png)
Рисунок 9. Схема фейка
Стабы в биллинге — это редирект на страницу со списком возможных реакций системы вместо отправки и обработки запроса (см. рис. 10), когда мы предоставляем все возможные реакции платёжного провайдера для текущего состояния платежа и вызываем эту реакцию вместо отправки запроса к реальному провайдеру или песочнице.
![](https://habrastorage.org/r/w1560/webt/-z/3p/f8/-z3pf8attjz-fiitaqbanlhmbbe.png)
Рисунок 10. Схема стаба
Все эти методы позволяют избежать траты реальных денег и времени, но назвать их совсем дешёвыми нельзя, потому что для их применения необходимо составить карты всех возможных состояний биллинга для каждого провайдера и поддерживать их в актуальном состоянии. Также для использования всех методов (кроме, пожалуй, фейка) требуется внести существенные изменения в код. Кроме того, являясь различными вариантами моделирования реального платежа, моки, стабы и фейки имеют определённую степень приближения к реальности и риски при использовании, которые необходимо учитывать.
Вернёмся к процессу осуществления одноразового платежа. Шаги 3, 4, 5 являются ключевыми для интеграции: передача управления платёжному провайдеру, отправка запроса провайдеру и получение ответа. При использовании каждого из рассматриваемых способов устранения внешних зависимостей фокус направлен на какие-то из этих шагов: при использовании мока мы моделируем передачу управления и отправку запроса, при использовании стаба — только передачу управления, при использовании фейка — получение ответа. Остальные шаги при этом «выносятся за скобки».
![](https://habrastorage.org/r/w1560/webt/2p/cu/w-/2pcuw-rvhju4ngyzr3ez7rqlhco.png)
Рисунок 11. Моделирование взаимодействия приложения с провайдером при разных методах устранения внешней зависимости (на примере одноразовой покупки в App Store)
С одной стороны, такое устранение шагов приводит к рискам (например, можно пропустить баг в нетестируемых шагах). С другой — моделирование каждого шага делает метод дороже, поскольку требует изменений в системе. Поэтому на практике мы используем комбинации методов. Например, моки и фейки, когда при отправке запроса на определённый номер не формируется реакция системы, а отправляется фейковая нотификация на точку входа для нотификаций на нашем сервере. Или стабы и фейки, когда при выборе реакции из стаба также отправляется фейковая нотификация. Естественно, подобные реализации должны быть ограничены окружениями для разработчиков и не должны попадать на прод.
Все описанные методы не являются панацеей. Как же понять, в какой момент лучше использовать тот или иной из них? Для этого предлагаем оценить их по следующим критериям:
Результаты оценки мы свели в таблицу.
![](https://habrastorage.org/r/w1560/webt/ck/sn/re/cksnrehqrplo3q14juwsyrar31m.png)
Таблица 4. Сравнительная характеристика методов тестирования биллинга
Реальный платёж. Довольно ограниченное количество кейсов. Годовую подписку нужно тестировать год. Но зато это единственный метод, который позволяет тестировать весь процесс интеграции. Он довольно дорогой: мы постоянно тратим реальные деньги, оплачивая транзакции провайдерам.
Песочница. Песочницы, например, у Apple и Google, отличаются. Поэтому ими можно покрыть разное количество кейсов (и точно не все). Песочница не предоставляет возможности полноценного end-to-end тестирования: даже код в самой песочнице может отличаться от кода на проде. Однако это, пожалуй, самый дешёвый метод.
Фейки, моки, стабы — самый гибкий метод. Мы можем покрыть весь набор кейсов. В силу специфики этого метода мы не тестируем весь процесс платежа целиком. Метод недёшев: нужно писать код и поддерживать его в актуальном состоянии.
Для того чтобы определить, какой из методов на каком этапе использовать, обратимся к классической пирамиде тестирования.
Внизу пирамиды находится большое количество тестов, которые должны полностью покрывать всю функциональность нашей системы. Это должны быть очень маленькие кейсы и достаточно дешёвые.
Наверху пирамиды покрытие может быть неполным: это могут быть дорогие кейсы. Основная проверка, которую мы хотим осуществить здесь, — это проверка полного пути нашего сервиса от запроса до доставки его пользователю.
Если мы соотнесём это с критериями оценки методов тестирования, то получим такое соотношение: для тестов внизу пирамиды — фейки, моки, стабы; для тестов вверху пирамиды — ориентированные на интеграцию методы: реальный платёж и песочница.
![](https://habrastorage.org/r/w780q1/webt/hc/rg/ka/hcrgka-jxqtj6rftvexttwrlvqw.jpeg)
Рисунок 12. Соотношение этапов и методов тестирования на пирамиде тестирования
Информацию о том, что бывает, если нарушается соотношение тестов в пирамиде тестирования, можно найти в большом количестве статей, например в этой.
Давайте рассмотрим примеры трёх антипаттернов тестирования, не соответствующих соотношению на рисунке 12, с которыми мы столкнулись в Badoo.
Для тестирования с использованием реальных платежей была заведена специальная карта. Она была доступна только узкому кругу лиц. Но однажды один QA-инженер из нашей команды узнал её данные. Имея благие намерения, он решил реализовать автотесты. Естественно, в какой-то момент банк увидел, что в течение очень короткого промежутка времени ему поступают запросы на несколько тысяч платежей, и заблокировал карту. Причём заблокировал так, что мы не могли разблокировать её примерно две недели.
Вывод такой: не нужно использовать реальные платежи везде.
Первая проблема, возникающая при избыточной зависимости от песочниц, — это сбои в их работе. Например, для тестирования платежей Apple песочница долгое время оставалась единственным способом. В итоге мы столкнулись с последствиями её нестабильной работы. Было два случая, когда песочница не работала вообще. Она не работала в течение двух недель: в итоге четыре релиза клиентского приложения мы вынуждены были выпускать без какого-то адекватного тестирования.
Вторая проблема — ограничения, которые имеют песочницы. Во-первых, это сложности с изменением срока действия подписки. Во-вторых, это отсутствие таких фич, как грейс-период, рефанды и прочих, то есть часть функциональности оказывается вообще никак не покрыта тестами.
Последствия использования песочниц внизу пирамиды — появление различных инфраструктурных проблем: при использовании одного и того же аккаунта в песочнице для большого количества платежей размер передаваемого ресита или нотификации может возрастать, потому что Apple накапливает историю покупок. Для одного из пользователей ресит достиг 1 Гб — естественно, тестовый стенд просто не выдержал передачи такого объёма данных.
Для одного из платёжных провайдеров мы использовали только комбинацию моков и фейков. В итоге для одного из операторов был изменён формат нотификаций, а тест при этом давал ложноположительные результаты. Проблема провайдера заключалась в невозможности осуществить реальный платёж, поскольку для этого требовалась сим-карта определённого оператора другой страны.
В подобных случаях необходимо выполнять оценку рисков устранения внешних зависимостей, важно отслеживать реальные нотификации и проверять их на соответствие шаблону или схеме (в случае несоответствия такие нотификации должны исследоваться отдельно).
О том, как нам удалось добиться стабильной и недорогой автоматизации тестирования платных сервисов в iOS-приложении, мы рассказываем в следующей статье.
Спасибо за внимание! Всем большой прибыли и меньше багов!
В этой статье я расскажу о методах тестирования, которые мы используем в Badoo, и о границах применимости этих методов — этапах тестирования, на которых они максимально эффективны.
Статья будет полезна тестировщикам, разработчикам и продакт-менеджерам, чьи проекты уже интегрированы с платёжными провайдерами, или процесс интеграции только начинается. Если в своей работе вы сталкиваетесь с проблемой выбора методов тестирования таких интеграций, добро пожаловать под кат!
![](https://habrastorage.org/webt/u0/dg/6k/u0dg6kdremnwjnqjqiabc_wq1m8.jpeg)
Меня зовут Владимир Солодов, я Billing QA Engineer в Badoo: занимаюсь проверкой тестовых интеграций и процессинга платежей. В подготовке текста мне помогал мой коллега Виктор Короневич: вместе с ним мы делали доклад на конференции Heisenbug (видео). В статье мы расширили область описания на все интеграции с платёжными провайдерами, которые используются в Badoo, подробнее классифицировали и описали практики удаления внешних зависимостей.
На примере бизнес-кейсов я расскажу, почему следует внимательнее относиться к тестированию платных сервисов и как не усугубить проблемы, если они всё-таки возникли. А затем перейдем к описанию технических проблем тестирования интеграций и путям их решения.
Вторая часть статьи, в которой мы рассказываем подробнее об автоматизации тестирования платных сервисов в iOS-приложениях — здесь.
Поехали!
Специфика тестирования биллинга
Обычно целью бизнеса является получение дохода. В Badoo, социальной сети для знакомств, доход приносят кредиты и премиум-подписки. Кредиты — это внутренняя валюта Badoo. С их помощью, например, можно поднять свой профиль в результатах поиска на первое место, сделать подарок другому пользователю и прочее. Премиум-подписка действует определённый период времени и даёт сразу несколько возможностей: включить режим «невидимки», видеть людей, проявивших к тебе интерес, подтвердить подлинность своего аккаунта и многое другое.
Чтобы эти платные сервисы работали, мы используем интеграции с более чем 70 платёжными провайдерами. Выбор провайдера зависит от платформы, страны, девайса, мобильного оператора и других факторов. Поэтому вопрос тестирования платных сервисов у нас стоит очень остро.
Для начала рассмотрим, почему к тестированию платных сервисов необходимо подходить с особым вниманием. Причины две.
1. Баги в биллинге критичны для бизнеса.
Первая проблема — репутационная. Пользователь, заплативший деньги за сервис, становится более чувствительным (и менее терпимым) к багам в приложении. Любой отзыв в публичном пространстве, будь то обзор приложения в блоге или комментарий в App Store или Google Play, от пользователя, столкнувшегося с багом в платном сервисе, будет более эмоциональным — это фактор, который приводит к репутационным потерям.
Вторая проблема заключается в том, что, как только вы начинаете получать деньги от пользователя за сервис, вы становитесь объектом права, защищающего потребителя услуг. И репутационные потери легко могут превратиться в финансовые.
Компании теряют деньги тремя путями.
Путь первый — рефанды (refunds). Предположим, пользователь обнаружил, что вы продали ему сервис, который не совсем соответствует его ожиданиям. В этом случае он обращается в вашу службу поддержки. Её сотрудники проводят расследование и выясняют, что ожидания пользователя действительно не оправдались из-за бага в приложении. Вы инициируете возврат денег. В этом случае имеет место рефанд: в результате компания сталкивается с недополученной прибылью, и это самый безобидный способ потери денег.
Путь второй — чарджбеки (chargebacks). Предположим, произошла та же ситуация, только пользователь обратился не в вашу службу поддержки, а в банк, который выдал ему карту, или к платёжному провайдеру. Банк/провайдер инициирует возврат денег. В этом случае мы имеем дело с чарджбеком. Опасность для бизнеса здесь не только в недополученной прибыли. После определённого количества чарджбеков компания получает штраф, а также снижается её рисковый рейтинг. Снижение рейтинга, в свою очередь, приводит к удорожанию стоимости услуг провайдеров платежей.
Путь третий — судебные иски (claims). В самых запущенных случаях могут иметь место судебные иски (в том числе и коллективные), приводящие к самым серьёзным последствиям. Так, в 2015 году после судебного иска регулятора Ofgem компания British Gas вынуждена была выплатить многомиллионную компенсацию пользователям, с которых взимала повышенную плату вследствие ошибки в системе начисления оплаты. Подробнее об этом можно прочитать здесь.
2. Для тестирования интеграций нужны знания и экспертиза.
Команды, только начинающие процесс интеграции с платёжными провайдерами, часто сталкиваются с этой проблемой. Не зная всех возможных кейсов биллинга, они упускают важные нюансы, когда реализуют реакцию системы на нотификации платёжных провайдеров.
Это может привести к непредсказуемым последствиям — от упущенной прибыли до недовольных пользователей.
Давайте обратимся к схеме, на которой перечислены виды платных сервисов, и рассмотрим проблему внимательнее.
![](https://habrastorage.org/webt/k0/qu/he/k0quhers6cgrorlijjpdjb8pex4.jpeg)
Рисунок 1. Возможные кейсы биллинга
Есть три основных кейса: ошибка, успешный платёж и возврат денег пользователю. Но у каждого кейса есть детали, каждый случай ваша система должна обрабатывать по-разному.
Ошибки могут быть критичными и некритичными. К некритичным можно отнести ошибку нотификации — когда платёжный провайдер информирует о недостатке средств на счёте пользователя, а к критичным — блокировку платёжного метода пользователя. И если в первом случае вы можете попробовать произвести оплату позже, то во втором — неплохо бы разобраться, почему метод заблокирован. Возможно, пользователь был замечен в мошенничестве и вам стоит более внимательно относиться к его транзакциям.
Возвраты. Вы уже знаете, что есть два типа возвратов: рефанды и чарджбеки. Ваша система должна по-разному на них реагировать. Например, после чарджбека имеет смысл задуматься о блокировке для пользователя некоторых функций вашего приложения, потому что чарджбек является одним из популярных методов мошенничества.
Успешный платёж может быть одноразовым, а может быть подпиской.
Одноразовые платежи (one-off payments) могут быть расходуемыми (consumable) и нерасходуемыми (non-consumable). Пример расходуемого платежа мы рассмотрели в самом начале статьи — это кредиты в Badoo. Пример нерасходуемого платежа можно привести из игр. Предположим, у вас есть персонаж, которым вы играете. Вы хотите купить для него суперспособности, которые действуют в течение некоторого времени. В этом случае покупка относится к классу нерасходуемых платежей.
Подписки (subscriptions). Здесь самое большое разнообразие кейсов. Помимо первичной покупки подписки, у вас может быть:
- продление подписки (renew);
- закрытие подписки (cancel subscription);
- пробная подписка (trial);
- подписка с грейс-периодом (grace period): когда мы не можем продлить подписку и пытаемся произвести оплату повторно в течение какого-то периода времени, называемого грейс-периодом. Для пользователя грейс-период выглядит так. Предположим, вы купили месячную подписку на газету. Компания, которая присылает вам газеты, пытается списать оплату за следующий месяц подписки по окончании первого месяца, но не может этого сделать (из-за блокировки карты, недостатка средств на счёте и пр.). Если срок действия грейс-периода составляет десять дней, то в течение этого времени компания пытается списать оплату, подписка при этом остаётся действующей. Если у компании не получается списать деньги, подписка аннулируется. Если получается, подписка возобновляется с даты последнего платежа;
- частичная оплата (partial billing). Например, PayPal позволяет производить частичную оплату, если на счёте пользователя недостаточно средств (partial pay), или разбивать платёж на части (partial invoice).
Также нужно принимать во внимание две характеристики, которые полностью зависят от платёжного провайдера: подписка может контролироваться вашим приложением или управляться внешне.
- Управляемая (internally managed) подписка — это, например, подписка с использованием кредитных карт или PayPal, когда после первой оплаты вам выдаётся токен, с использованием которого вы повторно обращаетесь к провайдеру, при этом не имея платёжных деталей пользователя.
- Управляемая внешне (externally managed) подписка — это когда платёжный агрегатор полностью берёт на себя управление вашими подписками и просто присылает вам нотификации об их текущих состояниях.
На рисунке фиолетовым цветом выделены наиболее очевидные области, реакция на которые обычно реализуется в первую очередь. Все остальные начинают приниматься во внимание значительно позже, по мере накопления экспертизы. Этому во многом способствует некорректное применение итеративных методологий разработки в области биллинга.
![](https://habrastorage.org/webt/7x/kf/bj/7xkfbjf-z3shfhzuftrl3p0tms4.jpeg)
Рисунок 2. Кейсы биллинга, которые в первую очередь реализуют в системах
Такая поэтапная реализация может привести к непредсказуемым последствиям. Например, в одном из проектов, которым я занимался до Badoo, не была учтена возможность осуществления возврата денег. В результате все возвраты делались не через рефанды, а через чарджбеки, что негативно отражалось на рисковом рейтинге компании и приводило к сбоям в сборе статистики о доходе. Незнание всего многообразия кейсов биллинга может привести к упущенной прибыли или к уязвимости компании перед пользователями, чувствующими себя обманутыми.
Итак, с одной стороны, баги в процессинге платежей должны быть найдены до релиза, потому что они могут приводить к самым негативным последствиям. Если сделать это не удалось, то важно максимально быстро понять, что баг попал в релизную версию приложения, исправить его и — самое важное, о чём многие забывают, — «успокоить» пользователей, которые столкнулись с этим багом.
С другой стороны, ситуация осложняется тем, что интеграции с платёжными провайдерами — это всегда взаимодействие с «чёрным ящиком», которое добавляет в процесс тестирования множество переменных.
Технические проблемы в процессе тестирования биллинга
Рассмотрим их на примере интеграции Badoo c App Store.
Подписки на App Store относятся к классу управляемых внешне, то есть управление ими в полном объёме осуществляется на стороне провайдера, а наша система может только запросить актуальное состояние или получить нотификацию о его изменении.
Мы специально выбрали именно эту интеграцию, поскольку она наиболее сложная и содержит всё многообразие кейсов, которые можно встретить в процессе интеграции сервиса с другими платёжными провайдерами.
Для начала обратимся к одноразовой расходуемой покупке.
![](https://habrastorage.org/webt/ob/xi/rd/obxirdlzjhofj6uvioqwixp-r2k.png)
Рисунок 3. Процесс осуществления одноразового расходуемого платежа
На шаге 1 пользователь делает запрос на покупку сервиса. Приложение решает, что должна быть произведена оплата, и на шаге 2 управление передаётся платёжному провайдеру (App Store). Шаг 3: пользователю предоставляется форма для совершения платежа. Шаг 4: пользователь предоставляет данные для оплаты. Шаг 5: провайдер выполняет транзакцию и сообщает о результате приложению, возвращая чек (receipt), содержащий полную информацию о покупке (дата, сервис, статус и прочее). Шаг 6: чек, дополненный данными о пользователе, отправляется на сервер для обработки. Сервер обрабатывает данные чека и формирует пуш-уведомление для приложения на седьмом шаге. На восьмом шаге уведомление показывается пользователю.
Проблема в том, что шаги 3, 4 и 5 выполняются на стороне платёжного провайдера, практически не контролируются нами и могут иметь различные вариации. Таким образом, процесс имеет на самом деле не линейную структуру, как показано на рисунке 2, а ветвящуюся (см. рис. 4), и каждая ветка должна быть обработана приложением по-разному.
![](https://habrastorage.org/webt/8h/ur/mv/8hurmv5_d6mact7vy90jcdb9s_i.png)
Рисунок 4. Ветвление схемы состояний одноразового платежа
Покупка подписок начинается так же, как одноразовый платёж, но дальнейшее управление процессом проконтролировать довольно трудно.
![](https://habrastorage.org/webt/lj/di/eb/ljdiebqce8tfo236xv8gir0jaa4.png)
Рисунок 5. Состояния управляемой внешне подписки
Напомню, что подписка Apple, которую мы рассматриваем в качестве примера, является управляемой внешне. Это означает, что пользователь после покупки может управлять ею асинхронно: закрыть, изменить срок действия, запросить возврат средств. Мы видим это на шаге 9. Поскольку действие происходит вне нашей системы, на рисунке я обозначил его пунктиром.
На шаге 10 App Store может изменить статус подписки: продлить, закрыть, ввести в окно грейс-периода.
Чтобы мы могли узнать, в каком состоянии находится подписка, есть шаг 11, который специфичен для таких агрегаторов, как App Store и Google Wallet. На этом шаге система отправляет токен, в качестве которого используется чек (receipt), полученный в самом начале при покупке подписки или после её предыдущего продления.
Шаг 12 — это ответ провайдера. Мы получаем чек с актуальным состоянием подписки. Результат на этом шаге зависит от асинхронных шагов 9 и 10.
Осенью 2018 года Apple для всех реализовала механизм межсерверных (server-to-server) нотификаций, который позволяет уведомлять об изменениях, произошедших с подпиской. Получение такой нотификации отображено на шаге 13. Для большинства других провайдеров механизм нотификаций server-to-server является единственным, поэтому можно утверждать, что пример с Apple покрывает всё многообразие кейсов. В случае с другими провайдерами шаг 13 позволяет исключить из схемы шаги 11 и 12.
На шаге 14 сервер формирует реакцию для приложения на изменение состояния подписки.
Таким образом, мы получили полный граф состояний, которые необходимо пройти, чтобы проверить платные сервисы.
![](https://habrastorage.org/webt/tg/he/vx/tghevxtlppxvc9xuqt4wczbav0s.png)
Рисунок 6. Полный процесс изменения состояний платежей (на примере управляемой внешне подписки)
Оранжевым цветом окрашены части, которые мы не контролируем в нашей системе, и они являются черными ящиками для нас.
Методы тестирования биллинга
Итак, основной технической проблемой при тестировании платных сервисов является наличие «чёрных ящиков», состояния которых мы очень слабо контролируем. Это определяет набор методов, которыми можно покрыть всё многообразие кейсов.
Этих методов не так много, и мы разделили их на три категории: реальные платежи, песочницы и устранение внешних зависимостей от «чёрных ящиков».
Реальные платежи
Реальные платежи в качестве тестового метода хороши тем, что они дают чёткое представление о состоянии интеграции. Ошибка при совершении реального платежа — это безусловное свидетельство наличия бага.
В остальном реальные платежи плохи. Во-первых, это дорого: очевидно, что для того чтобы совершить реальный платёж, нужно потратить реальные деньги. Вы ошибаетесь, если думаете, что в конечном итоге вся сумма вернётся в компанию: во-первых, провайдеры берут комиссию с каждой транзакции, размер которой, как было описано выше, зависит от рискового рейтинга организации и может достигать 40% (и даже больше); во-вторых, вы можете потерять деньги при тестировании платежей в других странах из-за валютного спреда — разницы между курсами покупки и продажи валюты (покупку вы будете делать по курсу банка на продажу валюты, а возврат придёт по курсу покупки).
Кроме того, этот способ может занять продолжительное время, потому что вам придётся ждать окончания срока обновления подписок, завершения грейс-периодов, а это могут быть месяцы.
Песочницы
Песочницы прекрасны. Это, по сути, та же функциональность, которую нам даёт платёжный провайдер в случае с реальным платежом, но без траты реальных денег. Она полностью поддерживается провайдером, а это означает, что интеграция с песочницей обходится дешево.
Проблема растянутости тестирования во времени решается, как правило, использованием различных ухищрений. Например, в песочнице App Store используется следующее преобразование срока действия подписок.
Реальное время подписки |
Время подписки в песочнице Apple |
1 неделя |
3 минуты |
1 месяц |
5 минут |
2 месяца |
10 минут |
3 месяца |
15 минут |
6 месяцев |
30 минут |
1 год |
1 час |
Срок действия подписок в песочнице Google Wallet, принятый по умолчанию, приведён в таблице 2, и он может настраиваться в консоли продавца.
Реальное время подписки |
Время подписки в песочнице Google |
1 неделя |
5 минут |
1 месяц |
5 минут |
3 месяца |
10 минут |
6 месяцев |
15 минут |
1 год |
30 минут |
В отличие от песочницы Apple, в песочнице Google можно также проверить триал, грейс-период и т. д., используя соотношение из таблицы 3.
Реальное время подписки |
Время подписки в песочнице Google |
Пробный период (trial) |
3 минуты |
Ознакомительный период (introductory) |
Равен времени соответствующей подписки |
Грейс-период (3/7 дней) |
5 минут |
Временная блокировка аккаунта (hold) |
10 минут |
Пауза (1/2/3 месяца) |
5/10/15 минут (соответственно) |
Закрытие подписки тоже может быть реализовано по-разному: в песочнице App Store закрытие выполняется после пятого продления, а в Google Wallet оно выполняется из консоли продавца или на девайсе из Play Store.
Проблема песочниц в том, что провайдеры по-разному относятся к их качеству. Наш опыт показывает, что из более чем 70 платёжных провайдеров, которые интегрированы в Badoo, только две песочницы могут похвастаться полной функциональностью и стабильной работой. Это песочницы Adyen и PayPal. Остальные провайдеры имеют либо стабильные, но урезанные в плане функциональности песочницы (как Google Wallet), либо нестабильные и сильно урезанные в функциональности (как App Store и Fortumo). А есть провайдеры, которые вообще не имеют и не собираются иметь песочницу.
![](https://habrastorage.org/webt/iz/as/im/izasimha0d95e0w214ym9kyfhcy.png)
Рисунок 7. Классификация песочниц по стабильности и функциональности
Устранение внешних зависимостей
Если мы убедили вас в том, что тестирование с использованием реальных платежей — это дорого и неэффективно, а платёжные провайдеры не предоставляют песочницы должного качества, то остаётся обратиться к различным способам устранения внешних зависимостей. Их всего три: моки, фейки и стабы.
Моки в биллинге — это формирование реакций вашей системы на запросы с заранее определёнными параметрами без реального обращения к платёжному провайдеру (см. рис. 8). Например, запрос к провайдеру СМС-платежей на номер +7111-111-11-11 перехватывается на этапе отправки запроса к провайдеру и формирует реакцию системы в виде успешного платежа. Запрос на номер +7111-111-11-12 также перехватывается, но приводит к реакции на ошибку с кодом «Не хватает средств для проведения транзакции».
![](https://habrastorage.org/webt/cb/zi/xy/cbzixy8v5c16-fjdnobzksxoij4.png)
Рисунок 8. Схема мока
Фейки в биллинге — это подделки нотификаций (как будто они приходят от реального провайдера) (см. рис. 9). Интеграция с каждым провайдером предполагает ограниченный набор реакций системы на ограниченный набор типов нотификаций или реситов. На основе этой информации для каждого отдельного платежа можно сформировать набор нотификаций (с подписями и прочими фейковыми атрибутами безопасности), которые наша система будет считать реальными нотификациями от платёжного провайдера.
![](https://habrastorage.org/webt/t5/nz/_h/t5nz_hwuq-49im9ow_csqennjh4.png)
Рисунок 9. Схема фейка
Стабы в биллинге — это редирект на страницу со списком возможных реакций системы вместо отправки и обработки запроса (см. рис. 10), когда мы предоставляем все возможные реакции платёжного провайдера для текущего состояния платежа и вызываем эту реакцию вместо отправки запроса к реальному провайдеру или песочнице.
![](https://habrastorage.org/webt/-z/3p/f8/-z3pf8attjz-fiitaqbanlhmbbe.png)
Рисунок 10. Схема стаба
Все эти методы позволяют избежать траты реальных денег и времени, но назвать их совсем дешёвыми нельзя, потому что для их применения необходимо составить карты всех возможных состояний биллинга для каждого провайдера и поддерживать их в актуальном состоянии. Также для использования всех методов (кроме, пожалуй, фейка) требуется внести существенные изменения в код. Кроме того, являясь различными вариантами моделирования реального платежа, моки, стабы и фейки имеют определённую степень приближения к реальности и риски при использовании, которые необходимо учитывать.
Вернёмся к процессу осуществления одноразового платежа. Шаги 3, 4, 5 являются ключевыми для интеграции: передача управления платёжному провайдеру, отправка запроса провайдеру и получение ответа. При использовании каждого из рассматриваемых способов устранения внешних зависимостей фокус направлен на какие-то из этих шагов: при использовании мока мы моделируем передачу управления и отправку запроса, при использовании стаба — только передачу управления, при использовании фейка — получение ответа. Остальные шаги при этом «выносятся за скобки».
![](https://habrastorage.org/webt/2p/cu/w-/2pcuw-rvhju4ngyzr3ez7rqlhco.png)
Рисунок 11. Моделирование взаимодействия приложения с провайдером при разных методах устранения внешней зависимости (на примере одноразовой покупки в App Store)
С одной стороны, такое устранение шагов приводит к рискам (например, можно пропустить баг в нетестируемых шагах). С другой — моделирование каждого шага делает метод дороже, поскольку требует изменений в системе. Поэтому на практике мы используем комбинации методов. Например, моки и фейки, когда при отправке запроса на определённый номер не формируется реакция системы, а отправляется фейковая нотификация на точку входа для нотификаций на нашем сервере. Или стабы и фейки, когда при выборе реакции из стаба также отправляется фейковая нотификация. Естественно, подобные реализации должны быть ограничены окружениями для разработчиков и не должны попадать на прод.
Ограничения методов тестирования биллинга
Все описанные методы не являются панацеей. Как же понять, в какой момент лучше использовать тот или иной из них? Для этого предлагаем оценить их по следующим критериям:
- воспроизводимость и покрытие — какой метод поможет покрыть и воспроизвести как можно больше кейсов?
- возможность проверок end-to-end — что метод делает лучше: позволяет проверить весь процесс осуществления платежа или тщательно и быстро протестировать только какой-то его этап?
- дешевизна — оцените полную стоимость: не только реальные денежные траты, но и расходы на написание и поддержку кода.
Результаты оценки мы свели в таблицу.
![](https://habrastorage.org/webt/ck/sn/re/cksnrehqrplo3q14juwsyrar31m.png)
Таблица 4. Сравнительная характеристика методов тестирования биллинга
Реальный платёж. Довольно ограниченное количество кейсов. Годовую подписку нужно тестировать год. Но зато это единственный метод, который позволяет тестировать весь процесс интеграции. Он довольно дорогой: мы постоянно тратим реальные деньги, оплачивая транзакции провайдерам.
Песочница. Песочницы, например, у Apple и Google, отличаются. Поэтому ими можно покрыть разное количество кейсов (и точно не все). Песочница не предоставляет возможности полноценного end-to-end тестирования: даже код в самой песочнице может отличаться от кода на проде. Однако это, пожалуй, самый дешёвый метод.
Фейки, моки, стабы — самый гибкий метод. Мы можем покрыть весь набор кейсов. В силу специфики этого метода мы не тестируем весь процесс платежа целиком. Метод недёшев: нужно писать код и поддерживать его в актуальном состоянии.
Выбор метода тестирования
Для того чтобы определить, какой из методов на каком этапе использовать, обратимся к классической пирамиде тестирования.
Внизу пирамиды находится большое количество тестов, которые должны полностью покрывать всю функциональность нашей системы. Это должны быть очень маленькие кейсы и достаточно дешёвые.
Наверху пирамиды покрытие может быть неполным: это могут быть дорогие кейсы. Основная проверка, которую мы хотим осуществить здесь, — это проверка полного пути нашего сервиса от запроса до доставки его пользователю.
Если мы соотнесём это с критериями оценки методов тестирования, то получим такое соотношение: для тестов внизу пирамиды — фейки, моки, стабы; для тестов вверху пирамиды — ориентированные на интеграцию методы: реальный платёж и песочница.
![](https://habrastorage.org/webt/hc/rg/ka/hcrgka-jxqtj6rftvexttwrlvqw.jpeg)
Рисунок 12. Соотношение этапов и методов тестирования на пирамиде тестирования
Антипаттерны при выборе метода
Информацию о том, что бывает, если нарушается соотношение тестов в пирамиде тестирования, можно найти в большом количестве статей, например в этой.
Давайте рассмотрим примеры трёх антипаттернов тестирования, не соответствующих соотношению на рисунке 12, с которыми мы столкнулись в Badoo.
Реальные платежи внизу пирамиды
Для тестирования с использованием реальных платежей была заведена специальная карта. Она была доступна только узкому кругу лиц. Но однажды один QA-инженер из нашей команды узнал её данные. Имея благие намерения, он решил реализовать автотесты. Естественно, в какой-то момент банк увидел, что в течение очень короткого промежутка времени ему поступают запросы на несколько тысяч платежей, и заблокировал карту. Причём заблокировал так, что мы не могли разблокировать её примерно две недели.
Вывод такой: не нужно использовать реальные платежи везде.
Песочницы внизу и наверху пирамиды
Первая проблема, возникающая при избыточной зависимости от песочниц, — это сбои в их работе. Например, для тестирования платежей Apple песочница долгое время оставалась единственным способом. В итоге мы столкнулись с последствиями её нестабильной работы. Было два случая, когда песочница не работала вообще. Она не работала в течение двух недель: в итоге четыре релиза клиентского приложения мы вынуждены были выпускать без какого-то адекватного тестирования.
Вторая проблема — ограничения, которые имеют песочницы. Во-первых, это сложности с изменением срока действия подписки. Во-вторых, это отсутствие таких фич, как грейс-период, рефанды и прочих, то есть часть функциональности оказывается вообще никак не покрыта тестами.
Последствия использования песочниц внизу пирамиды — появление различных инфраструктурных проблем: при использовании одного и того же аккаунта в песочнице для большого количества платежей размер передаваемого ресита или нотификации может возрастать, потому что Apple накапливает историю покупок. Для одного из пользователей ресит достиг 1 Гб — естественно, тестовый стенд просто не выдержал передачи такого объёма данных.
Устранение внешних зависимостей наверху пирамиды
Для одного из платёжных провайдеров мы использовали только комбинацию моков и фейков. В итоге для одного из операторов был изменён формат нотификаций, а тест при этом давал ложноположительные результаты. Проблема провайдера заключалась в невозможности осуществить реальный платёж, поскольку для этого требовалась сим-карта определённого оператора другой страны.
В подобных случаях необходимо выполнять оценку рисков устранения внешних зависимостей, важно отслеживать реальные нотификации и проверять их на соответствие шаблону или схеме (в случае несоответствия такие нотификации должны исследоваться отдельно).
Выводы
- Платные сервисы должны тестироваться особенно тщательно, поскольку даже самые незначительные баги могут привести к неожиданным последствиям.
- При реализации интеграции с платёжным провайдером (особенно при использовании итеративных методологий разработки) важно изучить и составить карту всех возможных состояний провайдера. Итеративность может быть использована в усложнении реакции системы на определённые состояния, но сами состояния система должна классифицировать правильно с самого начала.
- Платёжный провайдер всегда является «чёрным ящиком» для нас, тестировать его работу очень сложно. Не стоит пытаться использовать какой-то один метод и тестировать с его помощью всё — это приведёт к печальным последствиям. Лучше протестировать всё в сочетании, в композиции: фейками, моками и стабами — все кейсы, песочницей и реальным платежом — пару кейсов для проверки интеграции.
- При использовании фейков, моков и стабов важно помнить, что это модели реального платежа, и, как любая модель, они имеют степень приближения к реальности и риски. Эти риски должны быть оценены и покрыты либо реальными платежами, либо дополнительными проверками.
О том, как нам удалось добиться стабильной и недорогой автоматизации тестирования платных сервисов в iOS-приложении, мы рассказываем в следующей статье.
Спасибо за внимание! Всем большой прибыли и меньше багов!