Як ми тестуємо взаємодія з Facebook



Вступ

Привіт, хаброжитель! Вже досить давно я хотів написати статтю про те, як у нас в Badoo влаштована автоматизація тестування. Хотілося написати про щось цікаве і, в той же час, корисному. Поділитися досвідом, який можна було б легко інтегрувати майже в будь-яку систему. І ось, така тема назріла…

Як багато з вас знають, Badoo — це соціальна мережа, орієнтована на пошук нових друзів і знайомств. Однією з найважливіших завдань є верифікація користувача. Адже всім нам хочеться, щоб приваблива дівчина, з якою у нас призначена зустріч, не виявилася дядьком Колею з Твері.

Для верифікації користувачів у нас існує багато різних способів. Деякі з них досить звичні, такі, як верифікація за номером телефону. Є і більш незвичайний — верифікація по фотографії. Але сама проста і швидка — верифікація через соціальні мережі.

Такий спосіб верифікації профілю можливий одразу на момент його створення — реєстрація через соціальну мережу. По-перше, це швидко, всього один клік і ніяких додаткових маніпуляцій з телефоном чи веб-камерою. По-друге, це зручно, так як при бажанні можна імпортувати фотографії і інформацію про себе, замість того, щоб вводити їх вручну.

Сьогодні я розповім про те, як на Badoo влаштована реєстрація та верифікація через Facebook і про те, як ми навчили selenium-тести її перевіряти.





Отже, уявимо, що ви — новий користувач сервісу Badoo. Ви заходите на сайт і бачите ось таку форму реєстрації. Заповнювати всі ці поля або клікнути по кнопочці реєстрації через Facebook? Для мене це — ніколи не питання. Я б заповнив всі поля вручну і не став би прив'язувати свій аккаунт. Чому? Тому що я трохи параноїк, сподіваюся, це не заразно. :)

Насправді Badoo ніколи не розмістить яку-небудь інформацію з стороннього джерела без згоди користувача, так що спокійно клікаєм по темно-синьої кнопки і реєструємося на сайті. Один клік, 10-15 секунд, і у нас є свій верифікований профіль на Badoo. Ура!



Як би вчинив справжній QA-інженер після того, як створив профіль на сервісі так просто і швидко? Правильно, спробував би створити ще один. Як відреагує сервіс, якщо на той самий FB-аккаунт спробувати зареєструвати ще один профіль?

Знову відкриваємо сторінку реєстрації і клікаємо по іконці FB. Нічого несподіваного не сталося, Badoo «дізналося» FB-аккаунт і замість реєстрації відразу авторизовало. Все в порядку.

Перший selenium-тест на реєстрацію

Тепер уявімо, що ви — QA інженером в компанії Badoo. Перед вами стоїть завдання — автоматизувати флоу реєстрації і авторизації через FB запис. На перший погляд завдання просте, ось що вам знадобиться:

  • аккаунт FB;
  • локатор кнопочки FB на сторінці реєстрації;
  • метод, який чекає авторизационную cookie (щоб переконатися, що тест залогінився на сайті);
  • локатор sign out кнопочки, щоб разлогиниться;
  • метод, який чекає, коли авторизационная cookie пропаде.


Після того, як були написані необхідні методи, складаємо сценарій:

  • Відкрити стартову сторінку;
  • Натиснути іконку facebook'а;
  • У новоствореній вкладці авторизуватися на Facebook;
  • Дочекатися авторизації на Badoo;
  • Отримати id користувача (нехай буде first_user_id);
  • Разлогиниться;
  • Відкрити стартову сторінку;
  • Натиснути іконку Facebook'a;
  • Дочекатися авторизації на Badoo;
  • Отримати id користувача (нехай буде second_user_id);
  • Переконатися, що first_user_id і second_user_id збігаються.


Отже, сценарій готовий, ви запустили тест і він пройшов. Все чудово. Саме час вставити котика в статті:



Коммитим код тесту в гілку, кидаємо завдання на рев'ю і йдемо пити каву. Однак, ви не встигли дійти до кухні, як приходить повідомлення — завдання не пройшла рев'ю, тест не працює. Щось пішло не так…

Після перезапуску тесту стає ясно, що проблема в наступному — FB-аккаунта вже існує профіль на Badoo. Замість реєстрації тест відразу авторизувався. Робити нема чого, треба видаляти профіль по завершенню тесту. Слава Богу, у нас є приголомшлива штука — QaApi!

Кілька років тому я розповідав, як вона інтегрована з нашими автотестами. Доповідь називалася «Selenium тести. Від RC і одного користувача до WebDriver, Page Object і пулу користувачів», знайти його можна тут — habrahabr.ru/company/badoo/blog/216255.

Якщо коротко, це внутрішній api, на який з тіста можна відправити запит і зробити деякі маніпуляції на боці додатка. Викликається він досить просто:

QaApiHelper::deleteUser(user_id);


Само собою, QaApi вміє працювати тільки з тестовими користувачами і доступний тільки через внутрішню мережу.

Коли тест навчився видаляти користувача за собою, він став працювати стабільно і чудово. Але так було не довго.

Етапи тестування Badoo

Про те, які етапи тестування існують в нашій компанії, ми розповідаємо практично на кожній конференції. Тут я коротко перерахую ті, які цікаві з точки зору selenium-тестів:
  • Тестування на девел-оточенні. Девел — це копія продакшену зі своїми базами і внутрішніми сервісами.
  • Тестування на шоти. Шот — це продакшен-оточення, доступне з внутрішньої мережі за певним урлу і є мержем коду майстра і досліджуваної задачі.
  • Тестування на стейджинге. Стейджинг, традиційно — це результат мержа гілки релізу і майстра.
  • Тестування на продакшені.


Спочатку ми ганяли тести на девел-оточенні і стейджинге. Однак, з часом, прийшли до висновку, що тести потрібно вміти ганяти і на шотах. Причина досить проста — девел не завжди ідеально копіює продакшн, а ловити баг на стейджинге і відкочувати завдання з релізу — погано. Це означає, що завдання в цей реліз вже не потрапить і поїде пізніше запланованого.

Другий selenium-тест на реєстрацію

Повернемося до нашого тесту. Уявімо, що ви — все той же QA-інженер, перед яким стоїть завдання навчити тест реєстрації працювати паралельно на декількох шотах і стейджинге.

Нагадаю, що шоти працюють в бойовому оточенні, тобто база користувачів у них одна. Цілком очевидно, що в поточній реалізації запускати тести паралельно не вийде. Якщо запустити два цих тесту з різницею в пару секунд на різних шотах, то другий спробує створити профіль Badoo тоді, коли його вже створив перший, і неминуче зламається:


Як вирішити нашу проблему? Як зробити так, щоб у тесту завжди був свіжий користувач FB?

Спочатку я спробував вирішити проблему мінімально просто. Створив mysql-табличку, в яку вніс кілька створених руками FB-користувачів і проставив їм статуси — вільні. Тест брав користувача з цієї таблички, міняючи йому статус на «зайнятий». Якщо вільного користувача не було, тест падав з відповідним повідомленням.

У цієї системи було кілька очевидних мінусів. Насамперед, якщо одночасно запущено занадто багато инстансов тіста, акаунтів не вистачало і взяти їх було нізвідки. Також тест міг з якоїсь причини не звільнити користувача в кінці (наприклад, якщо він був зупинений натисканням на «Ctrl+C»). Ніщо з цього не радувало вранці, коли до релізу залишалося менше години.



Досить швидко втомившись від нестабільних падінь і неконтрольованих станів FB-акаунтів, я почав шукати рішення краще…

The Graph API

У Facebook є чудовий api, який дозволяє створювати тестових користувачів і маніпулювати ними — developers.facebook.com/docs/graph-api. Організована вона досить просто: ми формуємо необхідний запит і посилаємо його на сервер FB, відповідь повертається в форматі json.

Приклад запиту, який зареєструє тестового користувача Alex:

https://graph.facebook.com/{APP_ID}/accounts/test-users?name=Alex&access_token={APP_ID}|{SECRET}
 


Application id secret ми отримуємо, реєструючи наш додаток на FB (докладніше тут — developers.facebook.com/docs/facebook-login/overview).

Цей пул Facebook користувачів

Що ж, давайте створювати користувачів! :)



Уважно вивчивши graph api і його особливості, ми склали список нюансів:

  • Кількість реєстрацій на один додаток обмежена. Цитата: «Для кожної програми можна створити не більше 2000 тестових користувачів.».
    Висновок: потрібно вести облік створених користувачів.
  • Тільки що створений тестовий користувач може взаємодіяти тільки з єдиним додатком. В даному випадку програма — це домен, на якому розмістився сервіс. В Badoo стейджинг і шоти знаходяться на різних доменах.
    Висновок: ведучи облік користувачів, їх необхідно розділяти на app id.
  • Користувач реєструється досить повільно. У середньому від 2 до 5 секунд.
    Висновок: зручніше мати заздалегідь створеного користувача FB, щоб тест не витрачав час на його створення.
  • Тест повинен мати справу з тим записом, який напевно не використовується в якомусь ще тесті, щоб уникнути флуктуаційних race condition.
    Цей пункт важливий у рамках описуваної тут тесту.


Загальна: було б круто мати кастомный пул користувачів FB, який відповідав би нашим «хотінням». По суті це повинна бути табличка, яка буде містити наступну інформацію:
  • Id користувача;
  • Email;
  • Password;
  • App id;
  • App Secret;
  • Стан користувача зайнятий тестом чи ні;
  • Timestamp створення користувача.


На додаток до цієї табличці нам знадобилося кілька скриптів.

Перший шукає в нашому пулі користувачів, які зайняті більш N хвилин і позначає їх як вільних. Це зроблено для того, щоб можна було використовувати не тільки в тесті (де можна прописати гарантований анлок користувача по завершенні роботи), але і для ручного тестування.

Другий вирішує проблему довгого створення користувача на стороні facebook. Виглядає це наступним чином:


Отримання FB-користувача ми обернули в спеціальний QaApi метод. Тест звертається до нього за вільним користувачем. Якщо такого немає, створюється спеціальне завдання. В рамках цього завдання скрипт посилає curl-запит до graph api, чекає відповіді і записує в таблицю нового користувача. Тест отримує відповідь — «необхідно почекати», закриває коннект і робить ще одну спробу через кілька секунд. Таким чином ми вирішили дві проблеми. По-перше, логіка роботи з graph api відокремлена від логіки тестів. По-друге, тести не тримають довгі коннекти до сторонніх сервісів, що суттєво полегшує дебаг будь-яких проблем, пов'язаних із збільшенням часу проходження тестів.

Далі ми переписали необхідні тести на нову систему отримання FB акаунтів і залишили тести ганятися на ніч нашому CI-сервером (ми використовуємо Teamcity). До ранку результат був готовий. Склалося рівно стільки користувачів, скільки було необхідно для використання у тестах.

У пулу є досить зручний інтерфейс методів. Він дозволяє в будь-який момент часу отримувати співвідношення вільних користувачів до загального на кожний додаток, отримувати кількість створених користувачів по даті. Це допомагає контролювати рівновагу пулу при додаванні нового тесту, що використовує FB-акаунти.

А чи є такий зручний API в інших соціальних мереж?

Я цікавився у хлопців з ВКонтакте:


І у хлопців з Однокласників:


Підсумок

На даний момент пул є невід'ємною частиною нашої системи. Навколо нього з'явилися нові скрипти і нові методи. Завдяки гнучкості і простоті систему зручно розвивати і контролювати.

Трохи про те, що вийшло в результаті:

  • Зручний інструмент для ручного та автоматизованого взаємодії Badoo з Facebook;
  • Більше 20 унікальних тестів, що використовують пул facebook-акаунтів: реєстрація/авторизація, верифікація, завантаження фотографій з FB-аккаунта, пошук друзів на Badoo, шарінг нагород і так далі;
  • У пулі 9 різних додатків, що використовують в цілому приблизно 1.5 до активних користувачів;
  • QaApi-методи вміють створювати FB-акаунти, робити їх друзями, заливати їм фотографію, асоціювати FB-акаунти з нашими тестовими користувачами;
  • Система сама підтримує необхідну кількість FB-акаунтів і найчастіше не вимагає ніякого ручного втручання.


За більш ніж рік використання api працював стабільно. Всього виникла проблема з токенами користувачів, але розробники facebook пофиксили її досить швидко. Кому цікаво детальніше — developers.facebook.com/bugs/1662068220677444.

На завершення хотілося б подякувати наших хлопців з розробки за їх неоціненну допомогу у створенні всієї цієї системи. Ви — молодці!

Спасибі за увагу!

Котов Віталій, QA-інженер з автоматизації.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.