Разделы портала

Онлайн-тренинги

.
Разбираемся с тестируемостью
24.01.2024 00:00

Автор: Роб Мини (Rob Meaney)
Оригинал статьи: Tea-Time With Testers, #01/2021
Перевод: Ольга Алифанова

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

Открытие: разработчики могут сделать ТО доступнее для тестирования

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

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

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

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

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

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

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

Этот опыт дал мне два важных урока:

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

Намеренное проектирование ПО с учетом тестирования

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

В ходе онбординга вся команда нового отдела, 35 человек, занялась регрессионным тестированием ПО перед грядущим релизом. Участвовала все сотрудники отдела разработки. После семи недель замысловатого регресса релиз наконец проковылял к дверям.

Это регрессионное тестирование поставило перед командой проблемы, полностью ее вымотавшие. Имеющаяся тест-автоматизация была такой ненадежной, что ее пришлось игнорировать. Нам пришлось тестировать все вручную, включая проверку тысяч атрибутов продукта через REST API. Когда мы находили и исправляли проблемы, это часто приводило к появлению новых багов в совершенно других участках продукта. Тесные взаимосвязи кода привели к необходимости в регрессе для каждого внедряемого изменения. Мы работали по вечерам и выходным. В течение недели после релиза пользователи сообщили о множестве проблем, и боевой дух отдела разработки сильно упал.

Когда пыль осела, ко мне подошел системный архитектор и задал мудрый вопрос: «Как можно упростить тестирование системы?» Мы обсудили проблемы тестирования, с которыми столкнулись. Мы сформулировали подход к проектированию первого компонента, самой важной характеристикой которого стала его тестируемость. Для описания этого подхода я воспользовался мнемоникой CODS. Каждая буква – это атрибут дизайна, о котором нужно подумать, проектируя систему на основании тестируемости.

  1. Контролируемость (Controllability). Способность контролировать систему, вызывать все важные ее состояния.
  2. Наблюдаемость (Observability). Способность наблюдать за всеми важными вещами, происходящими в системе.
  3. Декомпозируемость (Decomposability). Способность декомпозировать систему на независимые тестируемые компоненты.
  4. Простота (Simplicity). Насколько просто понять систему.

Мы декомпозировали новый компонент на единичные, независимо тестируемые сервисы. Мы добавили контрольные точки, позволяющие манипулировать состояниями, и точки наблюдения, позволяющие взглянуть на внутреннюю кухню сервиса. Через год после внедрения этого подхода мы произвели революцию в подходе компании к разработке ПО. Болезненные циклы регрессионного тестирования остались в прошлом – теперь у нас была устойчивая, надежная автоматизация, дающая почти мгновенную обратную связь после каждого изменения. Это высвободило тестировщикам время на глубокое, важное тестирование. Команды работали в хорошем ритме и быстрее поставляли качественное ПО.

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

Я начал изучать о тестируемости все, до чего мог дотянуться. Я изучил статьи и модели Джеймса Баха, Майкла Болтона, Анны-Марии Шарре, Марии Кедемо, Эша Уинтера и Боба Байндера – и это не исчерпывающий список. Моя мнемоника помогла повлиять на тестируемость самого продукта, но не изменила окружения, в котором проводилось тестирование.

Помощь команде с выплатой долгов по тестированию

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

Упражнение требует, чтобы вся команда зафиксировала, что делает тестирование непрактичным, медленным, сложным или ненадежным.

Что делает тестирование

Непрактичным

Медленным

Сложным

Ненадежным

Это упражнение – простой способ разобраться с проблемами тестирования, уникальными для конкретной команды. Это отличный старт для обсуждения тестируемости и решения связанных с ней проблем.

10 P тестируемости

Чем больше я работал с командами, тем больше я узнавал об источниках тест-долга. Было очевидно, что на тестирование влияет общий набор факторов. Я назвал эту модель «10 P тестируемости». 10 P – это линза, через которую команды могут самостоятельно оценить свое тестирование. Рассматривая его через каждую из этих линз, команды могут разобраться, где требуются улучшения.

Люди (People)

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

Философия (Philosophy)

Философия нашей команды поощряет ответственность всей команды за качество и сотрудничество между разными ролями, бизнесом и пользователями.

Продукт (Product)

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

Процесс (Process)

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

Проблема (Problem)

Команда хорошо разбирается в проблеме, которую решает продукт, и активно выявляет и снижает риски.

Проект (Project)

У команды есть время, ресурсы, ментальное и физическое пространство и автономия, позволяющие отлично выполнять тестирование.

Цепочка операций (Pipeline)

Цепочка операций поставки в команде дает быструю, надежную, доступную и понятную обратную связь о каждом уходящем на прод изменении.

Продуктивность (Productivity)

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

Проблемы на проде (Production issues)

У команды мало влияющих на пользователей проблем на проде. Когда такие проблемы возникают, команда может быстро выявить, изолировать и исправить проблему.

Проактивность (Proactivity)

Команда проактивно и непрерывно работает над улучшением подхода к тестированию. Она учится на своих ошибках и экспериментирует с новыми инструментами и техниками.

10 P оказались очень гибкой моделью. Я использовал ее для ежеквартальной проверки состояния тестируемости в командах разработки, а также для создания планов карьерного развития тестировщиков. Как только мне нужно подумать о связанной с тестированием проблеме, я неизбежно изучаю ее через призму 10 P.

Почему у машин есть тормоза?

Закончу аналогией. Задумайтесь на минутку, зачем машинам тормоза? Чтобы замедлять ее? Для безопасности? Это верные ответы, но по сути тормоза нужны машинам, чтобы иметь возможность быстро ехать. Современные команды разработки движутся максимально быстро. Нашим командам нужны эффективные и продуктивные тормоза, нам нужна отличная тестируемость. Без надежного тестирования, чтобы вовремя остановить нас, если мы в опасности, мы неминуемо разобьемся об стену головой.

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

Обсудить в форуме