Image for post
Image for post
Author: xotabu4

Мій топ анти-патернів у автоматизації тестування

Більшість своєї кар’єри я займався автоматизацією тестування. І за цей час зібралось декілька речей у нашій сфері, які бісять. Частина з них є організаційна, частина — технічна.

Цей список містить моє особисте бачення. Можливо, у певних умовах, якісь з цих “анти-патернів” можуть бути виправдані. Але у моєму досвіді так не було, і я спробую пояснити чому.

Автоматизація відділена від команд

Іноді автомейшн інженери нагадують мені системних адміністраторів. Ніхто не знає, що вони роблять, але всі знають, що вони щось роблять. Те саме і з автоматизаторами.

Ми часто робимо роботу, яка цікава лише нам. Пишемо тести за котрими слідкуємо лише ми.

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

Так не повинно бути. Тести (будь які) повинні приносити цінність для всіх учасників команди, і у першу чергу — розробникам. Лише за допомогою тестів вони дізнаються чи поламали щось чи ні.

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

Не займатись тест дизайном

Дуже часто я чую підхід, коли тестувальники пишуть “тест кейси”, а автоматизатори їх автоматизують. У мене був випадок, коли у такому тест кейсі потрібно було відкрити Notepad і записати якісь дані. І автоматизатор повністю повторив ці дії, хоча міг ті самі дані зберегти у змінній. Ну бо ж у тест кейсі було написано про Notepad.

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

Варто зазначити, що у класичних тест кейсах переважно не враховують речі, котрі зробити автотестом простіше. Це як з прикладом про Notepad. Іноді автотест може уникнути якихось кліків чи переходів. Або, декілька перевірок у одному тесті— у автотестах це буде переважно антипатерн, але у звичайних тест кейсах — “йоой, най буде”. Людина котра пише тест кейси, часто може не бути в курсі цих деталей. І у вас виникнуть розбіжності між автотестами та тест кейсами.

Вирішення такої проблеми — більше колаборації. Автоматизатор повинен бути також залучений до процесу написання тест кейсів, а тестувальник більше розуміти як виглядають автотести, і що вони можуть спростити чи ускладнити. Не бійтесь обмінюватись зонами відповідальності.

Покривати все автотестами

Існує думка, що якщо написати максимум UI чи API автотестів — багів не буде. Покривати все автотестами, у більшості випадків, буде надлишково.

  • Ви витратите багато часу на покриття тестами логіки, які рідко, або ніколи не змінюється. Але на написання та підтримку такого тесту може йти багато часу, а цінності від такого тесту мало. Я про тести, на кшталт, перевірити повідомлення, що у поле “Name” не можна ввести більше N символів. Повідомлення таке може рідко змінюватись, та і юзери не часто пробують ввести у поле Name 25 тисяч символів. Звісно, це все дуже залежить від контексту і десь подібний тест важливий
  • Велика к-сть автотестів збільшує ймовірність нестабільних тестів. Коли тести нестабільні і завжди червоні, ніхто не хоче з ними розбиратись та реагувати на падіння. Краще мати менше тестів, але стабільних

Варто більше звернути увагу на тести нижчих рівнів (unit, integration, etc). Там простіше і надійніше покривати різні edge cases.

Я стараюсь обирати для автотестів сценарії юзерів або основні бізнес області додатку. Важливіше бути в курсі, чи користувач зможе виконати свої стандартні задачі, ніж перевірити всі edge case-и.

Писати фреймворки

У вас було таке, що ви витрачаєте тиждень\місяць\рік на те, щоб написати “фреймворк” — десятки допоміжних методів, будуєте структуру PageObject-ів, котра повинна бути універсальна. І при тому, що тестів ще немає. Жодного тесту. А пізніше, ваша універсальна структура, виявляється не універсальною і доводиться дописувати новий велосипед, або переписувати все. Ще бачив випадки, коли для такого наймали зовнішніх консультантів.

Проблема у тому, що “фреймворк” повинен народжуватись навколо тестів, роблячи їх простішими. А не навпаки — тести навколо фреймворка.

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

Все наперед ви не зможете написати. Існує принцип YAGNIYou Aren’t Going to Need It. Власне, написання таких фреймворків порушує його.

У світі автотестів є багато готових фреймворків на базі WebDriver чи інших інструментів. Я про Selenide, NSelene і десятки інших.

Основне — пишіть спочатку тести, а вже пізніше покращуйте їх своїм “фреймворком”

Розводити зоопарк технологій

Мені дуже не подобається коли, наприклад, на .NET проект, тести починають писати на Python. На це повинна бути об’єктивна причина.

Але коли причина “хочу вивчити пайтон” або “ну я раніше пайтон юзав” — так собі причина.

Зоопарк технологій на проекті породжує наступні проблеми:

  • Потрібно підтримувати декілька екосистем
  • Проблема взаємодії між розробниками та тестувальниками. Коли розробники пишуть на мові А, а тестувальники на мові В, то їх важче буде змусити співпрацювати.
  • Інтеграція між технологіями. Маючи одну і ту ж платформу чи мову програмування, можна легко інтегрувати додаток і тести у один CI. Також, можна перевикористовувати спільний код чи бібліотеки

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

Тестувати 3rd party додатки

На одному проекті перевіряли функціонал надсилання листів. І для цього було написано декілька PageObject-ів для Gmail. Власне, потрібно було лише перевірити чи листи були надіслані, але ці сценарії в той же час допомагали Google з тестування Gmail :)

У випадку якщо ваша система має інтеграцію з 3rd party сервісами, їх потрібно уникати по максимуму. Якщо можна — використовуйте якісь заглушки чи фейки. Якщо ні — спробуйте працювати з цими сервісами за допомогою їхнього API.

У випадку з поштою — підніміть краще поштовий сервер у себе, так ви уникнете залежності на чужий сервіс. Ваші тести не будуть падати, бо “їхній” сервіс лежить.

Будувати “ручну” автоматизацію

Ваші тести самодостатні ? Після або перед запуском тестів потрібно щось налаштовувати “ручками” ? Вони запускаються автоматично ?

Неодноразово бачив як для запуску тестів потрібно запускати якісь скрипти чи чистити базу даних. Або після виконання тестів.

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

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

Писати гігантські тести

Якось я бачив тест на 500 рядків. І це жах. Підтримувати такий тест дуже важко, занадто багато хитких моментів.

Причин появи таких тестів можуть бути дві :

  • Тест у якому хочеться перевірити ВСЕ або дуже багато — у такому випадку, тест потрібно розбити на декілька менших. Хороша практика — один тест, одна перевірка.
  • Тест у якого дуже складні передумови, потрібно багато налаштувати щоб досягти такої умови. На подібне, я бачу 2 рішення : або шукайте можливість спростити ці умови, або подумайте, чи дійсно такий тест потрібен. Зусилля на його підтримку можуть перебільшувати цінність, яку приносить вам тест.

Писати “прямолінійні” тести

Уявіть UI тест, котрий перевіряє функціонал, для відкриття якого потрібно пройти декілька меню. І ваш тест повинен перевірити суто роботу цього функціоналу. Можливо, має сенс, щоб уникнути всі оці меню використовувати deep link для переходу до потрібного функціоналу ? Нас же не цікавить саме шлях, яким користувач дійде до цього меню, цей шлях перевіряє інший тест.

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

Або, інший приклад:

Тест на перевірку magic feature:

Юзер А робить запит до юзера B

Юзер B підтверджує запит

Юзер A виконує magic feature

У цьому тесті, для нас важливий третій крок. Перші два кроки це передумови. Я часто бачив подібні UI тести, і там все було через UI. Але по суті, нам потрібен лише третій крок перевірити. То може ми перші два кроки виконаємо за допомогою API ? Це ж зекономить нам купу часу.

Власне, ідея, яку я хочу донести цим пунктом — якщо у автотестах можна замінити дії через UI на щось інше (API, JS events, test hooks, deep links, etc) і воно не впливає на кінцевий результат , скористайтесь цим. Так, воно не буде як з точки зору кінцевого користувача, але технічно код буде виконуватись той самий. Сервер оперує HTTP запитами і він не знає(та і байдуже йому) хто його надіслав — ваш код чи веб сторінка.

Низькорівневі тести

На мою думку, тести повинні бути орієнтовані більше на поведінку кінцевого користувача і менше на технічні деталі реалізації.

Типовий приклад — форма логіну. Уявімо, стандартну форму логіну, яка складається з полів ‘userName’, ‘password’ та кнопки ‘login’.

Дуже часто, у тестах напряму працюють з цими трьома елементами.

loginPage.userName = 'Oleg';                       
loginPage.password = 'password'; loginPage.ClickLogin();

Багато хто скаже, що так дуже добре видно конкретні дії користувача. Але я вважаю, що такі дії краще інкапсулювати в один метод, який буде виконувати конкретну бізнес дію.

loginPage.Login('Oleg', 'password');

Таким чином, тест буде більш високорівнений і код набагато чистіший. Високорівневість дасть кращу читабельність та розуміння логіки. Бо те, що ми бачимо заповнення якихось полів, може бути не дуже інформативним для нас.

Summary

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

Цією статтею я переслідую ціль — переглянути існуючі підходи до автоматизації тестування та спробувати робити їх більш ефективними.

P.S.

Дякую, що ви прочитали цю статтю. Я хочу бути максимально корисний Вам і тому, витратьте ще 1 хв на заповнення форми фідбеку. За це вам плюсик у карму !

Вирішив писати про ІТ українською

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store