Разбираемся с тестируемостью |
24.01.2024 00:00 | ||||||||||||||||
Автор: Роб Мини (Rob Meaney) В этой статье я расскажу, как последние пятнадцать лет изменили мое понимание тестируемости. Надеюсь, по прочтении вы разделите мой энтузиазм в отношении тестируемости. Я обнаружил, что концентрация всей команды на тестируемости – один из немногих рычагов разработки ПО, способный положительно повлиять на производительность команды. Открытие: разработчики могут сделать ТО доступнее для тестирования Как и многие уроки, полученные в ходе карьеры, ценность тестируемости открылась мне случайно. Будучи еще джуниор-тестировщиком, я работал в опытно-конструкторском проекте создания первых в мире камер системы безопасности. Это был потрясающий проект, давший мне возможность решать массу разнообразных проблем тестирования. Мы проектировали сложную систему, состоящую из визуальных сенсоров, физического блока управления и десктоп-приложения для конфигурации и контроля системы безопасности, предназначенной для промышленности. Из всех проблем, с которыми я столкнулся, самой раздражающей была сложность воспроизведения падений приложения. Приложение позволяло инженерам безопасности следить за тем, как обстоят дела на заводе – если работники приближались к опасному оборудованию, оно понимало это, замедлялось или останавливалось. Приложение требовало сложного графического интерфейса пользователя, позволявшего инженерам взаимодействовать с моделями среды. Печальным побочным эффектом этой сложности был непрерывный поток падений приложения, вызванных малейшими вмешательствами в его работу. Важность системы для безопасности подразумевала, что я должен был тщательно исследовать и воспроизвести все падения до единого. Воспроизведение каждого падения требовало часов и даже дней – зачастую критически важна была и последовательность, и местоположение кликов пользователя. Как-то раз, столкнувшись с очередным падением приложения, я решил поработать в паре с одним из разработчиков, чтобы воспроизвести проблему. Как обычно, мы следовали памятным мне шагам, которые я выполнял перед падением. Мы повторяли их снова и снова, каждый раз слегка их варьируя. Прошло несколько часов, и мы наконец воспроизвели проблему. После воспроизведения падения разработчик быстро выявил причину и исправил ее. И тут все становится интереснее. Раздраженный кучей потраченного на воспроизведение проблемы времени, разработчик предложил добавить в приложение флаг, который будет записывать все взаимодействия в файл. Через два часа изменения были внедрены и готовы к использованию. С этого момента сложные в воспроизведении проблемы остались только в воспоминаниях. Как только я натыкался на падение, я копировал лог-файл в баг-репорт, и разработчики легко могли воспроизвести ситуацию. Этот опыт дал мне два важных урока:
Намеренное проектирование ПО с учетом тестированияСемя было посеяно, но не всходило несколько лет, пока я вновь не оказался в ситуации, где выполнять тестирование хорошо казалось невозможной целью. Я начал работать в качестве инженера-автоматизатора в новеньком отделе разработки компании-производителя оборудования. Компания впервые приступила к разработке ПО, и после хорошей обратной связи от рынка мы приступили к дальнейшему развитию опытного образца. В ходе онбординга вся команда нового отдела, 35 человек, занялась регрессионным тестированием ПО перед грядущим релизом. Участвовала все сотрудники отдела разработки. После семи недель замысловатого регресса релиз наконец проковылял к дверям. Это регрессионное тестирование поставило перед командой проблемы, полностью ее вымотавшие. Имеющаяся тест-автоматизация была такой ненадежной, что ее пришлось игнорировать. Нам пришлось тестировать все вручную, включая проверку тысяч атрибутов продукта через REST API. Когда мы находили и исправляли проблемы, это часто приводило к появлению новых багов в совершенно других участках продукта. Тесные взаимосвязи кода привели к необходимости в регрессе для каждого внедряемого изменения. Мы работали по вечерам и выходным. В течение недели после релиза пользователи сообщили о множестве проблем, и боевой дух отдела разработки сильно упал. Когда пыль осела, ко мне подошел системный архитектор и задал мудрый вопрос: «Как можно упростить тестирование системы?» Мы обсудили проблемы тестирования, с которыми столкнулись. Мы сформулировали подход к проектированию первого компонента, самой важной характеристикой которого стала его тестируемость. Для описания этого подхода я воспользовался мнемоникой CODS. Каждая буква – это атрибут дизайна, о котором нужно подумать, проектируя систему на основании тестируемости.
Мы декомпозировали новый компонент на единичные, независимо тестируемые сервисы. Мы добавили контрольные точки, позволяющие манипулировать состояниями, и точки наблюдения, позволяющие взглянуть на внутреннюю кухню сервиса. Через год после внедрения этого подхода мы произвели революцию в подходе компании к разработке ПО. Болезненные циклы регрессионного тестирования остались в прошлом – теперь у нас была устойчивая, надежная автоматизация, дающая почти мгновенную обратную связь после каждого изменения. Это высвободило тестировщикам время на глубокое, важное тестирование. Команды работали в хорошем ритме и быстрее поставляли качественное ПО. Эта потрясающая трансформация убедила меня, что тестируемость – ключевой фактор скорости работы без ущерба для качества. Я также осознал, что значительные улучшения качества произошли не благодаря тестированию, а благодаря построению взаимоотношений и влиянию на правильных людей в правильное время, которые помогли встроить качество в продукт. Я начал изучать о тестируемости все, до чего мог дотянуться. Я изучил статьи и модели Джеймса Баха, Майкла Болтона, Анны-Марии Шарре, Марии Кедемо, Эша Уинтера и Боба Байндера – и это не исчерпывающий список. Моя мнемоника помогла повлиять на тестируемость самого продукта, но не изменила окружения, в котором проводилось тестирование. Помощь команде с выплатой долгов по тестированиюПримерно в это время я начал консультировать команды разработки, помогая им улучшить тестирование. Я создал простую модель – квадрант долга по тестированию, помогающий командам выплатить этот долг. Тест-долг возникает, когда команда выбирает сценарий, приносящий краткосрочную выгоду, но накапливающий тест-издержки – время, силы или риск – на длительной дистанции. Иными словами, тест-долг – это проявление недостаточной тестируемости. Упражнение требует, чтобы вся команда зафиксировала, что делает тестирование непрактичным, медленным, сложным или ненадежным.
Это упражнение – простой способ разобраться с проблемами тестирования, уникальными для конкретной команды. Это отличный старт для обсуждения тестируемости и решения связанных с ней проблем. 10 P тестируемостиЧем больше я работал с командами, тем больше я узнавал об источниках тест-долга. Было очевидно, что на тестирование влияет общий набор факторов. Я назвал эту модель «10 P тестируемости». 10 P – это линза, через которую команды могут самостоятельно оценить свое тестирование. Рассматривая его через каждую из этих линз, команды могут разобраться, где требуются улучшения.
10 P оказались очень гибкой моделью. Я использовал ее для ежеквартальной проверки состояния тестируемости в командах разработки, а также для создания планов карьерного развития тестировщиков. Как только мне нужно подумать о связанной с тестированием проблеме, я неизбежно изучаю ее через призму 10 P. Почему у машин есть тормоза?Закончу аналогией. Задумайтесь на минутку, зачем машинам тормоза? Чтобы замедлять ее? Для безопасности? Это верные ответы, но по сути тормоза нужны машинам, чтобы иметь возможность быстро ехать. Современные команды разработки движутся максимально быстро. Нашим командам нужны эффективные и продуктивные тормоза, нам нужна отличная тестируемость. Без надежного тестирования, чтобы вовремя остановить нас, если мы в опасности, мы неминуемо разобьемся об стену головой. Подведу итог – поощряйте командные разговоры о тестировании. Используйте вышеописанные модели, чтобы выявить и осознать проблемы тестирования, и совместно поработайте над их решением. |