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

И, конечно, довольно часто социальные сети банят наших тестовых пользователей, потому что считают их вовсе не тестовыми, а «подозрительными». В данной статье я расскажу, как бороться с банами Instagram и почему приходится это делать.



Суть проблемы


Итак, давайте разбираться по порядку. Начнем с того, что у нас есть сервис, который нам надо покрыть UI-тестами. И на нем есть некий функционал, который зависит от каких-либо социальных сетей. Например, у нас есть возможность авторизоваться на сайте через Instagram. Как покрыть такой функционал тестами?

На первый взгляд все просто. Мы создаем юзера на Instagram и прописываем его email и пароль в тесте (в специально созданном для этого месте):

class InstagramUsers:
    EMAIL = "some_email@example.com"
    PASS = "secret"

Далее пишем тест, который находит необходимую иконку и кликает на нее.

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

Тест делает следующее. Он открывает нужный экран, находит иконку социальной сети и кликает на нее. Начинается процесс авторизации на Instagram. В нужном окошке мы вводим email и пароль нашего аккаунта (пример для web):



Соответственно, тест авторизуется и далее идет проверка взаимодействия нашего сервиса с Instagram. Мы видим желаемый статус теста «success» и радуемся — все в порядке.

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



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

Для данной проблемы есть два решения.

Первое решение


Мы можем сохранять куки, полученные от Instagram, между запусками тестов. И авторизовываться только в необходимом случае. Правда тут я вижу несколько проблем.

Во-первых, если у нас много тестов, нам рано или поздно захочется их распараллелить, чтобы процесс тестирования проходил быстрее. В данном случае придется решать проблему параллельного доступа к данным. Когда expire date у авторизационной куки закончится, нам надо как-то гарантировать, что два или более тестов не попробуют авторизоваться в Instagram одновременно из параллельных потоков.

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

Второе решение


Собственно, ради чего я сел писать статью… Мы можем авторизовываться на Instagram через Facebook. Странно звучит, верно? Сейчас я расскажу подробнее.

По какой-то причине Instagram не банит аккаунты, которые то и дело авторизовываются через Facebook вместо формы авторизации. Честно, я не знаю почему так происходит, я наткнулся на эту особенность от безысходности, пытаясь решить вопрос с баном аккаунтов. И решил поделиться с вами.

Итак, последовательность действий следующая. Мы создаем пользователя на Facebook. Далее мы создаем пользователя Instagram, сразу привязанного к пользователю Facebook. В тестах прописываем только доступы к пользователю Facebook.

Сам тест надо научить логиниться в Instagram через Facebook. Тут сложностей возникнуть не должно.

Итог


Я не люблю воркэраунды. Чем проще подход, который мы применяем в тестировании, тем он честнее. Соответственно, тем спокойнее можно спать по ночам. Но, к сожалению, иногда приходится «выкручиваться».

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

Я очень надеюсь, что однажды все крупные сервисы будут иметь подобный API. Еще больше я надеюсь, что если ребята из Instagram увидят этот материал, они не просто исправят эту особенность, а сделают адекватный способ получения тестовых аккаунтов для автоматизированного тестирования.

У меня все, спасибо за внимание.

Комментарии (6)


  1. brrr
    13.12.2017 13:50

    Что ж вы так русский язык-то не любите.


    Я не люблю воркэраунды.

    Там же в википедии по-русски: "Обходной прием", на техническом жаргоне — «костыль»


    1. saver Автор
      13.12.2017 14:11
      +1

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


  1. vesper-bot
    13.12.2017 15:34
    -1

    Разлогиниваться надо!


  1. jumale
    13.12.2017 15:58

    Я не сталкивался конкретно с инстаграмом, но предполагаю что у их API должна быть возможность зарегистрировать приложение в режиме sandbox с тестовыми пользователями, которое можно связать с staging сервером и запускать UI тесты там. Лично я бы не стал на проде запускать какие либо тесты кроме smoke тестов.


    1. saver Автор
      13.12.2017 16:04
      +1

      Все верно, подобное API у них действительно есть: https://www.instagram.com/developer/sandbox/.

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

      This is a fully functional environment that allows you to test the API before submitting your app for review. Sandbox mode is ideal for developers who are new to the Instagram Platform and want to explore the API Platform, as well as for teams that need multiple clients for development, staging, and other non-live environments.


      Это API больше подходит для отладки и написания кода. Оно не предназначено для сервисов, которые не в режиме разработки.

      Since this mode is meant for development, apps in Sandbox mode are not visible to the general public, but instead are only visible to a limited set of up to 10 authorized 'sandbox users'. Only these users will be able to test and authenticate your app.


      Только лимитированное количество Instagram-аккаунтов сможет взаимодействовать с нашим сервисом. Этого мало, к сожалению.

      To get out of Sandbox mode, you need to submit your app for review. If your app falls into the approved use cases and gets approved, it will automatically go liv


      Не очень понятно, как бороться с этим.

      Мы пробовали писать автотесты, привязывая юзеров через этот API. В конечном итоге такой подход нам не подошел.


  1. igor_suhorukov
    13.12.2017 21:52

    Скорее всего такое поведение с аутентификацией через фейсбук — наспех сделаная функциональность. Уверен, что скоро «залатают». Фейсбук переводит инфраструктуру инстаграм на graphQL и свои технологии. Что как бы логично с точки зрения стоимости поддержки и добавления новых фич штатными сотрудниками. Как раз месяц назад это стало причиной багов в библиотеке, которая работала с старым форматом данных instagram.