XP - практика применения.

Crazy

Developer
pachanga, ты смерти моей хочешь. :)

Позволь спросить, что заставило тебя задать именно этот вопрос (а не спросить, пью ли я кефир) и связано ли решение задать именно этот вопрос с моим предыдущим ответом?
 

pachanga

Новичок
Нет, все же мы с тобой говорим все это время о разных вещах, по-моему. Разве TFD подразумевает рефакторинг?
 

Crazy

Developer
Подразумевает ли TFD обязательное использование рефакторинга? Нет.

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

pachanga

Новичок
Автор оригинала: Crazy
Подразумевает ли TFD обязательное использование рефакторинга? Нет.
Стоп. А как же это понимать тогда?
TDD = TFD + refactoring.

Т.е в TFD, по-твоему все же может входить рефакторинг?

Правильно ли я понял: моя фраза о том, что я использую TFD, вызвала у тебя подозрение, что я не использую рефакторинг?
Вообще-то да, точнее не именно твоя фраза, а то как это подается на http://www.agiledata.org/essays/tdd.html

Я, опять же повторюсь, не выделяю такой фазы как TFD...
 

_RVK_

Новичок
Crazy вмешаюсь можно? Ты сказал TDD = TFD + рефакторинг. Ты используешь TFD но не иcпользуешь TDD.Согласно формуле TFD != TDD только если нет рефакторинга....
 

syfisher

TDD infected!!
1. What is TDD?

The steps of test first development (TFD) are overviewed in the UML activity diagram of Figure 1. The first step is to quickly add a test, basically just enough code to fail. Next you run your tests, often the complete test suite although for sake of speed you may decide to run only a subset, to ensure that the new test does in fact fail. You then update your functional code to make it pass the new tests. The fourth step is to run your tests again. If they fail you need to update your functional code and retest. Once the tests pass the next step is to start over (you may first need to refactor any duplication out of your design as needed, turning TFD into TDD).
Я думаю, это самый значимый абзац в данной статье.

Как я понимаю ( об этом упоминал в своей последней статьей на phpinside.ru) - TDD - это когда дизайн формируется через тесты. TFD - это когда пишется тест до кода. Дизайн в этом время уже может быть разработанным, а может и нет. Если дизайн еще не был разработан, то, избавляясь от запахов кода после зеленой полосы, получается test-driven design.

Это практически бесполезно придумывать дизайн, а затем его тестировать модульными тестами. Реализация зачастую будет очень далека от первоначальной задумки. Наша практика показывает, что в большинстве случаев TFD быстро переходит в TDD. Может это только у нас так? Но правда мы к этому не сразу шли... Согласен, с Crazy, что нужно ломать стереотипы разработки для перехода к чистому TDD.
 

Crazy

Developer
Автор оригинала: _RVK_
Crazy вмешаюсь можно? Ты сказал TDD = TFD + рефакторинг. Ты используешь TFD но не иcпользуешь TDD.Согласно формуле TFD != TDD только если нет рефакторинга....
Да-да. Старая школьная шутка.

Коммунизм = Советская власть + Электрификация всей страны

Следовательно:

Электрификация всей страны = Коммунизм - Советская власть

-~{}~ 16.02.06 19:21:

Автор оригинала: pachanga Вообще-то да, точнее не именно твоя фраза, а то как это подается на http://www.agiledata.org/essays/tdd.html
Для начала я просто процитирую маленький фрагмент:

Kent Beck, who popularized TDD in eXtreme Programming (XP) (Beck 2000), defines two simple rules for TDD (Beck 2003). First, you should write new business code only when an automated test has failed. Second, you should eliminate any duplication that you find.
Теперь перейдем к фразе:

Стоп. А как же это понимать тогда?
TDD = TFD + refactoring.

Т.е в TFD, по-твоему все же может входить рефакторинг?
Странность твоей логики я поясню на следующей аналогии:

ТриЛитраВоды = ДваЛитраВоды + ЛитрВоды

Следовательно В ДаЛитраВоды не может входить ЛитрВоды.

Если переход от TFD к TDD подразумевает использование рефакторинга (причем, весьма специфичное использование -- см. статью), то как из этого можно сделать вывод, что в TFD рефакторинга -- никакого и никогда -- быть не может? Мне это непонятно.

Если для приготовления литра сладкой воды нужно добавить к воду к сиропу -- значит в сиропе воды нет. Вообще. Он сухой. Или на глицерине. Очень оригинальная логика.
 

pachanga

Новичок
Благодаря твоим аналогиям с сиропом, тремя литрами воды и коммунизмом я глубоко внутри понял, что некая вселенская истина обошла меня стороной, но вот какая? (э...в Коммунизме обязательно есть Советская власть?)

Давай лучше так - ты расскажешь мне пример из твоей практики использования TFD, буквально по шагам, на реальном примере. Затем я приведу тебе пример из своей практики того, как мы обычно в паре с syfisher занимаемся TDD. Мне просто интересно сравнить и понять, что же это за зверь такой многоликий TFD.

P.S. если бы robocomp знал во что это выльется :)

-~{}~ 16.02.06 23:22:

Оk, раз уж ты так любишь обращаться к цитатам:

(you may first need to refactor any duplication out of your design as needed, turning TFD into TDD)
Ошибаюсь ли я, в своем предположении, что ты don't refactor any duplication out of your design когда используешь TFD?

-~{}~ 16.02.06 23:27:

И еще, я вот тут в гугле покопался и набрел на интересную ссылку, так вот цитирую:

Test Driven Development (TDD), a software development
practice used sporadically for decades has gained added visibility
recently as a practice of Extreme Programming (XP) .
TDD is also known by names such as, Test First Design (TFD),
Test First Programming (TFP) and Test Driven Design (TDD). The
practice evolves the design of a system starting from the unit test
cases of an object. Writing test cases and implementing that object
or object methods then triggers the need for other objects/methods.
Мне кажется, автору этой статьи тоже бы понравились твои аналогии с сиропом ;)
 

Crazy

Developer
Автор оригинала: pachanga Ошибаюсь ли я, в своем предположении, что ты don't refactor any duplication out of your design когда используешь TFD?
Судя по вопросу -- даже пример с сиропом не помог.

В продолжении лично я смысла не вижу.
 

pachanga

Новичок
Послушай, разве что-то нелогично в моих аргументах?

Я очень внимательно прочитал статью, на которую ты ссылался. Там о TFD буквально несколько слов, и, по-моему, Амблер не выделяет TFD как самостоятельную от TDD дисциплину - для меня это неотъемлимая часть. Я не знаю, как можно писать тесты без постоянного рефакторинга, но, быть может, ты раскроешь секрет?

Мое предположение также доказывает довольно авторитеный документ, цитату из которого я привел. Его авторы вообще не видят разницы между TFD и TDD, о чем я говорил в самом начале спора. Согласен, что это не аналогия с сиропом?

Как вариант, я тебе предложил обменяться примерами разработки: ты с использованием TFD, я же с примером, основанным на моем понимании TDD.

Давай не будем превращать это в личную склоку, ок?
 

Crazy

Developer
Автор оригинала: pachanga Послушай, разве что-то нелогично в моих аргументах?
Прости, в пятый раз я начинать не стану. Это уже утоляет.

Давай не будем превращать это в личную склоку, ок?
Я уже сказал:

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

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

pachanga

Новичок
Ок, дело твое.

Я все же надеюсь, robocomp однажды ответит и расскажет о CI...
 

whirlwind

TDD infected, paranoid
>Я не знаю, как можно писать тесты без постоянного рефакторинга, но, быть может, ты раскроешь секрет?

Может быть речь идет о первоначальных тестах, тех самых, что пишутся до первого рефакторинга? Ведь TDD: test -> code -> refactoring. Вот и получается, что TFD, это проект, где реализовано test -> code без рефакторинга и возврата на test. Получается TFD - это "дизайн первого взгляда/версии", когда тестами описывается требуемый функционал и главное добиться, что бы этот функционал проходил по тестам. И здесь я согласен, лучше такие тесты, чем никаких. Кстати, TFD тесты легче представить, если не использовать моки. Если вместо них заюзать реальные юниты, то TFD - это очень быстрые тесты.
 

Crazy

Developer
whirlwind, это борьба с ветряными мельницами. :) Никто не утверждал, что TFD используется без рефакторинга вообще. Процитированное -- просто один из парадоксальных для меня выводов, сделанных с использованием загадочной логики.

Да, согласно моему пониманию TFD тесты пишутся до того, как начнется разработка кода. Рефакторинг при этом используется на тех же основаниях, на которых он используется при разработке вообще. Так, если при написании тестов я вижу, что три теста имеют много общего -- я выношу общий код в суперкласс или в утилиту. Классическое использование рефакторинга -- но не имеющее никакой привязки к TFD/TDD.

После того, как написаны ВСЕ тесты -- жизнь еще не кончается. К примеру, поступают новые требования. Соответственно, корректируется код тестов. Корректировка -- повод задуматься о рефакторинге.
 

pachanga

Новичок
Автор оригинала: whirlwind
Может быть речь идет о первоначальных тестах, тех самых, что пишутся до первого рефакторинга?
Да я понимаю, что, наверняка, это и имелось в виду. Только вот из моей практики ни разу не было такого случая чтобы "дизайн первой сессии" прижился больше чем на 5 минут. У нас рефакторинг идет постоянный.

Кстати, TFD тесты легче представить, если не использовать моки. Если вместо них заюзать реальные юниты, то TFD - это очень быстрые тесты.
Быстрые в каком плане?
 

whirlwind

TDD infected, paranoid
>Быстрые в каком плане?
В плане времени разработки конечно

>Да я понимаю, что, наверняка, это и имелось в виду. Только вот из моей практики ни разу не было такого случая чтобы "дизайн первой сессии"

У меня было, чесслово :) ORM пошел как по маслу, потому что я еще до написания тестов знал что и как будет и как не будет. Но эт конечно же не значит что вот прям как написал тесты от балды, так под них и код написал. Нет, тесты конечно менялись, но не так активно, как на этапе рефакторинга. А вот с MVC пришлось повозиться. Пока выделил выгодную сущность, несколько редакций тестов переписывать пришлось. А все потому, что не знал с какой стороны подступиться.

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

PS. И тесты у меня не изолированные. Моки не люблю - без них "случайно" выясняются граничные ситуации других юнитов (т.к. общее кол-во тестов увеличивается) да и время затраченное на изоляцию меня почему то не окупается. И рефакторинг у мну циклический. Так что мой TDD вполне подходит под определение TFD, хотя мне абсолютно по барабану как это называется, лишь бы в помощь :)
 

pachanga

Новичок
И тесты у меня не изолированные.
Немного не понял, что ты имеешь в виду под изоляцией в данном контексте. Если твои тесты выполняются в любой последовательности, не влияя друг на друга и автоматически устанавливая необходимую среду для тестирования(БД, набор директорий, почтовый сервер и проч.), то это, в принципе, и есть изоляция.

Моки не люблю - без них "случайно" выясняются граничные ситуации других юнитов (т.к. общее кол-во тестов увеличивается) да и время затраченное на изоляцию меня почему то не окупается.
Согласен почти на 100%, т.к. не раз была ситуация, когда моки в первоначальных тестах заменялись "реальными" классами или стабами в последующих итерациях рефакторинга тестов.

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

Так что мой TDD вполне подходит под определение TFD, хотя мне абсолютно по барабану как это называется, лишь бы в помощь
Вот и я про что, да хоть TFP :)
 

itprog

Cruftsman
С моками самое главное - знать меру и не слишком ими увлекаться.
Но ведь если объект "B", с которым работает тестируемый объект "A", окажется неправильно рабочим, то слетит и тест для класса "A".
Получается мы потратим некоторое время только лишь на выяснения того, что тест провалился из-за объекта "B"
 

whirlwind

TDD infected, paranoid
>Немного не понял, что ты имеешь в виду под изоляцией в данном контексте. Если твои тесты выполняются в любой последовательности, не влияя друг на друга и автоматически устанавливая необходимую среду для тестирования(БД, набор директорий, почтовый сервер и проч.), то это, в принципе, и есть изоляция.

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

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

-~{}~ 18.02.06 01:14:

PS

>Но ведь если объект "B", с которым работает тестируемый объект "A", окажется неправильно рабочим, то слетит и тест для класса "A".

ИМХО, дык лучше тест слетит, раньше чем софт. Они как раз для этого и нужны, в смысле тесты.
 

pachanga

Новичок
Но ведь если объект "B", с которым работает тестируемый объект "A", окажется неправильно рабочим, то слетит и тест для класса "A".
Получается мы потратим некоторое время только лишь на выяснения того, что тест провалился из-за объекта "B"
По-хорошему, также должен слететь тест на "B" и обычно из контекста видно, что если слетел тест на "B", который используется "A", то надо именно чинить "B".

Вот в этом-то, как ни странно, может и оказаться преимущество реальных объектов - мок порой дает лживое ощущение, что все работает, как надо :(
 
Сверху