Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Привет! Меня зовут Валерий Богданов, и я отвечаю в Мир Plat.Form за тестирование в команде мобильных платежей. Я уже писал, что в 2018 году мы запустили сервис мобильных платежей и в связи с этим, примерно одновременно, мы начали разрабатывать 2 мобильных платежных приложения:
— наше собственное приложение Mir Pay;
— приложение, разрабатываемое одним из наших партнеров по нашим спецификациям.
Имеются в виду мобильные приложения, предназначенные для оплаты покупок в магазинах на POS-терминалах с помощью телефона посредством NFC.
В связи с началом их разработки возникла необходимость наладить процесс тестирования именно платежного ядра мобильного приложения.
Платежное ядро представляет собой компонент мобильного платежного приложения, отвечающий за логику взаимодействия телефона с POS-терминалом, которое должно осуществляться в строгом соответствии со спецификациями платежных систем, за риск-менеджмент со стороны устройства (отклонить/одобрить операцию) и за безопасность транзакции (формирование платежной криптограммы).
Если с нашим платежным приложением все было относительно понятно, его можно тестировать и вдоль и поперек, то с приложениями партнеров все было не так просто. В этом случае у нас нет исходников приложения, да и достать само приложение до его релиза не так то просто. Поэтому нужно было создать не просто какой-то внутренний инструмент для тестирования, а целый сервис, который мог бы использоваться другими организациями и предоставлять нам полную картину о функционировании протестированного платежного ядра.
Еще на этапе аналитики был обозначен следующий важный момент: тестирование должно проходить платежное ядро, максимально приближенное к релизной конфигурации.
Так как подобные приложения могут подвергаться изменениям после сборки — как правило, это интеграция систем защиты приложения, например, один из самых известных — dex-protector, мы не можем исключать влияние такого вмешательства в приложение на работу его платежной части. Также влияние на работу платежного ядра потенциально могут оказывать особенности аппаратной реализации телефона или особенности операционной системы.
Например, один из телефонов между командами нашего приложения вставлял команду от стороннего платежного приложения, установленного на это же устройство, а другой телефон вообще не мог корректно взаимодействовать с терминалом без изменения системных настроек.
В классическом случае, такая система могла бы представлять собой набор unit-тестов для разработчиков, или какой-нибудь набор программно-запускаемых сценариев, — казалось бы — все очевидно и просто, но в силу ранее обозначенных требований такой подход здесь не применим. Разумеется, он не исключает unit-тестирование, какие-либо еще этапы функционального тестирования, но в итоге все должно быть прогнано в среде максимально приближенной к боевой.
Следовательно, система должна уметь тестировать настоящий телефон с настоящим платежным приложением.
В таком случае, в тестировании должен присутствовать специфический компонент — платежный терминал, причем корректно настроенный (или некорректно, для негативных кейсов), а так как подобный тестовый прибор есть далеко не у всех, тестирование взаимодействия с терминалом всегда вызывало трудности.
Дело осложняется еще и тем, что далеко не каждый разработчик или тестировщик понимает, как должен взаимодействовать терминал с телефоном, не каждый знает необходимые стандарты и хорошо в них ориентируется.
Можно было бы тестировать, отправляя готовые терминалы разработчикам, но согласитесь, отправлять всем огромное количество терминалов, настраивать их постоянно, при чем, то ли удаленно, то ли опять возвращать их, при этом обучать кого-то как ими пользоваться, как снимать логи — было бы крайне ресурсоемко и неудобно. Собственно, на первых этапах так и было, и изначально для тестирования ядра нужно было сделать огромное количество операций:
— разработчику выпустить версию приложения;
— настроить терминал, согласовав ключи (а это делают уже другие специалисты);
— отправить терминал разработчику;
— провести операцию;
— отдать терминал профильным специалистам;
— снять логи с терминала, — что само по себе не так-то просто;
— проанализировать логи и вычислить ошибку;
— сформировать отчет и отправить его разработчику.
И на каждом из этих этапов возможны какие-то заминки/форс-мажорные обстоятельства затягивающие процесс. Все эти этапы были необходимы, но все это требовало огромного количества времени.
Нам удалось решить эту проблему. Система, о которой пойдет речь, позволила нам сократить эту процедуру буквально до одного действия.
Исходя из всего вышеописанного, возникла задача создать сервис тестирования платежного ядра таким, что бы для его использования не надо было обладать специфическими познаниями в области платежных систем, что бы для него не требовалось сложного специального оборудования и что бы результаты тестирования могли быть понятными разработчикам. То есть в случае неуспешного теста в отчетах должно быть достаточное описание некорректного поведения для его исправления.
С учетом всех этих требований мы выбрали формат веб-сервиса. В нашем понимании, тестировщик должен был зайти на веб-страницу и иметь возможность протестировать платежное приложение с использованием простого PCSC-считывателя. Тут нужно было подружить как-то веб-страницу, открытую в браузере со считывателем, — для этого было написано расширение для браузера.
Популярные браузеры позволяют наладить информационный обмен с нативным приложением при помощи расширений через стандартные потоки ввода-вывода (Native messaging в Хроме, например). Такое приложение было реализовано, оно устанавливалось при установке соответствующего расширения, передавало команды на считыватель и ответ возвращало обратно, через расширение на страницу.
Таким образом у бэка системы появилась возможность напрямую общаться по NFC с телефоном удаленного пользователя.
С другой стороны, наши специалисты по терминалам реализовали полностью настраиваемый виртуальный терминал, который в своем дефолтном состоянии представляет практически полную функциональную копию POS-терминалов, которые мы встречаем в магазинах. Эта задача тоже не из легких, но благодаря нашим специалистам на этом этапе никаких затруднений у нас не возникло.
И на основе этого была реализована возможность, скажем так, удаленно совершать покупки.
То есть на странице веб сервиса, есть кнопка — оплатить. Тестировщик может выбрать в каком типе терминала он хочет провести оплату (это либо обычный POS-терминал, а может быть и банкомат) и на какую сумму, после этого достаточно приложить телефон к считывателю и произойдет ровно то, что произошло бы, если бы он совершал операцию на настоящем терминале. Вот именно эта возможность на порядок сократила сроки реализации ПО, существенно изменив цикл разработки. Если раньше нужно было, как я уже говорил: разработчику выпустить версию приложения, настроить и отправить терминал, снять логи с терминала и так далее, то теперь все очень сильно упростилось: разработчик, даже не имея толком приложения, лишь какой-то прототип на костылях может в любой момент провести любую операцию и мгновенно получить отчет по ней вместе с распарсеными логами и пояснениями к ним.
Еще больше возможностей для автоматизации у нас есть, когда мы говорим о нашем собственном приложении – Mir Pay.
Дело в том, что наши партнеры в силу тех или иных причин, зачастую не могут нам предоставить свое приложение до его релиза или какую-то отладочную его версию, но в случае с нашим приложением, все карты у нас на руках — наше приложение взаимодействует с нашими серверами, у нас есть исходники и полное понимание того, как оно должно себя вести.
С другой стороны, приложение было подключено к заглушке бэковой части, которая могла выдавать в приложение любые данные, заданные в тесте в качестве профиля токена.
Таким образом было написано порядка сотни различных тестов на одно только платежное ядро, а процесс заведения карты в приложение тоже был автоматизирован. Для этого было написано еще одно расширение для браузера, которое теперь могло выполнять скрипты ADB по команде с сервера, а эти самые команды отправлялись в нужные моменты тестирования.
То есть, тестировщик заходит на страницу сервиса, выбирает галочками нужные тесты — например все, кладет телефон на считыватель и нажимает «Пуск». При выполнении каждого теста на телефон, посредством команд ADB добавляются нужные карты, от заглушки бэка приходит нужный в тесте профиль, и происходит обмен между телефоном и считывателем. Анализируется поведение телефона, а также логи виртуального терминала, тест отмечается, как пройден/не пройден, данные сохраняются, карта с телефона удаляется, — то есть приводим все в исходное состояние и тут же начинается следующий тест.
С такой системой полное тестирование платежного ядра с составлением отчета теперь занимает не более пары часов, в то время как ранее, в полуручном режиме, для этого могло потребоваться вплоть до недели.
Таким образом описанный сегодня подход позволил нам фактически изменить (хоть и частично) цикл разработки мобильных платежных приложений, и этап отладки платежного ядра, который ранее мог длиться месяцами теперь занимает считаные дни.
Такой подход не ограничивается тестированием платежных приложений, потенциально его можно применять и в других случаях. Если функциональность разрабатываемого приложения включает в себя сложное взаимодействие с какими-то другими устройствами по «не TCP»-протоколу и реализуется сторонним разработчиком, то вполне возможно построить нечто подобное, и, вероятно, это так же даст свой результат.
— наше собственное приложение Mir Pay;
— приложение, разрабатываемое одним из наших партнеров по нашим спецификациям.
Имеются в виду мобильные приложения, предназначенные для оплаты покупок в магазинах на POS-терминалах с помощью телефона посредством NFC.
В связи с началом их разработки возникла необходимость наладить процесс тестирования именно платежного ядра мобильного приложения.
Платежное ядро представляет собой компонент мобильного платежного приложения, отвечающий за логику взаимодействия телефона с POS-терминалом, которое должно осуществляться в строгом соответствии со спецификациями платежных систем, за риск-менеджмент со стороны устройства (отклонить/одобрить операцию) и за безопасность транзакции (формирование платежной криптограммы).
Если с нашим платежным приложением все было относительно понятно, его можно тестировать и вдоль и поперек, то с приложениями партнеров все было не так просто. В этом случае у нас нет исходников приложения, да и достать само приложение до его релиза не так то просто. Поэтому нужно было создать не просто какой-то внутренний инструмент для тестирования, а целый сервис, который мог бы использоваться другими организациями и предоставлять нам полную картину о функционировании протестированного платежного ядра.
Еще на этапе аналитики был обозначен следующий важный момент: тестирование должно проходить платежное ядро, максимально приближенное к релизной конфигурации.
Так как подобные приложения могут подвергаться изменениям после сборки — как правило, это интеграция систем защиты приложения, например, один из самых известных — dex-protector, мы не можем исключать влияние такого вмешательства в приложение на работу его платежной части. Также влияние на работу платежного ядра потенциально могут оказывать особенности аппаратной реализации телефона или особенности операционной системы.
Например, один из телефонов между командами нашего приложения вставлял команду от стороннего платежного приложения, установленного на это же устройство, а другой телефон вообще не мог корректно взаимодействовать с терминалом без изменения системных настроек.
В классическом случае, такая система могла бы представлять собой набор unit-тестов для разработчиков, или какой-нибудь набор программно-запускаемых сценариев, — казалось бы — все очевидно и просто, но в силу ранее обозначенных требований такой подход здесь не применим. Разумеется, он не исключает unit-тестирование, какие-либо еще этапы функционального тестирования, но в итоге все должно быть прогнано в среде максимально приближенной к боевой.
Следовательно, система должна уметь тестировать настоящий телефон с настоящим платежным приложением.
В таком случае, в тестировании должен присутствовать специфический компонент — платежный терминал, причем корректно настроенный (или некорректно, для негативных кейсов), а так как подобный тестовый прибор есть далеко не у всех, тестирование взаимодействия с терминалом всегда вызывало трудности.
Дело осложняется еще и тем, что далеко не каждый разработчик или тестировщик понимает, как должен взаимодействовать терминал с телефоном, не каждый знает необходимые стандарты и хорошо в них ориентируется.
Можно было бы тестировать, отправляя готовые терминалы разработчикам, но согласитесь, отправлять всем огромное количество терминалов, настраивать их постоянно, при чем, то ли удаленно, то ли опять возвращать их, при этом обучать кого-то как ими пользоваться, как снимать логи — было бы крайне ресурсоемко и неудобно. Собственно, на первых этапах так и было, и изначально для тестирования ядра нужно было сделать огромное количество операций:
— разработчику выпустить версию приложения;
— настроить терминал, согласовав ключи (а это делают уже другие специалисты);
— отправить терминал разработчику;
— провести операцию;
— отдать терминал профильным специалистам;
— снять логи с терминала, — что само по себе не так-то просто;
— проанализировать логи и вычислить ошибку;
— сформировать отчет и отправить его разработчику.
И на каждом из этих этапов возможны какие-то заминки/форс-мажорные обстоятельства затягивающие процесс. Все эти этапы были необходимы, но все это требовало огромного количества времени.
Нам удалось решить эту проблему. Система, о которой пойдет речь, позволила нам сократить эту процедуру буквально до одного действия.
Исходя из всего вышеописанного, возникла задача создать сервис тестирования платежного ядра таким, что бы для его использования не надо было обладать специфическими познаниями в области платежных систем, что бы для него не требовалось сложного специального оборудования и что бы результаты тестирования могли быть понятными разработчикам. То есть в случае неуспешного теста в отчетах должно быть достаточное описание некорректного поведения для его исправления.
С учетом всех этих требований мы выбрали формат веб-сервиса. В нашем понимании, тестировщик должен был зайти на веб-страницу и иметь возможность протестировать платежное приложение с использованием простого PCSC-считывателя. Тут нужно было подружить как-то веб-страницу, открытую в браузере со считывателем, — для этого было написано расширение для браузера.
Популярные браузеры позволяют наладить информационный обмен с нативным приложением при помощи расширений через стандартные потоки ввода-вывода (Native messaging в Хроме, например). Такое приложение было реализовано, оно устанавливалось при установке соответствующего расширения, передавало команды на считыватель и ответ возвращало обратно, через расширение на страницу.
Таким образом у бэка системы появилась возможность напрямую общаться по NFC с телефоном удаленного пользователя.
С другой стороны, наши специалисты по терминалам реализовали полностью настраиваемый виртуальный терминал, который в своем дефолтном состоянии представляет практически полную функциональную копию POS-терминалов, которые мы встречаем в магазинах. Эта задача тоже не из легких, но благодаря нашим специалистам на этом этапе никаких затруднений у нас не возникло.
И на основе этого была реализована возможность, скажем так, удаленно совершать покупки.
То есть на странице веб сервиса, есть кнопка — оплатить. Тестировщик может выбрать в каком типе терминала он хочет провести оплату (это либо обычный POS-терминал, а может быть и банкомат) и на какую сумму, после этого достаточно приложить телефон к считывателю и произойдет ровно то, что произошло бы, если бы он совершал операцию на настоящем терминале. Вот именно эта возможность на порядок сократила сроки реализации ПО, существенно изменив цикл разработки. Если раньше нужно было, как я уже говорил: разработчику выпустить версию приложения, настроить и отправить терминал, снять логи с терминала и так далее, то теперь все очень сильно упростилось: разработчик, даже не имея толком приложения, лишь какой-то прототип на костылях может в любой момент провести любую операцию и мгновенно получить отчет по ней вместе с распарсеными логами и пояснениями к ним.
Еще больше возможностей для автоматизации у нас есть, когда мы говорим о нашем собственном приложении – Mir Pay.
Дело в том, что наши партнеры в силу тех или иных причин, зачастую не могут нам предоставить свое приложение до его релиза или какую-то отладочную его версию, но в случае с нашим приложением, все карты у нас на руках — наше приложение взаимодействует с нашими серверами, у нас есть исходники и полное понимание того, как оно должно себя вести.
С другой стороны, приложение было подключено к заглушке бэковой части, которая могла выдавать в приложение любые данные, заданные в тесте в качестве профиля токена.
Таким образом было написано порядка сотни различных тестов на одно только платежное ядро, а процесс заведения карты в приложение тоже был автоматизирован. Для этого было написано еще одно расширение для браузера, которое теперь могло выполнять скрипты ADB по команде с сервера, а эти самые команды отправлялись в нужные моменты тестирования.
То есть, тестировщик заходит на страницу сервиса, выбирает галочками нужные тесты — например все, кладет телефон на считыватель и нажимает «Пуск». При выполнении каждого теста на телефон, посредством команд ADB добавляются нужные карты, от заглушки бэка приходит нужный в тесте профиль, и происходит обмен между телефоном и считывателем. Анализируется поведение телефона, а также логи виртуального терминала, тест отмечается, как пройден/не пройден, данные сохраняются, карта с телефона удаляется, — то есть приводим все в исходное состояние и тут же начинается следующий тест.
С такой системой полное тестирование платежного ядра с составлением отчета теперь занимает не более пары часов, в то время как ранее, в полуручном режиме, для этого могло потребоваться вплоть до недели.
Таким образом описанный сегодня подход позволил нам фактически изменить (хоть и частично) цикл разработки мобильных платежных приложений, и этап отладки платежного ядра, который ранее мог длиться месяцами теперь занимает считаные дни.
Такой подход не ограничивается тестированием платежных приложений, потенциально его можно применять и в других случаях. Если функциональность разрабатываемого приложения включает в себя сложное взаимодействие с какими-то другими устройствами по «не TCP»-протоколу и реализуется сторонним разработчиком, то вполне возможно построить нечто подобное, и, вероятно, это так же даст свой результат.