Блеск и нищета автоматизации тестированияИсточник: habrahabr Дмитрий Мамонов
Принято считать, что наличие автоматических тестов - это безусловное благо. Если разработчики пишут тесты - это хорошо, чем больше тестов, тем лучше. При этом, в реальности их чаще не пишут, а все тестирование делают вручную. Не стоит списывать такое положение дел на некомпетентность, глупость или банальную лень разработчиков. По сравнению с ручным тестированием, автоматизированное имеет как достоинства так и явные недостатки. Если бы были одни только плюсы, и говорить было бы не о чем.
Преимущества автоматических тестовАвтоматизированное тестирование имеет ряд существенных преимуществ по сравнению с ручным тестированием. Дешевизна - прогон автоматических тестов всегда дешевле ручной проверки на несколько порядков. Разработка автоматических тестов конечно дороже разового ручного тестирования. Неутомимость - автоматические тесты можно запускать снова и снова, у них неограниченный рабочий день, они не устают, и не болеют. Скорость - автоматические тесты выполняются на порядки быстрее, чем те же проверки, выполненные вручную. Конечно, бывают и сравнительно медленные тесты, но это скорее исключение, подтверждающее правило. Точность - автоматические тесты проверяют ровно то, что описано в сценарии, во всех деталях и мелочах. Они не отвлекаются, не путают и не забывают. Всеобъемлемость - автоматические тесты позволяют покрыть огромное количество сценариев и находить наведенные ошибки в таких далеких углах приложения, до которых ручной тестировщик никогда бы не добрался, кроме как случайно.
Преимущества ручного тестированияРучное тестирование, тем не менее, превосходит автоматизированное по многим аспектам. Проворность - проверить что-то вручную в первый раз легко и быстро. Автоматический тест нужно прежде разработать. Практически всегда это гораздо медленнее ручной проверки. Гибкость - ручное тестирование можно проводить гораздо разнообразнее, и изменение способа тестирования практически ничего не стоит. Давайте протестируем в 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 тестов. Если какой-то из них красный - "все хорошо", можно вернуть задачу к разработчикам - пусть разбираются. Если все тесты зеленые - это ничего не значит до тех пор, пока человек, отвечающий за ручное тестирование, не будет уверен, что из логики регистрации проверяется автоматически, а что все еще нужно проверить вручную. А тестов почти двадцать тысяч - в этом невозможно разобраться. Результат - проверить вручную нужно все. Неудивительно что некоторые уходят из разработки продавать пластиковые окна, обучать бильярду или варить кофе (и это все реальные случаи). |