Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Альтруикс - To TDD or not to TDD?


altruix logo

РЕШЕНИЯ ПРОБЛЕМ ПРЕДПРИЯТИЙ ПРИ ПОМОЩИ ИТ

Альтруикс - To TDD or not to TDD?

twitt_button rss button rss button

Здравствуйте!

Любой разговор про тестирование не может обойти стороной одну модную ныне идею с претензией на статус методологии. Речь идёт о т. н. «разработке через тестирование» (test driven development, TDD).

В этой записи мы разберёмся с этой идеей и определим, есть ли в ней разумное зерно.

Главный постулатт TDD

Главная идея TDD заключается в том, что перед внесением любого изменения в код программы, должна быть написана проверочная программа.

Выражаясь словами Остапа Ибрагимовича – утром тесты, вечером – код. Или вечером тесты, а утром – код. Но тесты вперёд! :)

Преимущество очевидно – при правильном подходе мы имеем 100 % покрытие кода проверочными программами.

TDD и виды модулей

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

  1. Модуль хранения данных
  2. Модуль отображения
  3. Модуль-координатор
  4. Алгоритмический модуль
  5. Модуль отчётов

Подробнее об этих видах можно прочитать здесь.

Теперь давайте посмотрим, применим ли подход TDD при разработке этих видов модулей.

TDD при разработке модуля хранения данных

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

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

TDD при разработке модуля отображения

Можно ли протестировать диалог или окно, до того, как оно создано?

Мне это не представляется возможным. Даже теоретически.

Вердикт: TDD при разработке модулей отображения неприменим.

TDD при разработке модуля-координатора

Можно ли протестировать модуль-координатор до того, как он сделан?

Теоретически да, можно. Но модуль-координатор работает в связке с модулями отображения и по-настоящему проверить его работу можно только в связке с модулями отображения.

Вердикт: TDD неприменим для тестирования модуля-координатора

TDD при разработке алгоритмического модуля

Алгоритмические модули (при правильном проектировании) можно без проблем протестировать до их реализации. Так что для этих модулей TDD вполне применим.

TDD при разработке модуля для создания отчётов

То же относится к модулю создания отчётов. TDD здесь вполне применим и имеет смысл.

Ошибка апологетов TDD

Как видно из моих высказывний выше, принцип TDD в некоторых случаях применим, а в некоторых – нет.

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

Невозможно всегда сделать тест перед написанием проверямого кода. Это требование невыполнимо в ряде случаев.

Как правильно?

Так есть ли рациональное зерно в тезисе о том, что перед внесением изменений в код надо обязательно иметь проверочную программу?

Рациональное зерно есть.

Перед разработкой той или иной функции (устранением того или иного бага) программист должен понимать, чего он хочет достичь. То есть, у него должно быть описание цели.

Исправленный принцип TDD гласит: Внесение изменений в код начинается с определения целей этих изменений. Всегда и везде!

Проверочная программа является одним из средств выражения этого описания, но не единственным.

Как я говорил выше, не всегда можно сделать проверочную программу до начала разработки с малыми затратами. Однако всегда (говорю из опыта) можно за 5-15 минут (в среднем) сформулировать цель той или иной работы с кодом (добавление или модификация функции, устранение дефекта).

Для этого лично я пользуюсь документом под названием “Процедура приёмки”.

Процедура приёмки

Процедура приёмки – это таблица с 5 столбцами:

  1. Номер
  2. Действие
  3. Ожидаемый результат
  4. Результат проверки
  5. Комментарий

Примечание: Если Вы не видите картинку, то можете посмотреть её здесь.

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

Для этого Вы берёте Вашу программу, и совершаете над ней некое действие (например, выбрать пункт меню). Вы знаете, как программа должна себя вести после этого действия, т. е. Вам известен ожидаемый результат Вашего действия (например, появился диалог такой-то).

Вы сравниваете ожидаемый результат с реальным и заносите результат проверки в соответствующую графу. Если ожидаемый результат совпадает с реальным, то Вы пишете туда “Работает”, если нет пишете “Ошибка”, а в графу “Комментраий” заносите подробности (stack trace исключения, например).

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

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

Пример из практики

А теперь пример процедуры приёмки из практики. У меня есть некое веб-приложение. Начиная очередную итерацию, я сформулировал конечный результат в виде процедуры приёмки. Отрывок из неё Вы можете увидеть ниже.

 Примечание: Если Вы не видите картинку, то можете посмотреть её здесь.

Небольшое дополнение: В этом варианте добавлена информация, необходимая для автоматизации этого сценария (“проверки”).

Возвращаемся к TDD

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

Правильный подход к тестам, на мой взгляд, такой:

  1. Перед тем, как приступить к той или иной работе с Вашим ПО (добавление или модификация функции, устранение ошибки), надо написать
    1. одну или несколько проверочных программ для тех модулей, которые легко протестировать,
    2. одну или несколько процедур приёмки (сформулировать цель работы в достаточной мере) для модулей, которые трудно написать тест.
  2. Внести изменения в код таким образом, чтобы процедуры приёмки “заработали” (цель достигнута) и проверочные программы заработали.
  3. Автоматизировать процедуры приёмки.

Вернусь к своей практике. Для алгоритмических модулей можно без особого напряга написать проверочные программы до внесения изменений в код (шаг 1 выше). Для модулей отображения и координаторов это сделать трудно – процедура приёмки, фрагмент которой я привёл выше, сделана для тестирования модулей отображения и модулей-координаторов.

Её я начал автоматизировать после того, как все проверочные программы заработали и процедура приёмки работала в ручном исполнении.

Кому нужна эта банальшина?

Критики могут возразить мне, что я не сказал ничего нового. Принцип TDD можно перефразировать так – “Прежде, чем Вы делаете что-то, удостоверьтесь в том, что Вы понимаете, что именно делаете”. Эка новость!

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

Из-за этого, он делает множество ненужных операций и тратит своё время попусту.

* * *

В этом выпуске мы обсудили модную ныне идею TDD. В следующих выпусках мы поговорим о том, как сделать автоматизированные проверки ПО постфактум, т. е. после того, как система разработана.

Успехов

Дмитрий Писаренко

П. С.: Если у Вас есть вопросы или проблемы из области автоматизированного тестирования ПО, напишите мне письмо и я постараюсь Вам помочь (в письме укажите, можно ли публиковать Ваш вопрос в блоге).


В избранное