Блиск і злидні автоматизації тестування

image

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

Не варто списувати таке положення справ на некомпетентність, дурість або банальну лінь розробників. Порівняно з ручним тестуванням, автоматизоване має як достоїнства так і явні недоліки. Якщо б були одні тільки плюси, і говорити було не про що.


Переваги автоматичних тестів

Автоматизоване тестування має ряд суттєвих переваг порівняно з ручним тестуванням.

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

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

Швидкість — автоматичні тести виконуються на порядки швидше, ніж ті ж перевірки, виконані вручну. Звичайно, бувають і порівняно повільні тести, але це швидше виняток, що підтверджує правило.

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

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

Переваги ручного тестування

Ручне тестування, тим не менш, перевершує автоматизоване по багатьом аспектам.

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

Гнучкість — ручне тестування можна проводити набагато різноманітніше, і зміна способу тестування практично нічого не коштує. Давайте протестуємо Safari — будь ласка, на Chromebook — немає проблем, IE6 — доведеться запустити віртуальну машину, але теж можна.

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

Креативність — ручне тестування дозволяє знайти проблеми, які заздалегідь не були відомі, більше того, навіть не передбачалися.

Осмисленість — хоча кожна річ окремо може бути абсолютно коректна, люди набагато легше розуміють, що разом ці речі не мають жодного сенсу.

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

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

Блиск парадоксів тестування

Говорячи про тестуванні, і тим більше про повну тестуванні, ми трохи лукавимо. Очевидно що перевірити всі неможливо.

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

Витративши на тестування 1 день, ми доб'ємося 90% задоволених користувачів. Тестуючи тиждень — 99%, тестуючи місяць 99.5%. На досягнення все меншого і меншого результату ми витрачаємо все більше часу. Це недоцільно.

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

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

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

Ситуація докорінно змінюється в тривалій перспективі. Код програми необхідно рефакторіть, щоб він не помер. Коли програмісти все переробили — тестувальники повинні все перевірити. Повний цикл регресійних тестів. Тиждень? Дві? Місяць? Або ще гірше: програмісти оновили версію ключовий бібліотеки. День роботи, начебто все компілюється — відмінно! І все одно тестувальники повинні перевірити всі. Божевілля. Пройшовши через таке кілька разів, будь-буде готовий піти на що завгодно, лише б уникнути подібних ситуацій в майбутньому. Для забезпечення стабільного базового рівня якості необхідно вкладатися в автоматизацію тестування.

На жаль, автоматичні тести не завжди є рішенням, іноді вони самі стають проблемою.

Злидні автоматизації тестування

Проблема: потрібно вміти перевіряти додаток повністю і швидко, нічого не втрачаючи, багато разів підряд.

Рішення: написати автоматичні тести, які все це роблять.

Але не все так просто.

Написання тестів — це розробка, точно така ж, як і розробка основний бізнес-логіки. Вона вимагає ресурсів і кваліфікації. Забезпечуючи якісне покриття коду програми тестами ми одночасно сповільнюємо розробку як таку. І сповільнюємо не на 10%, а вдвічі, втричі чи навіть більше.

Швидкість — поняття відносне. Кожен конкретний тест, звичайно, виконується дуже швидко, особливо чисті unit-тести, коли всі перевірки відбуваються локально. Інтеграційні тести, REST-тести теж порівняно швидкі. Що таке 100 мілісекунд, ну нехай навіть 1 секунда, навіть десятки секунд для selenium тестів — дурниця в порівнянні з ручним тестуванням. Але коли кількість тестів хоч скільки-небудь істотно, швидкі тести виявляються дуже повільними. Прогін тестів за 5 хвилин? Півгодини? Три години? Два дні? Ще навіть не домігшись повноцінного покриття бізнес-логіки, серйозно постає питання про те, як запускати не всі тести, або запускати тести не кожен раз — інакше вже автоматичні тести починають гальмувати розробку.

Примітка: Тести можна суттєво прискорити, вклавшись в залізо — виділити під них окремий сервер, 10 серверів, 50 і т. д. Деякі компанії можуть дозволити собі і 1000 тестових серверів, але далеко не все.

Інструментарій поганий. Жодна з мейнстрімних платформ програмування не проектувалася з метою забезпечити можливість максимально просто і повноцінно розробляти тести. В Java всі тестові фреймворки є сторонніми бібліотеками. Запуск тестів, здійснення перевірок, створення mock-об'єктів — все це є, але по частинах і поза платформи. В Go тестовий фреймворк вже додали в екосистему мови спочатку, але це лише запуск тестів. Вибір відповідного інструментарію для написання тестів це окрема проблема, яка потребує вирішення.

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

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

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

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

Кількість тестів оманливе: 3000 тестів в сумі — веб-інтерфейс, REST API, бізнес-логіку та юніт-тести — можуть перевіряти з натяжкою 1000 ситуацій. Все інше — дублювання.

Автоматична регресія не скасовує ручну всупереч головним задумом. Все тому що автоматичні тести перевіряють багато чого, але далеко не все. Але що конкретно вони перевіряють, а що ні — ніхто не знає. Нам потрібно перевірити реєстрацію. А ще у нас є 18 927 тестів. Якщо якийсь із них червоний — «все добре», можна повернути завдання до розробників — нехай розбираються. Якщо всі тести зелені — це нічого не значить, до тих пір, поки людина, що відповідає за ручне тестування, не буде впевнений, що з логіки реєстрації перевіряється автоматично, а що ще потрібно перевірити вручну. А тестів майже двадцять тисяч — це неможливо розібратися. Результат — перевірити вручну потрібно все.

Недивно, що деякі йдуть з розробки продавати пластикові вікна, навчати більярду або варити каву (і це все реальні випадки).

Про те, які висновки ми в Wrike зробили з власних і чужих помилок, розповім в наступному пості.

Дмитро Мамонов

Департамент розробки,
Підрозділ мержа у майстер,
Відділ роботи з гіт,
Провідний оператор баш консолі 1 розряду

Джерело: Хабрахабр

0 коментарів

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