Software testing

Последнее время наблюдается тенденция к отказу от ручного тестирования в пользу полной автоматизации. Стоит разобраться, возможно ли это и насколько это хорошо. Для этого рассмотрим плюсы и минусы обоих видов тестирования, а также области их применения с точки зрения потребностей заказчика.

Автоматическое тестирование – очевидные плюсы и менее очевидные минусы

Стоит начать с того, что нагрузочное и стресс-тестирование — это практически всегда автоматическое тестирование. Будь то скрипты JMeter, LoadRunner или какие-либо специальные скрипты и приложения, написанные для тестирования конкретного продукта — всё это автотест. Как правило, создать требуемую нагрузку для серверной части вручную практически невозможно, если не привлекать для этого тысячу инженеров.

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

Ещё одна область, где скрипт предпочтительнее человека, — это тесты с точными замерами. Например, проверить точный цвет некоторых элементов, замерить расположение элементов с точностью до пикселя, замерить время анимации или обработки события до миллисекунд и тому подобное. Хотя часть из этого и может быть выполнена вручную, скрипт сделает это значительно быстрее и точнее.

Однако при своих достоинствах автотесты не лишены недостатков. Требуя для написания и поддержки более дорогостоящих специалистов, они обычно более затратны по времени, уходящему на их создание. При этом, если продукт меняется, то необходимо обновление регрессионных тестов, что может отнять значительное время. Небольшая ошибка в архитектуре проекта, например, отсутствие однозначных локаторов элементов на странице, может затруднить разработку автотестов. Небольшая ошибка в архитектуре самих тестов, например, захардкоженные последовательности или локаторы, вместо выделения их в функции и параметры, может потребовать огромных трудозатрат при обновлении тестов после внесения изменений в функционал продукта. Словом, продукт должен быть изначально архитектурно предназначен для тестирования автоматическими тестами, что означает дополнительные расходы на разработку.

Автоматические тесты порой дают некорректные результаты из-за самого факта работы инструмента автотеста на тестируемом оборудовании. Например, они могут отъедать процессорное время и память, тормозя работу тестируемого приложения или сервиса, могут конфликтовать при доступе к файлам, базам данных, оборудованию. Всё это иногда приводит к проваливанию тестов там, где в нормальных условиях всё работает. Бывают и экзотичные обратные случаи: запущенное тестовое ПО, занимая ресурсы системы, позволяет асинхронному коду выполняться корректно, в то время как на незагруженной системе можно получить рассинхронизацию и ошибки. Таким образом, автотест будет давать положительный результат там, где ручное тестирование сразу найдет проблему.

Другой интересный пример кейса, который нельзя просто так автоматизировать: при тестировании системы безопасности есть сценарий, где пользователю показывается модальное окно, с которым он может взаимодействовать. Однако никакое другое приложение его не видит. Это сделано специально именно для того, чтобы ни одно приложение не могло вмешаться в работу системы безопасности и скрыть сообщение прежде, чем его увидит пользователь.

Ещё одним очевидным ограничением автотестов являются сценарии, в которых требуются физические действия от тестировщика. Например, иногда необходимо переключать разъёмы, подключать и отключать устройства, физически перемещать оборудование или изменять состояние его датчиков температуры, влажности и тому подобное. То, что достаточно легко может сделать тестировщик во время ручных тестов, порой оказывается тяжело автоматизировать. Такие действия могут требовать установки дополнительных реле и системы управления ими, сервоприводов для наклонов устройства, сложных решений для управления температурой и влажностью среды. Все это окупится только при постоянном применении подобных решений на протяжении длительного срока. Это больше соответствует задачам завода, производящего оборудование, а не компании, занимающейся разработкой ПО для него.

Неочевидным, но серьезным недостатком автотеста является то, что он способен выявить только те проблемы, которые явно смог предусмотреть автор теста. В то же время при ручном тестировании инженер всегда смотрит на всё, что окружает тестовый сценарий и может заметить «поехавшую вёрстку», проблемы при переходе между экранами приложения, ошибки, возникающие в стороне от основного сценария. Создать автоматические тесты, предусматривающие все подобные классы ошибок для большинства видов ПО на данный момент практически невозможно. Таким образом, может возникнуть ситуация, когда большой и качественный набор автотестов, выполняемый на регулярной основе, создаёт ложное чувство защищённости от ошибок, упуская на самом деле странные дефекты, которые бы сразу заметил любой «ручной» тестировщик.

Сильные и слабые стороны ручного тестирования

Ручное тестирование практически всегда дешевле для коротких проектов длительностью менее года. Да, «ручные» тестировщики обычно дешевле «автоматизаторов». Порог входа в специальность здесь заметно ниже и найти таких «ручных» инженеров значительно легче «автоматчиков». При этом опытный инженер может начать «исследовательское тестирование» продукта практически сразу после его получения и ознакомления с минимальным набором инструкций или документации, начальные результаты и некоторые дефекты можно получить иногда уже в первый день работы, что практически недостижимо для автоматических тестов.

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

В некоторых случаях нет возможности жёстко задать результат теста. Например, при отсутствии барокамеры нельзя написать тест для датчика давления, который бы говорил, что система должна показать ровно 746 мм р.с., т.к. реальное атмосферное давление постоянно колеблется. В лучшем случае, тест будет требовать соответствия показаний датчика и независимого сертифицированного барометра, причём с заданной точностью.

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

Недостатки ручного тестирования вполне понятны и очевидны. Ручное тестирование выполняется значительно медленнее автоматического. Порой это может занять пару недель вручную вместо одного часа скриптом, в других случаях может соотношение может колебаться в меньших пределах. При этом хорошо написанный скрипт не ошибается и не пропускает дефекты, устав от однообразной рутины день за днём, в отличие от инженера. Вручную практически невозможно выполнять сценарии, требующие большой скорости действий или крайне высокой точности по времени.

Подводим итоги

Исходя из вышеперечисленного, можно довольно чётко очертить границы применения обоих подходов. Автоматизация нужна для нагрузки и стресс-тестов, для накапливающейся массы регрессионных тестов, для проверки особо крупных массивов однообразных тестов. Автоматизация требует дорогостоящих инженеров, много времени для получения первых результатов и, зачастую, изменений в самом тестируемом продукте, что повышает объём работ для команды разработки. Кроме того, автоматизированные тесты предъявляют требования к архитектуре продукта и внимательности при написании тестового сценария.

Ручное тестирование нужно для проверки юзабилити, документации, кейсов с нечёткими ожидаемыми результатами, исследовательского тестирования и т. п. Ручное тестирование дешевле и может давать первые результаты почти сразу после начала работ. Поддержка ручных тестов при частых изменениях функционала значительно проще и быстрее. В то же время, ручные тесты требуют больше времени на исполнение, а риск «человеческого» фактора возрастает (люди устают и отвлекаются).

Автоматические тесты лучше всего справляются с задачей вида «подтвердить, что продукт соответствует требованиям», в то время как ручные тесты значительно лучше в задаче «найти проблемы и узкие места». Таким образом, эти два подхода ни в коем случае не должны исключать друг друга, а должны дополнять и использоваться уместным образом. Если какая-то часть функционала постоянно проверяется автотестами в рамках регрессии, то стоит всё же иногда заглядывать в неё ручными тестами.

Вячеслав Ванюлин, Генеральный директор Ауриги, поделился своим мнением о ручном тестировании в медицинской отрасли:

«Несмотря на то, что лично я сторонник автоматизации, ручное тестирование играет большую – и даже незаменимую – роль для некоторых задач. Идет ли речь о тестировании юзабилити или документации, задачах с нечеткими требованиями или, скажем, исследовательском тестировании – и без ручного тестирования не обойтись. Тем более, что, как правило, сами ручные тестировщики дешевле и результаты выдают практически сразу, как только приступили к работе. Обратившись к высококлассным специалистам, вы получите гораздо больше, чем просто ручное тестирование. Но как отличить профессионала от того, кто еще «не нюхал пороха»?

Три наиболее важных качества тестировщика, без которых никуда:

  • он должен быть уверенным бизнес-пользователем, который может проверить работу основного функционала;
  • он должен понимать внутреннюю архитектуру продукта и взаимозависимости;
  • он должен, прочтя release notes, пристально пробежаться по последним изменениям, включая зависимости

Это, конечно, база, применимая к любому мало-мальски серьезному проекту. Как только речь заходит о тестировании медицинского прибора, который завтра будет стоять в отделении реанимации и отвечать за жизнь пациента, одной этой базы будет мало. В компании «Аурига» мы используем термин Intelligent testing – умное тестирование. Такое тестирование предполагает, что инженеры на проектах проходят дополнительные тренинги по специфике оборудования и стандартам отрасли; они должны разбираться в приборной экосистеме, природе различных сигналов, зависимостях, критических значениях показателей. Обычно они еще и выступают в качестве квалифицированного бизнес-пользователя, т.е. медицинского персонала – чтобы проверить как работает прибор требуется понимание основных сценариев работы продукта. Правильно подобранная сбалансированная команда зачастую становится наиболее важным фактором успеха всего проекта. Мы в Ауриге гордимся тем, что умеем выстраивать и управлять подобными командами, избавляя заказчиков от лишней головной боли».

Как всё это работает в действительности?

Ситуация на проекте одного из крупных заказчиков Ауриги может послужить неплохой иллюстрацией, почему ручные тесты остаются нужными даже на проекте, который развивается уже почти два десятка лет.

Первая и главная причина, о которой все сразу говорят — это унаследованное ПО и тесты. Изначально на этом проекте делалось только ручное тестирование, накопился огромный пул регрессионных тестов, и заказчик пока не спешит отказываться от них в пользу автоматизации.

Тем не менее, при детальном рассмотрении выясняется, что автоматизация на проекте уже есть, в неё ушла довольно значительная часть тестов, ранее бывших ручными. Если сравнить оставшиеся тесты с автоматизированными, можно выявить главное различие. Все автотесты представляют из себя массивы тест-кейсов, различающихся только данными, но использующих один скрипт, один фрагмент кода. Т.е. на одну сотню кейсов есть всего несколько строчек кода, а остальное — параметры из конфига. На другую сотню ещё один фрагмент кода и опять конфиг. Оставшиеся ручные тесты все уникальны по набору действий и проверок. Все тесты, автоматизация которых давала значительную экономическую выгоду и повышала надёжность (в том числе за счёт уменьшения монотонных нагрузок на инженеров), уже автоматизированы.

Среди оставшихся ручными имеется массив тестов, связанных с физическим взаимодействием с оборудованием: подключение и отключение модулей, помещение оборудования в термокамеру и многое другое. Даже когда количество таких тестов не очень велико, их всё равно кто-то должен выполнять вручную, т.к. их автоматизация обычно не оправдывает себя по вложениям в тестовое оборудование.

Также нужно заметить, что вычислительные мощности тестируемого оборудования достаточно скромны и в значительной части заняты самим тестируемым ПО. Поэтому для автотестов используется легковесный фреймворк, разработанный специально в рамках данного проекта. Применение более мощных и сложных инструментов, дающих больше возможностей (например, с распознаванием), может привести к невалидным результатам тестирования из-за возрастания нагрузки на железо до критической. Это также накладывает ограничения на возможности автоматизации тестов. Конечно, остаётся вариант автоматизации внешними устройствами, способными физически нажимать на кнопки и распознавать изображение на экране, но стоимость разработки, внедрения и поддержания таких автотестов будет неоправданно высока.

Дополнительно к тест плану в рамках каждого тестового цикла инженеры всегда проводят ad-hoc тестирование. Это крайне полезная традиция, позволяющая найти проблемы, саму возможность возникновения которых никто даже не предполагал.

Надо заметить, что на протяжении последних лет большинство найденных на проекте дефектов не являются провалами конкретных тест-кейсов, они найдены как результат ad-hoc теста или наблюдения за системой за пределами заданных кейсов. Например, при тестировании сценария в одном модуле наблюдается кратковременный сбой в другом модуле. Предусмотреть все возможные подобные проверки при разработке автоматических тестов практически невозможно, поэтому ручное тестирование остается важным элементом в процессе разработки качественного продукта.

В конечном счете, от команды тестирования в целом и от руководителя команды в частности требуется находить оптимальный баланс между ручным и автоматическим тестированием для каждого отдельного случая, учитывая технические особенности проектов.