Блеск и нищета автоматизации тестирования

в 10:40, , рубрики: wrike, автоматизация тестирования, автоматизирование веб-разработки, автоматизированное тестирование, Блог компании Wrike, Программирование, тестирование, Тестирование IT-систем, тестирование веб-приложений, Тестирование веб-сервисов, тестирование по
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 разряда

Автор: Wrike

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js