Главная » Хабрахабр » [Из песочницы] Сопротивления автоматизации тестирования

[Из песочницы] Сопротивления автоматизации тестирования

Даже несмотря на очевидные преимущества автоматического тестирования, все равно поведенческое сопротивление достаточно сильное. Несмотря на то, что технологии модульного тестирования существуют уже 30 лет (в 1989 году Кент Бек написал статью “Simple Smalltalk Testing: With Patterns”), тем не менее не все программисты владеют этой технологией и не все компании сделали автоматическое тестирование частью своей корпоративной культуры. Кто пробовал внедрять автоматические тесты, тот знает, что всегда найдется какая-то причина, почему это не удалось сделать.

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

Все возражения я сгруппировал в пирамиду надежного программирования, которая включает четыре уровня:

  • Профессиональная культура (самый высокий уровень, основа надежного программирования) — совокупность норм, неписаных правил, убеждений сотрудника, которыми он руководствуется в работе. Например: “Отправить в репозиторий код непокрытый тестами — плохо”, “Замолчать о найденных ошибках в коде — стыдно”.
  • Менеджмент — это процедуры, политики, правила, принятые в организации, а также воля (решения) руководителей. Например: “Каждая разработанная функция приложения должна пройти код ревью. Без исключений!”.
  • Методы — это научные подходы, способы решения той или иной задачи. Например: “Если функцию приложения сложно протестировать, нужно повысить тестопригодность приложения, применив шаблон Dependency Injection”.
  • Технологии (самый низкий уровень) — это языки программирования, библиотеки, фреймворки, инструменты. Например, JUnit, Selenium, XCTest и так далее.

Потому что проблема одного уровня решается методами этого же уровня или методами более высокого уровня. Зачем нужно такое деление? Даю гарантию, что через неделю никто писать тесты не будет, невзирая на утвержденный бизнес-процесс. Например, если в организации не принято писать автоматические тесты (проблема профессиональной культуры), то эту проблему невозможно решить подробно описав бизнес-процесс тестирования (уровень “менеджмент”) или установив современный фреймворк (уровень “технологии”).

Возражения культурного уровня

“Мои программы не ломаются. Я не вижу нужды в тестировании”.

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

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

На одном из собеседований, которое я проводил, произошел такой диалог:

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

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

Нежелание брать ответственность за качество кода, за тестирование.

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

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

"Пишите сразу правильно без ошибок"

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

У вас низкая квалификация? — Давайте покроем приложение автоматическими тестами.
— Зачем?
— Чтобы убедиться, что все работает корректно и нет ошибок.
— Вы пишите с ошибками? Пишите сразу правильно без ошибок.
— Да, но все допускают ошибки…
— А вот друга компания XYZ сказала, что у них топ-программисты, которые пишут без ошибок!

В результате, менеджмент вынужден разрабатывать проект без автоматических тестов, что приходит к известным проблемам. Таким образом, разработку тестов сложно “продать” заказчикам, которые не подкованы технически.

Возражения на уровне менеджмента

“C тестами программу писать в два раза дольше. Мы не уложимся в сроки”.

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

У автоматических тестов есть несколько функций:

  1. Проверяющая.
    1.1. Тесты проверяют, корректно ли работает объект тестирования.
    1.2. Тесты проверяют качество работы программиста: решена ли поставленная задача, нет ли побочных эффектов в виде регрессий.
  2. Диагностирующая. Диагностические тесты позволяют существенно сократить время на поиск дефекта. Тесты позволяют определить место ошибки с точностью до класса и метода, а иногда и с точностью до строчки кода.
  3. Автоматизирующая. Тесты позволяют быстро и легко вводить объект тестирования в нужное состояние для отладки.
  4. Документирующая.
    4.1. Приемочные тесты фиксируют требования заказчика к разрабатываемому продукту.
    4.2. Тесты показывают примеры использования разрабатываемого компонента, тем самым сокращая время на изучение работы системы другим программистом.

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

Мы не уложимся в сроки!
— У вас есть ошибки, которые вы очень долго искали и исправляли?
— Да, есть такие.
— Какой самый сложный случай?
— Одну ошибку мы искали 80 часов.
— 80 часов — это две недели работы программиста. — Но ведь тесты писать долго! Если бы вы потратили даже целую неделю на автоматизацию тестированию, то это сэкономило бы вам месяцы на диагностировании и отладке вашего приложения!

Обсуждается только коэффициент 2 — иногда бывает и 3, и 4. В нашей организации есть постулат: “С тестами писать программу в два раза быстрее!” и этот постулат не обсуждается. заваленный проект). А некоторые проекты просто невозможно завершить без грамотного автоматического тестирования (см.

“У нас уже есть отдел ручного тестирования, пусть они и тестируют”.

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

Но давайте рассмотрим недостатки ручного тестирования:

  • Стоит очень дорого.
  • Выполняется очень долго. Например: тестовые сценарии для мобильного приложения “Онлайн кинотеатр” тестер делает 40 часов. И это только для одной платформы! Если нужно протестировать приложение на iPhone, iPad, Apple TV, Android, Fire TV, то нужно потратить 40 × 6 = 240 часов рабочего времени, это полтора месяца, что неприемлемо для коротких циклов разработки.
  • Ручное тестирование подвержено обычным человеческим ошибкам — не дает объективного и истинного результата.

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

  1. Функция импорта CSV-файлов.
  2. Парсеры текстовых документов.
  3. Финансовые инструменты.

Возражения на уровне методов

Незнание методов автоматического тестирования.

Таких же курсов очень мало в коммерческих айти-школах. Из-за кризиса образования в вузах нигде нет дисциплин автоматического тестирования. Поэтому, я часто встречал ступор у программистов: они не знают, как протестировать нетривиальные приложения (сложнее, чем 2 + 2 = 4). А существующие курсы — поверхностные и низкого качества.

Например, не каждый программист сразу ответит на вопросы: а) что такое тестопригодность? На самом деле наука о тестировании достаточно обширная. в) какие шаблоны проектирования улучшают тестопригодность приложения? б) что такое управляемость и наблюдаемость? И так далее.

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

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

При таком подходе исключается формальный этап проектирования программной системы: определение бизнес-логики, предметной области, интерфейсов компонентов, а также их внутренней организации их отношений между ними. Особенность некоторых проектов в том, что они разрабатываются по технологии Minimum Viable Product, который иными словами можно охарактеризовать так: “Давайте сделаем хоть что-то за минимальное время и минимальный бюджет”, а программист рассматривается заказчиком или менеджментом как аналитик, дизайнер, архитектор, программист и тестировщик в одном флаконе. Нет формализованной архитектуры, нет интерфейсов, нет прописанных бизнес-процессов — непонятно, что тестировать, через какие интерфейсы и какой ожидаемый результат.

Нетестопригодный код.

Тестопригодность определяется двумя другими свойствами: управляемостью и наблюдаемостью. Тестопригодность — свойство проекта, которое говорит: насколько легко его можно протестировать. Наблюдаемость — как легко можно считать состояние после проведения теста, сравнить его с ожидаемым. Управляемость — свойство, которое определяет насколько легко можно ввести приложение в нужное состояние для тестирования (выполнить предусловия).

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

Сталкиваясь с нетестопригодной системой, программист опускает руки и избегает тестирование такой системы.

Подготовка тестовых данных.

Например: начальное состояние базы данных на которой производится тестирование. Одно из неочевидных сопротивлений — это подготовка тестовых данных и эталонов. На подготовку тестовых данных может уходить много времени и рутинного труда, поэтому этот труд считается среди программистов неблагодарным и неинтересным.

Решение:

  • разработка эталонных значений и примеров на этапе разработки приемочных тестов — они также помогут решить конфликты с заказчиком на этапе приема работ;
  • разработка эталонных значений на этапе проектирования системы. Например, эталонные HTTP запросы и ответы — помогут легче интегрировать клиент и сервер;
  • разработка специальных процедур сборки баз данных, при которых требуемое состояние базы данных создается автоматически, а не вручную
  • использование шаблона Object Mother [Fowler, Schuh, Peter, and Stephanie Punke. "Easing Test Object Creation in XP." XP Universe. 2003], который помогает легко аллоцировать и инициализировать объекты в требуемом состоянии.

Обслуживание тестов.

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

Решение:

  • использование шаблона “адаптер” для того, чтобы отвязать логику теста от того интерфейса, который он тестирует;
  • использование высокоуровневых тестов (Gherkin, Cucumber, Given-When-Then);
  • см. решение к сопротивлению “подготовка тестовых данных”.

Заключение

Автоматические тесты — хоть и не единственный, но важный компонент при разработке надежного программного обеспечения. Нет сомнений, что программное обеспечение должно быть надежным: превосходить ожидания потребителей.

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

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

  1. Формирование и пропаганда новой культуры ИТ-проектирования, которая заключается в надежности, гордости и персональной ответственности за результат.
  2. Разработка новых высоких стандартов тестирования кода.
  3. Разработка и внедрение учебных курсов.
  4. Введение мотивации в карьеру программистов и менеджеров, увязанной с качеством разрабатываемых программных продуктов, а также с навыками автоматического тестирования.

И решать их нужно на соответствующих уровнях. Самое важное, что мне удалось понять — это то, что проблемы находятся на разных уровнях: технологическом, методическом, управленческом и культурном. Очень сложно внедрить автоматические тесты, если программист не обучен методам тестопригодного проектирования или если менеджмент не поддерживает культуру надежного программирования в организации.

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


Оставить комментарий

Ваш email нигде не будет показан
Обязательные для заполнения поля помечены *

*

x

Ещё Hi-Tech Интересное!

[Из песочницы] C++: сеанс спонтанной археологии и почему не стоит использовать вариативные функции в стиле C

Началось все, как водится, с ошибки. Я первый раз работал с Java Native Interface и делал в C++ части обертку над функцией, создающей Java объект. Эта функция — CallVoidMethod — вариативна, т.е. помимо указателя на среду JNI, указателя на тип ...

Почему разработчикам железа важно проводить качественный cusdev

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