Стендап Сьогодні
📢
Канал в Telegram @stendap_sogodni
🦣
@stendap_sogodni@shevtsov.me в Федиверсі
Пости з тегом #ІнтеграційніТести
31.03.2025
Очікування в інтеграційних тестах
Хто що використовує для фіча-тестів? Я вже бозна скільки років на Capybara, та про інші фреймворки знаю тільки поверхнево. Але це показник того, що Capybara така хороша, що для Ruby on Rails нічого більше не потрібно.
Але гадаю, тема сьогодні незалежна від інструмента. Фіча-тести ніколи не є на 100% стабільними. Графічний інтерфейс це вже складно, а коли його автоматизувати, то складність тільки помножується. Тому багато фіча-тестів дають хибу, але не кожного разу — а випадково.
Виправляти хиби важко, бо це ще й доводиться робити пізніше, коли контекст втрачений. (Ідея: якось зробити, щоб тільки що додані тести запускалися багато разів, для виявлення випадкових хиб.) Та що люди першим роблять: додають очікування. У випадку з Capybara це зажди помилка, оскільки Capybara чекає результатів автоматично.
Але то якщо правильно писати тести. Наприклад, Capybara чекатиме тільки всередині перевірок. Якщо просто звертатися до елементів, то невідомо, чого саме чекати. Ще є класична помилка expect(page).not_to have_content
: тут Capybara не знає, що потрібно чекати, поки зміст зникне. Правильна форма - expect(page).to have_no_content
.
До того ж очікування не розвʼязують питання послідовності дій. От виправляв тільки-но помилку, де сценарій інколи стартував ще до того, як компонент React встигне перемалюватися з даними. В такому разі перший крок сценарію затирався. Я собі стільки морочив голову над поведінкою та можливими проблемами з кнопкою SVG, а виявилося, що лише треба було на початку почекати правильного стану.
05.05.2025
Середовища для тестів та для розробки
От вже не знаю, наскільки це поширено, але в Rails в тебе локально завжди є два екземпляри середовища. Одне — для розробки - development
- містить сталі дані. Друге — для тестів - test
- витирається начисто на кожний запуск тестів. В “середовище” завжди входить база даних, але також може бути кеш, набір файлів тощо. Ну, та ще й належна конфігурація.
Це взагалі дуже корисна ідея, та якщо у вас такого нема, раджу спробувати. Хоча не завжди легко й одне середовище зробити, не те що копію. Багато залежить від того, наскільки у вас параметризований код.
Але я навіть не про те хотів сказати. Я, з подачі колеги, ось що згадав: інструменти для налаштування тестового середовища значно зручніше, ніж робочого. Причина проста — тестове середовище ми відтворюємо багато-багато разів, а робоче… ну може коли новий працівник приходить, чи після якоїсь катастрофи. Гарно, коли для розробки є скрипт (в Rails це seeds.rb
), але за досвідом він майже завжди застарілий, бо його майже не використовують. Та й локальне оточення буде застарілим, якщо єдиний спосіб його оновити — це все перестворити наново.
Тому я вже давно, якщо потрібно зробити ілюстрацію якогось стану в застосунку, відтворюю той стан в тестах. Або просто роблю знімок екрана прямо з тесту, який вже написав. Це швидко, а головне, я можу відтворити стан скільки завгодно разів.
А якщо піти далі (що й пропонував колега), то можна запустити інтеграційні тести з відкритим браузером, а посередині поставити на паузу та далі взаємодіяти із застосунком в потрібному стані.
Все це наводить на думку… може до середовища для розробки треба ставитись схоже? Не підтримувати повністю готове оточення, а мати інструменти для його створення — ті ж фабрики, як в тестах. Або додумати підхід із використанням тестів як трампліну для ручної перевірки. Цікаво.
12.05.2025
Міграція інтеграційних тестів: погана задача для ШІ
Передісторія. Десь у 2019 зʼявився Chrome DevTools Protocol - протокол поглибленого керування браузером. Наприклад, він дозволяє прямо встановити кукі, або зробити знімок екрана. Гарна річ, дозволяє позбавитись посередника для автоматизації браузера. Зокрема (але не тільки) для інтеграційних тестів.
Невдовзі вийшов гем Cuprite для тестів на Ruby, який дозволяв позбавитися Selenium. Selenium - не найстабільніший пакет на світі, тому тоді це сприйняли з радістю та мігрували. Радикального виграшу не отримали, хоча поглиблене керування стало в пригоді. Минуло 6 років, та Cuprite так і не переміг Selenium, а до того ж його не дуже гарно підтримують. Інтеграційні тести, на жаль, це така галузь, де вчасна підтримка все вирішує, бо Chrome оновлюється постійно та десь щось ламає. От і зараз це стало великою проблемою… можна було б переїхати назад на Selenium, тільки це проблема ще більша. Питання: чи допоможе із цим впоратись ШІ?
Виправлення, широко кажучи, можна поділити на 3 категорії.
Різниця в пробілах. Для зручності в Capybara можна перевіряти не тільки сухий DOM, але і його текстовий зміст. Кожний із рушіїв по-своєму його будує (зверну увагу, що ніякого стандартного способу тут немає.) Це веде до купи абсолютно тривіальних помилок вигляду Foo\nBar
замість Foo Bar
. Я думав, що ШІ тут легко все поробить, але ні. Часто він або не розумів задачі, або заміняв надто багато, вигадував своє. Зробив висновок, що ні — дрібні, розсипані по коду виправлення ШІ робить погано. Я сам швидко зʼясував природу змін… от тільки робити їх вручну все одно довго та нудно.
Зміна API В Selenium за ці роки зʼявилася підтримка CDP. Втім, звісно, виклики не збігаються. Умовно, замість driver.set_cookie
треба писати driver.devtools.network.set_cookie
, та ще й термін передати числом, а не датою. Я сподівався, що “перероби на API Selenium” пройде, але ні. Навіть коли додав “читай цю сторінку із прикладами”. Зрештою виявилося, що я вручну з масовою заміною можу адаптувати виклики швидше, ніж вигадувати запит до ШІ.
Складніші зміни. Взагалі, мій перший план був такий: забирати з CI журнал невдалих тестів та передавати до Claude із додатковими інструкціями. Окрім вище описаних змін, були й менш зрозумілі. Наприклад, деколи Selenium відпрацьовує швидше (чи не чекає чогось?) та перевірка випереджує стан. Тут ШІ робив якісь незрозумілі кроки. Зокрема - спрощував тести, щоб ті проходили. Тобто з масовим виправленням без людського втручання точно успіху немає.
Якщо підсумувати, то ця міграція, про яку мені навіть казали “так може ШІ це швидко зробить?”, так і залишилась великою та складною задачею.
30.05.2025
Я втомився від Capybara
В Ruby on Rails надто зручна система для інтеграційних тестів — з Capybara. Вона дозволяє керувати браузером з Ruby. Та це чудово. Можна поєднувати в одному файлі будь-які налаштування застосунку та бізнес-логіки та всі можливості браузера.
Бо знаєте, не всякі побічні ефекти можна прочитати не те що з інтерфейсу, а навіть з API. А у нас, оскільки інтеграційні тести повністю на Ruby, то можна все що завгодно перевіряти. Стан бази та інших систем — звісно. Але також легко замокати все що завгодно та перевіряти, що відбулися очікувані виклики.
А ще в Capybara приємний DSL, абстрагований майже від всіх нюансів вебсторінок. (Хоча за потребою можна й спуститися на низький рівень чи навіть виконувати JavaScript.)
Такі зручності формують стиль тестів, де браузер для нас — лише ще один спосіб перевірки. Тобто головний фокус тестів залишається на застосунку, єдина різниця що для цих тестів ми ним керуємо з браузера — на відміну від юніт-тестів, де код викликається напряму, та тестів запитів, де ми робимо прямий запит до API застосунку.
Але браузер — річ складна та хаотична. Абстракція тече, та замість простих “перевірок браузером” ми починаємо латати в ній дірки. Хоч є багато системних покращень (як-от Capybara вже давно вміє автоматично чекати, доки на сторінці зʼявиться зміст, який ми перевіряємо), але код тестів вкривається латками все одно.
Минає час, та ми отримуємо незграбну, незрозумілу масу коду, який ще й все одно регулярно дає хибу.
Який я можу зробити висновок… Capybara була чудовим інструментом на той час, коли JavaScript був рідкістю (так, колись взагалі окремо виділяли тести, яким він потрібний — решта навіть браузер не запускала!) Але зараз фокусом інтеграційних тестів є застосунок JavaScript, та набагато легше було б їх писати не на Ruby, а наближено до браузера — тобто в Cypress чи Playwright тощо. Тим паче, що для них вже давно зробили інтеграції, які вміють запускати фабрики, а то й довільний код на Ruby.
12.06.2025
Capybara + Playwright: мрії здійснюються?
Не встиг я написати, що втомився від Capybara, як натрапив на незнайому мені досі бібліотеку capybara-playwright-driver. Так, це саме те, як що воно звучить: драйвер для Capybara через потужності Playwright - одного з передових інструментів інтеграційного тестування.
(До речі: знайшов я цю бібліотеку з іншого проєкту - capybara-lockstep - він стабілізує тести через неявне примусове очікування кожної операції. Але з нею досвіду не дуже маю.)
Отже, Capybara із Playwright, за досвідом, працює непогано — порівняно з Selenium, значно більше можливостей та менше місць, де доводиться робити криві обходи. Наприклад: є метод route для легкої підміни запитів з браузера. Дуже корисно для всяких сторонніх інтеграцій. Або Download - для перевірки завантажень. Це взагалі ексклюзив!
Також, оскільки цей драйвер керує звичайним сеансом Playwright, ми можемо трасувати тести, тобто зберігати повний хід виконання, включаючи всі запити до мережі, всю консоль, навіть стан DOM в кожний момент тесту! Це астрономічно більше інформації, ніж дає Capybara.
Втім, трасування виказує й недолік цього драйверу. Він використовує Playwright на простому, низькому рівні. Наприклад, в Playwright є власне очікування операцій — та дуже гарне. Але щоб зберегти поведінку Capybara, драйвер не користується ним, а тільки виконує команду перевірки багато разів.
Тут же ж є й альтернатива: пакет plsywright-ruby-client, на якому збудований драйвер. Він вже дає безпосередній доступ до дій та перевірок від Playwright. Тобто теоретично можна викинути капібару та писати тести прямо на Playwright, але з Ruby! Та зі збереженням повними можливостями підготовки стану та перевірки результатів на бекенді.
Поки я в захваті від цього нового підходу, та сподіваюся, він закриє частину недоліків Capybara. Одне тільки трасування чого варте.