TDD и юниттесты — это
1. способ описать, что конкретно будет делать код. Не в терминах классов, domain models etc, а в совершенно конкретных вещах — берем на входе a,b,c — получаем на выходе d,e,f. Не больше, но и не меньше. Не надо писать "на будущее", надо только то, что надо.
2. юниттесты — это не способ тестить приложение, этим занимаются тестеры. Юниттесты — это снапшот кода, работающего по описанным правилам.
3. Не тесты пишутся под код, а код под тесты. Это заставляет тщательно продумывать, чего, собственно, должен делать код, на совершенно конкретных примерах и ситуациях.
А то в большинстве случаев программирование сводится к
"Высоко-высоко над Небесным Градом, на небольшой площадке, венчающей
собою верхушку Шпиля Высотою в Милю, стоял Владыка Иллюзий, Мара-Сновидец.
Одет он был в плащ всех цветов — и не только радуги. Воздел он над головой
руки, и, сливаясь воедино с собственной силой, хлынула через его тело мощь
всех остальных богов.
В уме его обретала форму греза. И излил он ее наружу, как разливается
по пляжу накатившаяся на берег высокая волна." (c) понятно кто
Изливаем в редактор грезу вместо того, чтобы сделать работу.
Здравствуйте, loco_che, Вы писали:
_>1. способ описать, что конкретно будет делать код. Не в терминах классов, domain models etc, а в совершенно конкретных вещах — берем на входе a,b,c — получаем на выходе d,e,f. Не больше, но и не меньше. Не надо писать "на будущее", надо только то, что надо.
Не знаю как у тебя но у меня практически нет задач для которых можно сказать что точно должно быть на выходе ибо во время решения задачи приходится заниматся кучей исселедований и как следствие постановка порой всесьма сильно корректируется либо выход такого размера что составить его руками просто не реально.
Таким образом максимум что я могу себе позволить это после того как код написан сделать несколько дампов для того чтобы засекать изменения в работе системы.
А бывают случаи когда даже дамп не сделать...
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
WH>Не знаю как у тебя но у меня практически нет задач для которых можно сказать что точно должно быть на выходе ибо во время решения задачи приходится заниматся кучей исселедований и как следствие постановка порой всесьма сильно корректируется либо выход такого размера что составить его руками просто не реально.
Если вы не представляете, что должно быть на выходе конкретного метода при подаче на вход конкретных значений — как вы можете быть уверены, что ваш код делает то, что должен?
Понятно, если есть 1 огромная функция, КОТОРАЯ ДЕЛАЕТ ВСЕ — тут да, тяжеловато.
Но суть-то как раз и в том, чтоб не писать сперва такой код и потом думать, как же его проверить-то
Суть в том, что сперва написать тест для проверки конкретной небольшой части кода, читай — написать правила, по которым должна работать эта конкретная часть кода. Потом — реализовать ее именно в том виде, в каком она придумана для теста. Потом убедиться, что она работает именно так, как придумано. И все.
WH>Таким образом максимум что я могу себе позволить это после того как код написан сделать несколько дампов для того чтобы засекать изменения в работе системы.
Юниттесты — это не способ проверить, как работает система. Для этого есть тестеры
Это способ убедиться, что написанные методы делают именно то, что должны и так, как должны. Автоматически, без отладки. Запустил раннер — все зеленое — ок
Красное — где-то что-то напортачил, чиним не отходя от кассы. Кто-то еще напортачил в методе, изменил логику под свои нужды, а ты и не знаешь об этом — о да, у него все работает, а у тебя нет. Что делать? Запускаем тесты и сразу видим, где жопа. Лучше сразу после изменений, чем тестер откопает это через месяц, или, что хуже, найдет клиент
WH>А бывают случаи когда даже дамп не сделать...
Бывают
Но компиляете-то вы исходники у себя на машине, так ведь?
По сути, тесты — это некая инкарнация компилятора. Компилятор вам говорит, что новонаписанный код нарушает синтаксис, тесты — где нарушена описанная в них логика.
Кстати
Ваша подпись... Энштейн, помимо этого, еще и говорил — Любой дурак может сделать систему сложнее, дороже и опаснее. Но только гениальный человек, достаточно храбрый для, способен двигаться в обратном направлении
Здравствуйте, loco_che, Вы писали:
_>Если вы не представляете, что должно быть на выходе конкретного метода при подаче на вход конкретных значений — как вы можете быть уверены, что ваш код делает то, что должен?
Наверное мы работаем на разных уровнях.
Лично мне никто и никогда не ставит задание:
Написать класс байда с методами инь, янь, хрень. Каждый из которых должен делать то-то и то-то.
Мне ставят задачи както так:
Придумать объектную систему в которой объект владелец может добавлять свойства тем объектам которыми он владеет (как придумай сам).
Все это должно описыватчся декларотивно (как придумай сам)
система должна сама сериализовать эту объектную систему (как придумай сам) в формат (придумай сам)
...
И главное все это должно быть расшаряемо.
Ну и к чему тут можно написать тесты? Мне особенно интересно как протестировать расшаряемость.
_>Понятно, если есть 1 огромная функция, КОТОРАЯ ДЕЛАЕТ ВСЕ — тут да, тяжеловато.
Подавляющие большинство моих функций не привышают 10 строк. _>Но суть-то как раз и в том, чтоб не писать сперва такой код и потом думать, как же его проверить-то _>Суть в том, что сперва написать тест для проверки конкретной небольшой части кода, читай — написать правила, по которым должна работать эта конкретная часть кода. Потом — реализовать ее именно в том виде, в каком она придумана для теста. Потом убедиться, что она работает именно так, как придумано. И все.
Если тебе ставят задание "написать класс байда..." то так работать можно, а если тебе ставять задание в виде "Придумать объектную систему..." то так работать невозможно ибо до того как работа будет закончена код будет переписан 3 раза. Меньше не получается. И на каждый раз писать тесты это просто пустая трата времени. Болие того непонятно даже что писать ибо я еще не придумал как это должно работать, какие должны быть классы, какие у них должны быть методы и тем болие что они должны делать.
_>Юниттесты — это не способ проверить, как работает система. Для этого есть тестеры _>Это способ убедиться, что написанные методы делают именно то, что должны и так, как должны. Автоматически, без отладки. Запустил раннер — все зеленое — ок
А если ошабка в тесте? _>Красное — где-то что-то напортачил, чиним не отходя от кассы. Кто-то еще напортачил в методе, изменил логику под свои нужды, а ты и не знаешь об этом — о да, у него все работает, а у тебя нет. Что делать? Запускаем тесты и сразу видим, где жопа. Лучше сразу после изменений, чем тестер откопает это через месяц, или, что хуже, найдет клиент
Вот для этого я и использую дампы решения. После изменений запусткается код и если дампы отличаются от эталонных то разбираемся что произошло.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
WH>Лично мне никто и никогда не ставит задание:
Мне тоже не ставят Мечтаю, чтоб ставили! Сиди себе и пиши. Нет, все самому приходится
WH>Мне ставят задачи както так: WH>... WH>И главное все это должно быть расшаряемо.
Тебе в любом случае надо иметь спецификацию. Либо ты ее пишешь сам, либо клиент. После того как она утверждена, начинаем рисовать юз кейзы на каждый пункт спецификации, и т.д. Т.д. — это все у Бека описано, копи-пастить сюда — это много
WH>Ну и к чему тут можно написать тесты? Мне особенно интересно как протестировать расшаряемость.
Ну вот тыж не читаешь, чего я пишу
Я пишу — тесты — это снапшот рабочего кода, гарантия, что код работает так, как ты его описал/задумал, что ты в результате очередной правки ничего не поломал.
А ты мне — а как мне тестить расширяемость...
WH>Если тебе ставят задание "написать класс байда..." то так работать можно, а если тебе ставять задание в виде "Придумать объектную систему..." то так работать невозможно ибо до того как работа будет закончена код будет переписан 3 раза.
Ты что, сразу код пишешь!?
WH>Меньше не получается. И на каждый раз писать тесты это просто пустая трата времени.
Не надо писать тесты под код
Надо писать код, котрый легко тестить
WH>Болие того непонятно даже что писать ибо я еще не придумал как это должно работать, какие должны быть классы, какие у них должны быть методы и тем болие что они должны делать.
Вот как придумаешь — сразу пиши тесты. Не код, а тесты, а потом — код.
WH>А если ошабка в тесте?
А ты пиши такие тесты(и, соответственно, код), чтобы они были маленькие и однозначные.
WH>Вот для этого я и использую дампы решения. После изменений запусткается код и если дампы отличаются от эталонных то разбираемся что произошло.
Здравствуйте, loco_che, Вы писали:
_>Мне тоже не ставят Мечтаю, чтоб ставили! Сиди себе и пиши. Нет, все самому приходится
А лично я сразу уволюсь если мне попытаются так задачу поставить.
_>Тебе в любом случае надо иметь спецификацию.
Какую еще спецификацию? "Класс байда с етодами инь, янь, хрень"? _>Либо ты ее пишешь сам, либо клиент.
Клиент понятие слишком растяжимое.
Если клиент это бугалтерик мегаконторы "Рога и копыта" то нужно писать спецификацию формочек. Если клиент это мега-софтовая контора "Твердософт" то нужно писать спецификацию на публичные классы и методы. _>После того как она утверждена, начинаем рисовать юз кейзы на каждый пункт спецификации, и т.д. Т.д. — это все у Бека описано, копи-пастить сюда — это много
Рисовать? В сад! Пустая трата времени. Работал я в разных конторах и ни разу от рисовальщиков накакого полезного выхлопа небыло. Те совсем никакого. Лучше бы писателей доков на их место наняли.
_>Я пишу — тесты — это снапшот рабочего кода, гарантия, что код работает так, как ты его описал/задумал, что ты в результате очередной правки ничего не поломал.
1)Снапшот кода это вобще не понятно что такое.
2)Если всетки имеется в виду снапшот результата работы то зачем его писать руками?
Лично я сначало пишу рабочий код. Потом пишу текстувую дампилку результатов (в языках с рефлекшеном это можно сильно автоматизировать).
После чего запускаю код с несколькими наборами аргументов на которых он может свалится и формирую дамп. Далие я этот дамп смотрю е если там все как задумано объявляю его эталонным.
Теперь если кто-то что-то поменял и у меня что-то поломалось то дампы изменятся и это очень легко отследить.
Выглядит это примерно так:
_>Ты что, сразу код пишешь!?
Да. Если ты можешь с чистого листа без единого прототипа нарисовать подсистему на 150К кода учтя все требования не забыв про то что это все нужно интегрировать в систему в которой уже болие 10 метров кода также нужно помнить про главное не функциональное требование расширяемость (оно даже главнее производительности при условии что она не фатально низкая). И при всем этом по твоим рисункам можно будет точно воссоздать систему не внеся в рисунки ни единого изменения и не делая отходов от рисунков в коде то ты мега гений и не понятно что делаешь среди нас простых смертных.
Лично я ничинаю с прототипа который непрерывно рефакторю.
После массы совещаний, продумываний, натыканий на грабли окружения... этот прототип постепенно превращается в законченую систему.
_>Надо писать код, котрый легко тестить
Надо писать код результат которого можно сдампить в текстовый файл, а это справедливо почти для любого кода. Это позволяет засечь непредвиденное изменение поведения. Больше ничего не нужно. Болие того в нормальном дампе все прекрасно видно.
_>Ну так в тестах-то искать быстрее искать
Уверен?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Немного от темы , я очень много раз слышал про код , который пишется один раз , до которого были написаны юнит тесты , который так хорош и просто , что его можно
1. Обдумать
2. Написать тесты
3. написать сам код.
Все про него говорят , но только я ни разу не встречал . кошмар короче , вероятно этот код по жизни бегает от меня и прячется ...
Здравствуйте, minorlogic, Вы писали:
M>Немного от темы , я очень много раз слышал про код , который пишется один раз , до которого были написаны юнит тесты , который так хорош и просто , что его можно
M>1. Обдумать M>2. Написать тесты M>3. написать сам код.
M>Все про него говорят , но только я ни разу не встречал . кошмар короче , вероятно этот код по жизни бегает от меня и прячется ...
открой любую книжку по программированию..
какое нибудь жёлтобелое дерево..
да просто бинарный поиск..
их проще всего на тестах отлаживать..
Здравствуйте, minorlogic, Вы писали:
M>Немного от темы , я очень много раз слышал про код , который пишется один раз , до которого были написаны юнит тесты , который так хорош и просто , что его можно
M>1. Обдумать M>2. Написать тесты M>3. написать сам код.
M>Все про него говорят , но только я ни разу не встречал . кошмар короче , вероятно этот код по жизни бегает от меня и прячется ...
Ты хочешь, чтобы он тебя преследовал?
А вообще никакая методология не применяется в чистом виде.
Всегда есть различные отклонения от "генеральной линии".
Если это принять, то многие проблемы чудным образом исчезают.
У нас в конторе довольно много юнит тестов.
Каждую ночь уходит около 4-х часов на прогон всех тестов.
Когда получается, то пишем их именно в последовательности "обдумать, написать тест, написать код".
Если не получается — это не трагедия. Значит напишем чуть позже по уже написанному коду.
Но я себя чувствую комфортнее, если написанный кусочек кода могу сразу же потестировать.
Здравствуйте, loco_che, Вы писали:
_>TDD и юниттесты — это
Я что-то не понял?
Это ответ или упрек? А кому и на что?
Тут рядом была большая ветка, в которой подробно обсуждали юнит тесты и высказывались различные точки зрения. В том числе и эта несколько раз (мной, например).
Хотя я и полностью согласен с таким взглядом а юнит-тесты, все же советую внимательно почитать ту ветку, а не пытаться сразу просвещать дикарей Там достаточно умных людей отметилось с интересными мыслями и с собственным опытом разработки, который может сильно отличаться от твоего...
Здравствуйте, Mikhail Polykovsky, Вы писали:
_>>Ты что, сразу код пишешь!? WH>Да. [skip] то ты мега гений и не понятно что делаешь среди нас простых смертных.
MP>ХитрО. Ты сам утверждаешь что пишешь код сразу, а затем записываешь таких как ты в гении. Мания величия?
Есть разница между писать сразу код и писать сразу код
WolfHound вроде четко сказал, что пишет сперва прототип, потом его многократно изменяет и обрабатывает, пока не получится уже окончательная структура, после чего она доделывается уже окончательно. Очень разумный и эффективный подход.
И это немножно не то, что сесть и сразу написать (или там — нарисовать так, что по ней без изменений можно написать) готовую рабочую систему, не находишь?
З.Ы.
Комбинация хитрого скипа в цитировании и собственной фразы, из-за которой изменился смысл высказывания, не остался незамеченным . Повторяем для хитрых — WH утверждал, что нереально сразу придумать правильную, эффективную и удобную структуру программы, ни разу ее не попробовав в прототипах. Бумага все стерпит — там легко нарисовать все классно и красиво, но при попыках отобразить эти рисунки на код обычно получаются проблемы, которые ведут либо к окольным путям в коде, либо к перерисовыванию рисунков и пререписванию кода наново. Т.е. те же самые прототипы, которые он и предлагает сразу делать.
Только и всего. Ты же сумел представить его слова совершенно иначе. Ай-яй-яй!
_>>>Ты что, сразу код пишешь!? WH>>Да. [skip] то ты мега гений и не понятно что делаешь среди нас простых смертных.
MP>>ХитрО. Ты сам утверждаешь что пишешь код сразу, а затем записываешь таких как ты в гении. Мания величия?
F>Есть разница между писать сразу код и писать сразу код F>WolfHound вроде четко сказал, что пишет сперва прототип, потом его многократно изменяет и обрабатывает, пока не получится уже окончательная структура, после чего она доделывается уже окончательно. Очень разумный и эффективный подход.
F>И это немножно не то, что сесть и сразу написать (или там — нарисовать так, что по ней без изменений можно написать) готовую рабочую систему, не находишь?
Здесь две части — проектирование и программирование. Мне кажется, что мы ломимся в открытую дверь, споря друг с другом. Я согласен, что сразу готовую программу написать сложно, как говорил Брукс "первую версию придется выкинуть". Но при этом мне показалось, что вы с WH отрицаете стадию проектирования, переходя сразу к написанию кода. И вот с этим я согласиться не смог Если я вас неправильно понял — извините.
F>Комбинация хитрого скипа в цитировании и собственной фразы, из-за которой изменился смысл высказывания, не остался незамеченным
Да? Я просто попытался выделить главное, обо что споткнулся. Приношу свои извинения, если извратил смысл исходного поста.
Здравствуйте, Mikhail Polykovsky, Вы писали:
MP>Здесь две части — проектирование и программирование. Мне кажется, что мы ломимся в открытую дверь, споря друг с другом. Я согласен, что сразу готовую программу написать сложно, как говорил Брукс "первую версию придется выкинуть". Но при этом мне показалось, что вы с WH отрицаете стадию проектирования, переходя сразу к написанию кода. И вот с этим я согласиться не смог Если я вас неправильно понял — извините.
Никто не отрицает проектирование. Просто выделеная стадия проектирование совершенно бессмысленна. Ни на бумаге ни в розе нельзя учесть даже все грабли о которых знаешь. О тех что не знаешь я вобще молчу. А когда начинаешь писать код то видно все и сразу. И при первых признаках проблемы можно изменить дизайн так чтобы этой проблемы больше небыло.
При таком подходе результат получается гораздо быстрее и гораздо качественнее. Также совершенно ясно что такой подход совершенно не совместим с юнит тестами ибо классы и методы постоянно появляются, исчезают, расщепляются и сливаются. Поддерживать актуальность тестов при таком подходе просто не возможно.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, Mikhail Polykovsky, Вы писали:
MP>>Здесь две части — проектирование и программирование. Мне кажется, что мы ломимся в открытую дверь, споря друг с другом. Я согласен, что сразу готовую программу написать сложно, как говорил Брукс "первую версию придется выкинуть". Но при этом мне показалось, что вы с WH отрицаете стадию проектирования, переходя сразу к написанию кода. И вот с этим я согласиться не смог Если я вас неправильно понял — извините. WH>Никто не отрицает проектирование. Просто выделеная стадия проектирование совершенно бессмысленна. Ни на бумаге ни в розе нельзя учесть даже все грабли о которых знаешь. О тех что не знаешь я вобще молчу. А когда начинаешь писать код то видно все и сразу. И при первых признаках проблемы можно изменить дизайн так чтобы этой проблемы больше небыло.
Ага. Теперь мне ясна ваша позиция, хотя я придерживаюсь противоположног подхода и считаю выделенную стадию проектирвоания очень важной. Что ж, каждый создает программу так, как ему удобнее
WH>При таком подходе результат получается гораздо быстрее и гораздо качественнее. Также совершенно ясно что такой подход совершенно не совместим с юнит тестами ибо классы и методы постоянно появляются, исчезают, расщепляются и сливаются. Поддерживать актуальность тестов при таком подходе просто не возможно.
Как обычно, важное дополнение — у вас результат получается гораздо быстрее. Поскольку у меня мнение противоположное, легко представить всю гамму вариантов между ними
Здравствуйте, Mikhail Polykovsky, Вы писали:
MP>Ага. Теперь мне ясна ваша позиция, хотя я придерживаюсь противоположног подхода и считаю выделенную стадию проектирвоания очень важной. Что ж, каждый создает программу так, как ему удобнее
Соглашусь с этим.
Каждый раз, когда мы на проекте выделяли специально время "на подумать"
и порисовать в MagicDraw, результат был всегда лучше, чем при спонтанном проектировании.
Проблемы открывались раньше и переделовать приходилось меньше.
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, Mikhail Polykovsky, Вы писали:
MP>>Здесь две части — проектирование и программирование. Мне кажется, что мы ломимся в открытую дверь, споря друг с другом. Я согласен, что сразу готовую программу написать сложно, как говорил Брукс "первую версию придется выкинуть". Но при этом мне показалось, что вы с WH отрицаете стадию проектирования, переходя сразу к написанию кода. И вот с этим я согласиться не смог Если я вас неправильно понял — извините. WH>Никто не отрицает проектирование. Просто выделеная стадия проектирование совершенно бессмысленна. Ни на бумаге ни в розе нельзя учесть даже все грабли о которых знаешь. О тех что не знаешь я вобще молчу. А когда начинаешь писать код то видно все и сразу. И при первых признаках проблемы можно изменить дизайн так чтобы этой проблемы больше небыло. WH>При таком подходе результат получается гораздо быстрее и гораздо качественнее. Также совершенно ясно что такой подход совершенно не совместим с юнит тестами ибо классы и методы постоянно появляются, исчезают, расщепляются и сливаются. Поддерживать актуальность тестов при таком подходе просто не возможно.
Абсолютно согласен с тем, что прототипирование важно и что практически нереально взять сесть и все заранее продумать. Но полагаю, что это никак не противоречит юнит тестам. Во-первых, эволюция кода совсем не означает, что код меняется по всему приложению/системе. Скорее всего он изменяется в некой локальной части и не аффектит все остальное (если это не так, то, скорее всего, надо что-то передизайнивать). Поэтому при изменении кода имеет смысл не все юнит тесты переписывать, а только те, которые относятся к той части кода, которая меняется. Юнит тесты вообще не надо переписывать, если меняется только внутреннее устройство тестируемого юнита и не меняется его интерфейс (что в общем-то бывает нередко).
Во-вторых, подход с текстовой дампилкой будет также неудовлетворительно себя вести при тотальном изменении кода, как и юнит тесты; поскольку эталонные дампы результатов станут неактуальны.
Здравствуйте, bkat, Вы писали:
B>Соглашусь с этим. B>Каждый раз, когда мы на проекте выделяли специально время "на подумать" и порисовать в MagicDraw, результат был всегда лучше, чем при спонтанном проектировании.
Ты все не так понял. Нет никакого спонтанного проектирования.
Просто проектирование идет прямо в коде. Это не отменяет совещаний и обсуждений того куда все катится. Болие того иногда даже на доске цеветными фломастерами рисуют схемы но эти схемы находятся на гораздо болие высоком уровне чем классы и тем болие методы и служат они исключительно для того чтобы было проще объяснить другим как в принципе работает система.
Но никто и никогда не рисует классы и тем болие методы ибо это совершенно пустая трата времени.
B>Проблемы открывались раньше и переделовать приходилось меньше.
Извини не поверю. Разрисовать систему можно только на очень высоком уровне где каждый кружочек раскрывается в десятки и сотни килобайт кода.
Все попытки спустится ниже утыкаются в детали работы с окружением и ничего с этим не поделать.
Болие того на большинство вопросов без написания прототипа ответить невозможно. Хуже того некоторые вопросы и не возникают до того как будет написан хотябы один прототип.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн