company_banner

Как не потерять деньги в черном ящике: методы тестирования биллинга

    Проверка платных сервисов — один из ключевых инженерных вопросов в тестировании Badoo. Наше приложение интегрировано с 70 платёжными провайдерами в 250 странах мира, и баг хотя бы в одном из них может привести к непредсказуемым последствиям. 

    В этой статье я расскажу о методах тестирования, которые мы используем в Badoo, и о границах применимости этих методов — этапах тестирования, на которых они максимально эффективны. 

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




    Меня зовут Владимир Солодов, я Billing QA Engineer в Badoo: занимаюсь проверкой тестовых интеграций и процессинга платежей. В подготовке текста мне помогал мой коллега Виктор Короневич: вместе с ним мы делали доклад на конференции Heisenbug (видео). В статье мы расширили область описания на все интеграции с платёжными провайдерами, которые используются в Badoo, подробнее классифицировали и описали практики удаления внешних зависимостей. 

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

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

    Поехали!

    Специфика тестирования биллинга


    Обычно целью бизнеса является получение дохода. В Badoo, социальной сети для знакомств, доход приносят кредиты и премиум-подписки. Кредиты — это внутренняя валюта Badoo. С их помощью, например, можно поднять свой профиль в результатах поиска на первое место, сделать подарок другому пользователю и прочее. Премиум-подписка действует определённый период времени и даёт сразу несколько возможностей: включить режим «невидимки», видеть людей, проявивших к тебе интерес, подтвердить подлинность своего аккаунта и многое другое.  

    Чтобы эти платные сервисы работали, мы используем интеграции с более чем 70 платёжными провайдерами. Выбор провайдера зависит от платформы, страны, девайса, мобильного оператора и других факторов. Поэтому вопрос тестирования платных сервисов у нас стоит очень остро.

    Для начала рассмотрим, почему к тестированию платных сервисов необходимо подходить с особым вниманием. Причины две.

    1. Баги в биллинге критичны для бизнеса.


    Первая проблема — репутационная. Пользователь, заплативший деньги за сервис, становится более чувствительным (и менее терпимым) к багам в приложении. Любой отзыв в публичном пространстве, будь то обзор приложения в блоге или комментарий в App Store или Google Play, от пользователя, столкнувшегося с багом в платном сервисе, будет более эмоциональным — это фактор, который приводит к репутационным потерям. 

    Вторая проблема заключается в том, что, как только вы начинаете получать деньги от пользователя за сервис, вы становитесь объектом права, защищающего потребителя услуг. И репутационные потери легко могут превратиться в финансовые. 

    Компании теряют деньги тремя путями.
     
    Путь первый — рефанды (refunds). Предположим, пользователь обнаружил, что вы продали ему сервис, который не совсем соответствует его ожиданиям. В этом случае он обращается в вашу службу поддержки. Её сотрудники проводят расследование и выясняют, что ожидания пользователя действительно не оправдались из-за бага в приложении. Вы инициируете возврат денег. В этом случае имеет место рефанд: в результате компания сталкивается с недополученной прибылью, и это самый безобидный способ потери денег. 

    Путь второй — чарджбеки (chargebacks). Предположим, произошла та же ситуация, только пользователь обратился не в вашу службу поддержки, а в банк, который выдал ему карту, или к платёжному провайдеру. Банк/провайдер инициирует возврат денег. В этом случае мы имеем дело с чарджбеком. Опасность для бизнеса здесь не только в недополученной прибыли. После определённого количества чарджбеков компания получает штраф, а также снижается её рисковый рейтинг. Снижение рейтинга, в свою очередь, приводит к удорожанию стоимости услуг провайдеров платежей.

    Путь третий — судебные иски (claims). В самых запущенных случаях могут иметь место судебные иски (в том числе и коллективные), приводящие к самым серьёзным последствиям. Так, в 2015 году после судебного иска регулятора Ofgem компания British Gas вынуждена была выплатить многомиллионную компенсацию пользователям, с которых взимала повышенную плату вследствие ошибки в системе начисления оплаты. Подробнее об этом можно прочитать здесь

    2. Для тестирования интеграций нужны знания и экспертиза.


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

    Это может привести к непредсказуемым последствиям — от упущенной прибыли до недовольных пользователей.

    Давайте обратимся к схеме, на которой перечислены виды платных сервисов, и рассмотрим проблему внимательнее.


    Рисунок 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) подписка — это когда платёжный агрегатор полностью берёт на себя управление вашими подписками и просто присылает вам нотификации об их текущих состояниях. 

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


    Рисунок 2. Кейсы биллинга, которые в первую очередь реализуют в системах

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

    Итак, с одной стороны, баги в процессинге платежей должны быть найдены до релиза, потому что они могут приводить к самым негативным последствиям. Если сделать это не удалось, то важно максимально быстро понять, что баг попал в релизную версию приложения, исправить его и — самое важное, о чём многие забывают, — «успокоить» пользователей, которые столкнулись с этим багом. 

    С другой стороны, ситуация осложняется тем, что интеграции с платёжными провайдерами — это всегда взаимодействие с «чёрным ящиком», которое добавляет в процесс тестирования множество переменных.

    Технические проблемы в процессе тестирования биллинга


    Рассмотрим их на примере интеграции Badoo c App Store. 

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

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

    Для начала обратимся к одноразовой расходуемой покупке.


    Рисунок 3. Процесс осуществления одноразового расходуемого платежа

    На шаге 1 пользователь делает запрос на покупку сервиса. Приложение решает, что должна быть произведена оплата, и на шаге 2 управление передаётся платёжному провайдеру (App Store). Шаг 3: пользователю предоставляется форма для совершения платежа. Шаг 4: пользователь предоставляет данные для оплаты. Шаг 5: провайдер выполняет транзакцию и сообщает о результате приложению, возвращая чек (receipt), содержащий полную информацию о покупке (дата, сервис, статус и прочее). Шаг 6: чек, дополненный данными о пользователе, отправляется на сервер для обработки. Сервер обрабатывает данные чека и формирует пуш-уведомление для приложения на седьмом шаге. На восьмом шаге уведомление показывается пользователю. 

    Проблема в том, что шаги 3, 4 и 5 выполняются на стороне платёжного провайдера, практически не контролируются нами и могут иметь различные вариации. Таким образом, процесс имеет на самом деле не линейную структуру, как показано на рисунке 2, а ветвящуюся (см. рис. 4), и каждая ветка должна быть обработана приложением по-разному.


    Рисунок 4. Ветвление схемы состояний одноразового платежа 

    Покупка подписок начинается так же, как одноразовый платёж, но дальнейшее управление процессом проконтролировать довольно трудно.


    Рисунок 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 сервер формирует реакцию для приложения на изменение состояния подписки.

    Таким образом, мы получили полный граф состояний, которые необходимо пройти, чтобы проверить платные сервисы.


    Рисунок 6. Полный процесс изменения состояний платежей (на примере управляемой внешне подписки)

    Оранжевым цветом окрашены части, которые мы не контролируем в нашей системе, и они являются черными ящиками для нас.

    Методы тестирования биллинга


    Итак, основной технической проблемой при тестировании платных сервисов является наличие «чёрных ящиков», состояния которых мы очень слабо контролируем. Это определяет набор методов, которыми можно покрыть всё многообразие кейсов.

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

    Реальные платежи 


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

    В остальном реальные платежи плохи. Во-первых, это дорого: очевидно, что для того чтобы совершить реальный платёж, нужно потратить реальные деньги. Вы ошибаетесь, если думаете, что в конечном итоге вся сумма вернётся  в компанию: во-первых, провайдеры берут комиссию с каждой транзакции, размер которой, как было описано выше, зависит от рискового рейтинга организации и может достигать 40% (и даже больше); во-вторых, вы можете потерять деньги при тестировании платежей в других странах из-за валютного спреда — разницы между курсами покупки и продажи валюты (покупку вы будете делать по курсу банка на продажу валюты, а возврат придёт по курсу покупки). 

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

    Песочницы


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

    Проблема растянутости тестирования во времени решается, как правило, использованием различных ухищрений. Например, в песочнице App Store используется следующее преобразование срока действия подписок.

    Реальное время подписки
    Время подписки в песочнице Apple
    1 неделя
    3 минуты
    1 месяц
    5 минут
    2 месяца
    10 минут
    3 месяца
    15 минут
    6 месяцев
    30 минут
    1 год
    1 час
    Таблица 1. Соотношение сроков действия реальной подписки и подписки в песочнице Apple

    Срок действия подписок в песочнице Google Wallet, принятый по умолчанию, приведён в таблице 2, и он может настраиваться в консоли продавца.

    Реальное время подписки 
    Время подписки в песочнице Google
    1 неделя
    5 минут
    1 месяц
    5 минут
    3 месяца
    10 минут
    6 месяцев
    15 минут
    1 год
    30 минут
    Таблица 2. Настройка срока действия подписки в песочнице Google

    В отличие от песочницы Apple, в песочнице Google можно также проверить триал, грейс-период и т. д., используя соотношение из таблицы 3.

    Реальное время подписки 
    Время подписки в песочнице Google
    Пробный период (trial)
    3 минуты
    Ознакомительный период (introductory)
    Равен времени соответствующей подписки
    Грейс-период (3/7 дней)
    5 минут
    Временная блокировка аккаунта (hold) 
    10 минут
    Пауза (1/2/3 месяца)
    5/10/15 минут (соответственно)
    Таблица 3. Срок действия дополнительных функций подписки в песочнице Google

    Закрытие подписки тоже может быть реализовано по-разному: в песочнице App Store закрытие выполняется после пятого продления, а в Google Wallet оно выполняется из консоли продавца или на девайсе из Play Store.

    Проблема песочниц в том, что провайдеры по-разному относятся к их качеству. Наш опыт показывает, что из более чем 70 платёжных провайдеров, которые интегрированы в Badoo, только две песочницы могут похвастаться полной функциональностью и стабильной работой. Это песочницы Adyen и PayPal. Остальные провайдеры имеют либо стабильные, но урезанные в плане функциональности песочницы (как Google Wallet), либо нестабильные и сильно урезанные в функциональности (как App Store и Fortumo). А есть провайдеры, которые вообще не имеют и не собираются иметь песочницу.


    Рисунок 7. Классификация песочниц по стабильности и функциональности 

    Устранение внешних зависимостей


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

    Моки в биллинге — это формирование реакций вашей системы на запросы с заранее определёнными параметрами без реального обращения к платёжному провайдеру (см. рис. 8). Например, запрос к провайдеру СМС-платежей на номер +7111-111-11-11 перехватывается на этапе отправки запроса к провайдеру и формирует реакцию системы в виде успешного платежа. Запрос на номер +7111-111-11-12 также перехватывается, но приводит к реакции на ошибку с кодом «Не хватает средств для проведения транзакции».


    Рисунок 8. Схема мока

    Фейки в биллинге — это подделки нотификаций (как будто они приходят от реального провайдера) (см. рис. 9). Интеграция с каждым провайдером предполагает ограниченный набор реакций системы на ограниченный набор типов нотификаций или реситов. На основе этой информации для каждого отдельного платежа можно сформировать набор нотификаций (с подписями и прочими фейковыми атрибутами безопасности), которые наша система будет считать реальными нотификациями от платёжного провайдера.


    Рисунок 9. Схема фейка

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


    Рисунок 10. Схема стаба

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

    Вернёмся к процессу осуществления одноразового платежа. Шаги 3, 4, 5 являются ключевыми для интеграции: передача управления платёжному провайдеру, отправка запроса провайдеру и получение ответа. При использовании каждого из рассматриваемых способов устранения внешних зависимостей фокус направлен на какие-то из этих шагов: при использовании мока мы моделируем передачу управления и отправку запроса, при использовании стаба — только передачу управления, при использовании фейка — получение ответа. Остальные шаги при этом «выносятся за скобки».


    Рисунок 11. Моделирование взаимодействия приложения с провайдером при разных методах устранения внешней зависимости (на примере одноразовой покупки в App Store)

    С одной стороны, такое устранение шагов приводит к рискам (например, можно пропустить баг в нетестируемых шагах). С другой — моделирование каждого шага делает метод дороже, поскольку требует изменений в системе. Поэтому на практике мы используем комбинации методов. Например, моки и фейки, когда при отправке запроса на определённый номер не формируется реакция системы, а отправляется фейковая нотификация на точку входа для нотификаций на нашем сервере. Или стабы и фейки, когда при выборе реакции из стаба также отправляется фейковая нотификация. Естественно, подобные реализации должны быть ограничены окружениями для разработчиков и не должны попадать на прод.  

    Ограничения методов тестирования биллинга


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

    • воспроизводимость и покрытие — какой метод поможет покрыть и воспроизвести как можно больше кейсов? 
    • возможность проверок end-to-end — что метод делает лучше: позволяет проверить весь процесс осуществления платежа или тщательно и быстро протестировать только какой-то его этап?
    • дешевизна — оцените полную стоимость: не только реальные денежные траты, но и расходы на написание и поддержку кода.

    Результаты оценки мы свели в таблицу.


    Таблица 4. Сравнительная характеристика методов тестирования биллинга

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

    Песочница. Песочницы, например, у Apple и Google, отличаются. Поэтому ими можно покрыть разное количество кейсов (и точно не все). Песочница не предоставляет возможности полноценного end-to-end тестирования: даже код в самой песочнице может отличаться от кода на проде. Однако это, пожалуй, самый дешёвый метод. 

    Фейки, моки, стабы — самый гибкий метод. Мы можем покрыть весь набор кейсов. В силу специфики этого метода мы не тестируем весь процесс платежа целиком. Метод недёшев: нужно писать код и поддерживать его в актуальном состоянии.

    Выбор метода тестирования 


    Для того чтобы определить, какой из методов на каком этапе использовать, обратимся к классической пирамиде тестирования. 

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

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

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


    Рисунок 12. Соотношение этапов и методов тестирования на пирамиде тестирования  

    Антипаттерны при выборе метода


    Информацию о том, что бывает, если нарушается соотношение тестов в пирамиде тестирования, можно найти в большом количестве статей, например в этой

    Давайте рассмотрим примеры трёх антипаттернов тестирования, не соответствующих соотношению на рисунке 12, с которыми мы столкнулись в Badoo.

    Реальные платежи внизу пирамиды 


    Для тестирования с использованием реальных платежей была заведена специальная карта. Она была доступна только узкому кругу лиц. Но однажды один QA-инженер из нашей команды узнал её данные. Имея благие намерения, он решил реализовать автотесты. Естественно, в какой-то момент банк увидел, что в течение очень короткого промежутка времени ему поступают запросы на несколько тысяч платежей, и заблокировал карту. Причём заблокировал так, что мы не могли разблокировать её примерно две недели. 

    Вывод такой: не нужно использовать реальные платежи везде.
     

    Песочницы внизу и наверху пирамиды


    Первая проблема, возникающая при избыточной зависимости от песочниц, — это сбои в их работе. Например, для тестирования платежей Apple песочница долгое время оставалась единственным способом. В итоге мы столкнулись с последствиями её нестабильной работы. Было два случая, когда песочница не работала вообще. Она не работала в течение двух недель: в итоге четыре релиза клиентского приложения мы вынуждены были выпускать без какого-то адекватного тестирования. 

    Вторая проблема — ограничения, которые имеют песочницы. Во-первых, это сложности с изменением срока действия подписки. Во-вторых, это отсутствие таких фич, как грейс-период, рефанды и прочих, то есть часть функциональности оказывается вообще никак не покрыта тестами.

    Последствия использования песочниц внизу пирамиды — появление различных инфраструктурных проблем: при использовании одного и того же аккаунта в песочнице для большого количества платежей размер передаваемого ресита или нотификации может возрастать, потому что Apple накапливает историю покупок. Для одного из пользователей ресит достиг 1 Гб — естественно, тестовый стенд просто не выдержал передачи такого объёма данных.

    Устранение внешних зависимостей наверху пирамиды


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

    В подобных случаях необходимо выполнять оценку рисков устранения внешних зависимостей, важно отслеживать реальные нотификации и проверять их на соответствие шаблону или схеме (в случае несоответствия такие нотификации должны исследоваться отдельно).

    Выводы


    1. Платные сервисы должны тестироваться особенно тщательно, поскольку даже самые незначительные баги могут привести к неожиданным последствиям. 
    2. При реализации интеграции с платёжным провайдером (особенно при использовании итеративных методологий разработки) важно изучить и составить карту всех возможных состояний провайдера. Итеративность может быть использована в усложнении реакции системы на определённые состояния, но сами состояния система должна классифицировать правильно с самого начала. 
    3. Платёжный провайдер всегда является «чёрным ящиком» для нас, тестировать его работу очень сложно. Не стоит пытаться использовать какой-то один метод и тестировать с его помощью всё — это приведёт к печальным последствиям. Лучше протестировать всё в сочетании, в композиции: фейками, моками и стабами — все кейсы, песочницей и реальным платежом — пару кейсов для проверки интеграции. 
    4. При использовании фейков, моков и стабов важно помнить, что это модели реального платежа, и, как любая модель, они имеют степень приближения к реальности и риски. Эти риски должны быть оценены и покрыты либо реальными платежами, либо дополнительными проверками.

    О том, как нам удалось добиться стабильной и недорогой автоматизации тестирования платных сервисов в iOS-приложении, мы расскажем в следующей статье. 

    Спасибо за внимание! Всем большой прибыли и меньше багов! 
    • +34
    • 4,6k
    • 9
    Badoo
    410,32
    Big Dating
    Поделиться публикацией

    Комментарии 9

      –3
      Спасибо за антипаттерны!

      А ещё integration testing это не фейки и песочницы, это реальные стыки систем. Это, например, тестирование DAL уровня запросв (методов Repository) с реальной базой. тестррование методов repository по обращению к сервису с реальным сервисом по http. Но никак не с фейкам. Нет песочницы и тестового аккаунта к реальной системе? Значит для этого куска нельзя реализовать интеграционные тесты. Обходитесь юнитами. И уже тем более интеграционное тестирование не «просто уровнем выше будем тестировать: наделали кучу зависимостей разных подсистем и один монстро-тест запустили, который и в базу лезет и в сервис шлёт и в очередь». Это самая распространённая ошибка, которая становится причиной: «ой… чё-то тесты опять упали», а потом «ну да, есть тесты, но поддерживать их тяжко, потому не запускали давно»

      Но однажды один QA-инженер из нашей команды узнал её данные. Имея благие намерения, он решил реализовать автотесты.

      Для автотестов делается свой сервис со стабами, фейк у вас в статье. В который скармливается «ожидаемый ответ на ожидаемый запрос» а ля Setup из библиотеки Moq только по HTTP
      И погнали тесты делать любые. QA должен был знать такие базовые вещи, прежде чем использовать карту. Но это ещё большой вопрос, надо ли это делать, когда достаточно один раз от реальной системы получить ответы, понять логику и всё заменить моками.

      Последствия использования песочниц внизу пирамиды — появление различных инфраструктурных проблем:

      Ещё бы. Когда на уровень юнит-тестов бизнес логики лезем е2е тестами, да ещё и с нестабильным инструментарием. Разделять, это нужно разделять. Бизнес логика тестируется только юнитами и только моками, никаких песочниц от эппл. Песочница это е2е тесты и частично интеграционные.
      формат нотификаций, а тест при этом давал ложноположительные результаты

      нужно трекать такие изменения. документацию или запросами к реальному серверу раз в день, например. Как минимум версию сервиса трекать и\или xsd схему.

      ЗЫ

      О боже, опять это дурное слово из рунглиша — «нужны знания и экспертиза». Пришлите адрес, вышлю ссылку на словарь Ожегова.

      Экспертиза в русском языке это документ, заключение по результатам исследований: «проводить экспертизу».
      В том значении, в котором автор пытается применять слово переводя с английского, есть добротное выражение: «знание и опыт» или «специальные знания». Но никак не «знания и экспертиза».

      Нужные знания и опыт. Или нужные опыт и специальные знания.
        +1
        Спасибо за важное дополнение. Конечно, всего в одну статью не уместишь: у нас готовится следующая статья от моего коллеги, с которым мы вместе делали доклад на Гейзенбаге, там как раз будет про то, что в каждом конкретном случае требуется оценка рисков и их покрытие. Мы также расскажем, на основе чего эти риски выявлять. Про рунглиш — да, в Лондоне возникает такая профессиональная деформация, иногда забываешь, как слова пишутся.
        +2
        В крупных организациях на каждого внешнего поставщика услуг заводят отдельный журнал (электронный) и назначают выделенного работника, который отвечает за все вопросы по этому поставщику, которые возникают у безопасноиков/разработчиков/тестировщиков, такие как-то:
        • Почему внезапно сменился HTTPS сертификат на API URI?
        • Зачем поставщик начинает мне слать 5xx ошибки если я делаю больше 10 одновременных вызовов API?
        • Как мне проверить метод XYZ под версию 1.2.3, если у поставщика выложена документация только на 1.1.2?


        Так что знания и экспертиза — это хорошо, но еще нужно иметь менеджера этих самых знаний, который будет предоставлять их команде по мере необходимости и поддерживать их у себя в журнале в актуальном состоянии.
          0
          Очень классное дополнение, спасибо! Надо попробовать в своей работе. Это позволит также формализовать свои знания и, в случае неоходимости, поделиться ими с коллегами. В нашем рабочем процессе закрепление человека за определенной областью не очень приветствуется, но ведение журнала подходит и в этом случае.
          0
          Честно говоря, в связи с утверждением
          Платёжный провайдер всегда является «чёрным ящиком» для нас
          — это действительно серьёзная и объективно полностью не преодолимая проблема, когда «чёрный ящик» не статичен, а живёт своей жизнью — составить актуальную полную карту всех его возможных состояний, связав с логикой всех возможных синхронных/асинхронных/временных и позитивных/негативных событий, построить адекватную модель платежа и спроецировать её (поддерживая в актуальном состоянии) на реализацию моков, стабов, фейков, включая соответствующие доработки в своём прикладе, да ещё не быть введёнными в заблуждение некорректной работой песочниц, не имея конкретики по производительности реальных внешних систем, не говоря об особенностях долгосрочных платежей-подписок на период, в течение которого бизнес-логика реализации внутренних/внешних систем и поведения «ящика» меняются…
          короче,
          я так до конца и не понял — ЧТО вы в условиях такой неопределённости тестируете (КАК — понял, спасибо! ещё для себя сделал выводы про двух надёжных и стабильных платёжных провайдера).
            0
            Рассматривая клиентское приложение или систему «приложение-сервер» (которые далее в коментарии я буду называть просто приложением), мы имеем дело с детерминированным конечным автоматом (ДКА), который обладает ограниченным (возможно очень большим, но ограниченным) числом состояний. Проблема подключения сторонних сервисов, которыми является, например, платежный провайдер, заключается в том, что на одну из точек входа начинают поступать сигналы на изменение состояний, которые a) нам известны, но плохо контролируются нами, б) нам неизвестны. Соотвтетственно, ответ на вопрос «ЧТО мы тестируем?» разбивается на две части: a) для известных сигналов черного ящика мы тестируем, что вся цепочка состояний нашего ДКА изменяется в соответствии с нашими ожиданиями, б) что мы не получаем сигналы, которые нам неизвестны.

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

            Вторая проблема — поступление на вход приложения неизвестного сигнала. Она очень серьезная, и решается она по-разному. В комментарии выше, например, коллега предлагает вести журнал и иметь в отделе менеджера, контролирующего изменения от внешней системы. У нас на текущий момент выполняется сбор всех приходящих нотификаций от внешних систем. Любые изменения сигналов мы рассматриваем как риск. Узнать о них (если нас не уведомляют провайдеры заранее) мы можем постфактум (и у нас были прецеденты), посмотреть в логах, что к нам стало приходить, увидеть изменения и отреагировать на них. Но это все равно не гарантирует нам своевременную реакцию на изменения. Если мы хотим получать информацию о неизвестных сигналах, как можно раньше, то в идеале мы должны валидировать приходящие к нам запросы (например, по xsd или json схемам), но здесь я немного хитрю, называя это риском. При рассмотрении риска мы должны учитывать вероятность его реализации, негативное влияние от его реализации и стоимость на его покрытие. В нашей ситуации решение с валидацией пока представляется достаточно дорогим, потому что это аналитическая или даже экспертная система, которая требует серьезных ресурсов на создание и поддержку. Да, изменения случаются, да они могут принести серьезный вред (и мы рассмотрим пример в следующей статье, которую готовит мой коллега по мотивам выступления на Гейзенбаге (ссылка в статье)). Но вероятность этого пока не настолько высока, чтобы потратить ресурсы на валидацю по схеме, поэтому мы ограничиваемся визуальным анализом статистики и логов, и немного уменьшаем неопределенность, покрывая интеграционными тестами с использованием реального платежа или песочницы.

            PS Вообще, своим коментарием вы подняли проблему, которую лично я считаю одной из ключевых в коммуникации, когда объект исследования подменяется методологией и потом забывается, а о чем мы вообще тут говорили. Ответ на этот вопрос помог сместить акценты, как мне кажется в нужном направлении. Спасибо!
            +5
            Но однажды один QA-инженер из нашей команды узнал её данные. Имея благие намерения, он решил реализовать автотесты.

            А в нашей конторе QA просто обналичил все что было на тестовой карточке и больше в офис не вернулся. История реальная, дальше его искали безопасники.
              –1
              Для тестирования интеграций нужны знания и экспертиза


              Экспертиза — в русском «это тестирование с целью оценки».
              А в английском сходное по написанию слово — это, действительно, «компетенция, уровень знаний».

              Если употреблено в английском смысле — то у вас тавтология «Для тестирования интеграций нужны знания и уровень знаний»

              А если в русском — то там ничего нет про «тестирование с целью проверки».

                0
                В данном случае используется значение в русском

                ЭКСПЕРТИЗА (франц. expertise, от лат. expertus — опытный) — исследование специалистом (экспертом) каких-либо вопросов, решение которых требует специальных познаний в области науки, техники, искусства и т. д. (Большой энциклопедический словарь)


                Экспертиза — Исследование Экспертами каких-либо вопросов, решение которых требует специальных познаний в области науки, техники, искусства и т. д. (Большая советская энциклопедия)


                Экспертиза — [< лат.; см. эксперт] – исследование и разрешение при помощи сведущих людей какого-либо вопроса, требующего специальных знаний, например, врачебная экспертиза, бухгалтерская экспертиза (Большой словарь иностранных слов)


                В сухом остатке — это исследование экспертом. «Необходимы знания и экспертиза» в данном контексте означает, что либо вы знаете все кейсы (например, потому что вы общаетесь с представителями провайдера, уверены, что версия та же, что описана в имеющейся документации). Либо вы проводите исследование, для которого вам нужны экспертные навыки и стартовые данные (например, критерии оценки или опорные точки, которые в статье и предложены). Поэтому здесь как мне кажется нет ни противоречия, ни тавтологии.

                При переводе на английский будет использован только термин expertise, потому что, как вы совершенно верно заметили, в английском языке это слово уже включает и навыки исследования, и знания.

              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

              Самое читаемое