Что для вас TDD (разработка через тестирование)?

syfisher

TDD infected!!
Что для вас TDD (разработка через тестирование)?

Что для вас TDD (разработка через тестирование)?

Привет всем. Хотелось бы поднять такую тему. Я хочу получить отзывы от разработчиков о том, что
для них TDD. Отзывы хотелось бы получить от следующих категорий разработчиков:

  1. * от тех, кто практикует TDD в своей работе уже достаточно
    давно,
    * от тех, кто только начинает пробовать свои силы в TDD,
    * от тех кто попробовал и бросил,
    * от тех кто посмотрел и подумал, что TDD - это не для него.
    [/list=1]
    То есть я хочу получить мнение различных групп программистов для того,
    чтобы составить полноценную картину, что в TDD может нравится, что нет и почему,
    как изменилась разработка после введения TDD, что изменилось в сознании разработчиков после перехода на эту методику разработки, как
    TDD способствует развитию разработчиков и в какой направлении. Отдельно - почему разработчики боятся тестов, в чем они видят наибольшие трудности при переходе на TDD.

    Я прошу, просто выскажите свой опыт. Желательно, чтобы была краткая история.

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

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

    В итоге я планирую сделать статью в phpinside или FAQ.
 

ssv

Новичок
Скорее отношусь к тем, кто только начинает пробовать свои силы в TDD

есть несколько фактов и следствий
- почему затрудняется использование TDD
Факты:
1.
есть опыт создания скриптов, благодоря которому получается писать качественные скрипты. 95% - уверенноесть что скрипт отвечает поставленным требованиям и внутренним стандартам.
2.
зачастую времени для написания скрипта не так уж и много
3.
на начальном этапе, нет готовых нароботок для проведения тестирования, эмуляции различных процессов.


Следствия:
1. По фактам (1-3) отсутствие нароботок приводит к тому, что тратится много времени для написания этих нароботок, и выполнения первостепенной задачи, при том что на нее и так не много времени выделенно.

- почему возвращаюсь к использованию TDD
1. В проектах с расширенными требованиями (специфическими фичами),
натыкаешься на ситуацию когда тестирование занимает немеренно времени или просто затрудненно.
Например,
TDD отлично помогает проверить взаимодействие сайта с другими системами, типа PayPal, eBay и т.д. в течени 1-2 минут

Следствие:
Как следствие очередной раз задумываешся над TDD и начиаешь писать заготовки
 

syfisher

TDD infected!!
Плиз, пишите, что вас мотивировало перейти на TDD и что наоборот, отказаться.
 

svetasmirnova

маленький монстрик
Три истории успешного применения TDD.
1. Банальная. В репозитории, о котором можно прочитать в топике onPHP's early announce здесь
лежит мой псевдо-шаблонный движок (Template). Он писался до того, как я стала принимать участие в этом проекте и до написания абстрактного синглтона, от которого теперь унаследованы 2 класса. Изначальный вариант Template несколько не соответствовал coding style onPHP и я некоторое время назад его отрефакторила. Все ошибки были проверены нажатием shortcut. Я думаю понятно, что времени было сэкономлено очень много.
2. Не банальная. Пишу сейчас приложение, дизайн к которому разрабатывается. Дизайн очень сложный, поэтому простая замена будущей красивой страницы на что-то примитивное не прокатит. В результате вся работа по занесению/изменению данных в БД уже проделана и оттестирована. А дизайн-то не готов! То есть пример иллюстрирует экономию времени уже при создании приложения, а не при его рефакторинге только.
3. Смешная. Многие говорят, что геттеры-сеттеры тестировать не надо. В одном классе у меня их штуки 3. Делаю, естесственно, copy-paste-ом. Сначала пишем метод setXXX() {$this->xxx = $x;}, а потом его copy-paste. Ну и перенесла: setXXX() {$this->xxx;}. Ха-ха. Но ведь эту ошибку нельзя обнаружить до тех пор, пока не вызовешь метод.

И вот тут я писала как со старым или сторонним кодом работаю, используя TDD.

Всё просто!
 

Screjet

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

[sid]

Новичок
Что привело меня к TDD? Должен признаться у меня уже был опыт работы с ООП и архитектурой ПО до этого момента. Не могу точно сказать, почему я обратил внимание на TDD. Просто однажды попробовал (тогда я начиналя рефакторинг своей CMF), мне понравилось, потому что я ощутил, как отлично подходит тестирование для проектирования ПО. Писав тесты не имея за плечами самого тестируемого кода, я продумывал интерфейс моего модуля до его реализации. Этот процесс я никогда не забуду, потому что он принес мне очень много пищи для ума. Начинаешь концентрироваться на вопросе "Как это использовать", а не "Как это должно работать". Ведь именно первый вопрос, а не второй, встает перед конечными пользователями. Ну и конечно опыт. Будем откровенны... TDD вещь довольно не легкая и для того что бы увидеть "свет в конце туннеля", новичкам прийдется изрядно постараться. Но я все яснее и яснее осознаю одну вещь. Она заключается в том, что TDD выводит мое умение использовать объектную модель на качественно новый уровень. Это легко понять, ведь для качественного тестирования необходимо писать код так, что бы этот код было удобно тестировать. А в итоге мы получаем не просто код, который был написан с учетом тестирования, а качественный и хорошо структуризированный код, который обладает низким уровнем связности (а ведь к этому все и стремятся). Другой код просто напросто тяжело протестировать (качественно). Это приводит меня к мысли о том, что модульное тестирование, кроме всего вышеперечисленного - это инструмент изучения ООП. Выполняя роль эдакого надзирателся, TDD не дает вам свернуть с верного пути.
 

Alexandre

PHPПенсионер
я TDD бегининг, но само тестирование использовал давно, еще до появления абревиатуры TDD
писал, как сейчас говорят тест для своего класса, и сперва отлаживал класс в "тестовой обертке", а потом его переносил и отлаживал уже в проекте.

тестирование нужно, это однозначно. Большинство простых проектов, для которых и первоночально был создан пхп - в тестировании по TDD не нуждаются.

если проект выходит за рамки средний, то TDD - необходим
 

ForJest

- свежая кровь
Сегодня нужно сделать кратким, рассказ о том что было раньше (с)

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

- TDD и лишь только МОДУЛЬНОЕ тестирование. То с чего я начал - нашёл PEAR::phpUnit и пошёл тестировать. phpUnit предоставляет средстава для модульного тестирования. Единственный опыт, который я вынес из этого - проектирование интерфейсов "того как будет использовано" до собственно использования. Это меня сподвигло на поиски/эксперименты проектирования интерфейсов классов. Выгода от этой части опыта - минимальная - всё что я вынес - умение писать модульные тесты, куча перепробованных вариантов, сам дух TDD
- TDD и функциональное тестирование. После конференции, имея материалы syfisher и pachanga я посмотрел на SimpleTest.
Опять же я изменил свой подход к написанию тестов - та необходимая кроха информации, которая изложена в докладе "Влияние TDD на дизайн кода".
Функциональное тестирование это реальная "прибыль" которую я получаю и по сей день от использования TDD. SimpleTest webTester плюс ко всему ещё и удобная среда разработки, помимо тестов - можно просто вывести полученную страницу и посмотреть "что неправильно" вместо того, чтобы делать это на "живом сайте".
Опять же сейчас, после того как у меня появился некоторый опыт функционального тестирования кардинально изменился подход. Я пишу то, что хочу "увидеть" на странице в тестах. Я теперь обладаю навыками для того, чтобы описывать требования к странице в терминах webTester, умею задавать нужный контекст данных в DB.

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

- Модульное тестирование, часть вторая. По истине бесценная информация по части использования Моков, тестировании сложных классов, которая была изложена на конференции. Без этой информации, без подхода модульное тестирование было пожалуй что пыткой, как я сейчас понимаю и всё держалось на одном "Надо, Вася, надо". Задавать контекст DB, данные, проверять рутинные операции, тестовая среда которая разрастается с любым увеличением сложности выполняемых классом функций...
Я был просто достаточно упрям, для того, чтобы продолжать идти по выбранному пути, пусть и видел некоторые несообразности.
----------------------------------------------------
Отсюда мои прямые выводы по части популяризации TDD. Или как я буду учить человека, когда мне это придётся делать.
1. Я научу человека функциональному тестированию. Создавать среду, описывать то, что он хочет увидеть на страницы, не видя её. Использовать для отладки сам testCase. Пусть он делает начинку любую - по своему собственному разумению.
2. Я покажу ему модульное тестирование, объсню как лучше создавать контекст СУБД, почему лучше делать так. Объясню основные приёмы.
3. Когда я увижу монстроидальное наслоение тестовых данных в тесте, я научу его использовать Mock Objects. И покажу, на практике, насколько стало меньше тестового кода.
---------------------------------
Пока что больше ничего не приходит в голову. Хочу выразить ещё раз огромную благодарность syfisher и pachanga за их доклад и раздаточные материалы.

Примечания: в заголовке использованы слова песни Бори Чистого http://chibo.ru/music/borja10.mp3
 

BeGe

Вождь Апачей, блин (c)
Отказ от TDD.

1. зачастую написание приложения с ипользованием тестов в два раза дороже и более, чем без тестов.
2. Тесты не предоставляют механизма тестирования наледований большой вложености
3.Очень часто (средние и крупные сайты) не требуют даже объектоной модели, и состоят из простых блоков.

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

TDD как и объекты пока отпдают, потому что не требуются с точки зрения бизнес задач. Кто скажет что это берд, пусть тогда посчитает сколько надо человекочасов для написания CMF или CMS для компании, и кто рискнёт отдать столько денег ради призрачной идеи написания CMS и/или CMF с нужными требованиями и функционалностью.
 

pachanga

Новичок
Итак с чего все начиналось в моем случае....

Это были не совсем далекие времена(года так 2.5 назад), когда мы "на коленке" проектировали LIMB 1.x и с помощью него пытались выполнять определенные задачи. Это были самые первые шаги серьезной разработки, хотя и код да и метафора были просто кошмарными(да, слышал бы я тогда себя), но мы были уперты в своем желании изобрести колесо. Мы тогда еще не применяли XP и полагали, что систему можно запланировать загодя, нарисовав кучу красивых диаграм и картинок на тему "как там все будет круто работать". Однако реальность была такова, что требования к системе менялись ежечасно и порой приходилось переворачивать с ног на голову тонны кода. Когда в очередной раз "ой, а чего-то не работает" случалось, обычно проводились довольно утомительные сессии с дебагером, за которыми следовали "quick'n'dirty fixes", которые в свою очередь не гарантировали, что не было сломано что-то еще....

Я сейчас даже вспомнить не могу, как наткнулся на SimpleTest. По-моему, в свое время это было довольно сильным buzz word на SitePoint и чисто интуитивно я зашел на www.lastcraft.com.

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

Примерно в это же время мы чудом наткнулись на cvs репозиторий WACT на SourceForge, тогда не было ни одного официального релиза и весь код был только в cvs. Я был поражен качеством кода, я им просто упивался! Но больше всего меня поразила методология разработки через тесты. Какие там были шикарные тесты по тем временам! Я для себя твердо решил в тот момент, что LIMB 2.x будет написан с использованием TDD. Как раз подоспел крупный заказ, который бы LIMB 1.x просто не потянул без очередной "революции" и мы с syfisher выкинули все UML долгосрочные диаграммы, попыталиь сделать пару карточек на неделю и сели в пару писать тесты(это был для нас первый XP опыт).

Мы насколько позволяли наши знания и опыт пытались вести разработку через тестирование, однако на 100% не получилось. Стоит признать, что TDD с "бухты барахты" применить не получится, требуется переворот мировоззрения разработчика(я пытаю судить по себе). Конечно, будет звучать громко, если я скажу, что учился программировать с нуля, вникая в азы TDD, но примерно так оно и было.

Мы применяли только модульные тесты и это было одной из ошибок(на тот момент пакета для web тестирования в SimpleTest не было). Мы все равно часто пользовались дебаггером для отлавливания GUI ошибок и многие вещи ошибочно считали слишком простыми, чтобы тестировать. Да и опыта ООП не хватало...я смотрю на прежний код и мне местами берет вдрожь(хотя это нормально, посмотрите свои лабораторные за первый курс :) ). Еще одной ошибкой было то, что когда было слишком сложно написать тест, мы сдавались(в основном это возникало из-за слишком сложных зависимостей в коде). Все это дало о себе знать впоследствии - LIMB 2.x подходит для средних проектов, но не для сложных, с богатой бизнес моделью....однако я благодарен этим ошибкам, т.к они позволили понять, каким именно должен быть код, чтобы его было легче протестировать.

Поставив testability основным приоритетом, мы начали разработку LIMB 3.x. Даже до беты еще далековато, однако в общем и целом я доволен качеством кода, в чем я премного благодарен TDD. Да, я и сейчас пользуюсь дебагарем, но только во время тестирования, когда первые реализации ведут себя непредсказуемо. Я почти не пользую дебагером для отловли ошибок в рабочем проекте, такое бывает оооочень редко. Крутые перцы типа Marcus Baker вообще не пользуются дебагером, это наверное будет следующая ступень развития :)

TDD учит правильно выделять небольшие тесно связанные ответственности в неповоротливых участках кода, т.к иначе тестирование превращается в муку. Для меня это одно из самых важных последствий TDD, и если кто-то упрекнет меня в code bloat после того, как из god-like класса я выделил бы шесть узкоспециализированных да еще и пару-тройку интерфейсов, и после этого читабельность и тестируемость системы повысились, я просто рассмеюсь.

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

Для меня наличие грамотных тестов - это признак профессионального подхода к разработке. Это как с cvs: или ввести в практику или даже не пытаться, т.к "...ну, это надо делать коммит".

Тут очень популярно говорить, ну зачем мне TDD, если проект маленький. Хорошо. У меня только один вопрос: вы для каждого проекта все кодируете с нуля? Нет никакой собственной библиотеки из проверенных временем решений? Если нет, то это самоубийство. А если да, то почему бы вашу библиотеку не зафиксировать тестами? Какая на этот раз отговорка?

"зачастую написание приложения с ипользованием тестов в два раза дороже и более, чем без тестов." - откуда такие цифры?

"Тесты не предоставляют механизма тестирования наледований большой вложености" - наследование в 99% хуже композиции, меня настораживает наследование более 3 уровней... Как насчет рефакторинга?

P.S. меня также интересует тема формализации TDD. Такое вообще возможно? Мне кажется TDD - чисто инженерная поделка, которая будет трудно поддаваться мало-мальскому формальному описанию.

P.P.S. Я надеюсь, вы не сочтете дешевым пиаром столь частое употребление слова LIMB в повествовании? :)
 

Bermuda

Новичок
Тема замечательная и, возможно, достойная для раздела " Всё о программировании на РНР > Для теоретических вопросов", но я так и не понял, при чем здесь PHP?
 

confguru

ExAdmin
Команда форума
Bermuda

Речь идет о "Экстремальном PHP программировании" :)
 

syfisher

TDD infected!!
Всем спасибо, кто уже ответил. Ждем остальных. Очень хочется видеть ответы тех, кто против TDD. Спасибо BeGe, а что остальные?

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

P.S. Admin - а где твой отзыв? Еще хотелось бы получить отзыв от Crazy, Varan и других, конечно, если вы найдете для этого время.
 

chameleon

Новичок
Признаюсь я использовать именно TDD не начал всвязи с тотальным переходом на php5 под который simpleTest работает с ограничениями (или моя информация устарела?) и неким завалом по работе. Вообще очень сложно навязать довольно большому штату сотрудников (цифру все помнят?) какую-либо идею, которая бы устраивала каждого - потому как каждый мнит себя творцом, который пишет чуть ли не спинным мозгом и не нуждается в тестах, ООП, cvs, комментариях, документации и прочее...многие просто не доросли. Поэтому в недрах предприятия сейчас рождается некий стандарт на веб-разработки - сборная солянка (Best practices), включающая рекомендации по многим процессам сопровождающим создание ПО (некий адаптированный карманный вариант ITIL). Включается все от стандартов кодирования до организации процесса управления изменениями и приемки кода. И единственно что сейчас возможно сделать в сторону продвижения TDD - это ОБЯЗАТЬ разработчиков для передачи своего кода на поддержку (у нас и такой отдел есть) снабжать свое приложение модулем самотестирования. Думаю что будучи вынужденными ВСЕ РАВНО писать тесты и наслышаны о TDD (уж пропиарить я смогу ;) народ у нас как-то это все сопоставит и примет правильное решение.. какое бы оно ни было :)..
Поэтому основной для меня вопрос есть ли мотивация у PM'а для перехода на TDD? Думаю, даже больше, чем у разработчика :)..время покажет.
резюмирую:
TDD:
+ для команды поддержки и внедрения ПО.
+ уверенность в качестве проекта
+ скиллзам разработчика, даже если он этого еще не понимает :)..
 

svetasmirnova

маленький монстрик
chameleon
>php5 под который simpleTest работает с ограничениями (или моя информация устарела?)
Фактически нет. Все проблемы устраняются минут за 5.
 

BOJIK

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

Я так и не понял, как писать тесты для кода, в котором идет активная работа с БД. Я не люблю mysql и редко его использую, предпочитаю pgsql. В разработке максимально стараюсь перенести логику хранения данных на сторону РСУБД. Соответственно, появляются функции, триггеры, представления, правила и как тестировать правильность их работы ума не приложу. На одном форуме я прочитал такой метод: делать тестовую БД (структуру которой необходимо периодически обновлять) с тестовым набором данных (который тоже необходимо обновлять) и потом писать тесты вида: выполнилась вставка – проверь, правильно ли отработали триггеры, а способ такой
проверки я знаю один - выбрать данные и проверить их правильность, а если, скажем, изменения охватывают три таблицы.
Не слишком ли будет много кода для тестирования двух строчек? Я уж не говорю, что объект для работы с БД (и параметры коннекта) надо таскать через подобные тесты.
 

pachanga

Новичок
Автор оригинала: svetasmirnova
Фактически нет. Все проблемы устраняются минут за 5.
Не хотелось бы мусорить топик, но это не так, существуют проблемы с генерацией моков из интерфейсов, а также с передачей мока в качестве аргумента с type hint. Лечится это отказом от пользования type hints вообще ради правильного тестирования.

Эти проблемы будут устранены только в SimpleTest 2.0.
 

confguru

ExAdmin
Команда форума
делать тестовую БД (структуру которой необходимо периодически обновлять) с тестовым набором данных (который тоже необходимо обновлять) и потом писать тесты вида: выполнилась вставка – проверь, правильно ли отработали триггеры, а способ такой
проверки я знаю один - выбрать данные и проверить их правильность, а если, скажем, изменения охватывают три таблицы
Именно так.. :)
Кстати именно тесты локализую багу, когда ты что-то резко
поменяешь.
 

Sergikus

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