Привет всем.
Хотел узнать, применяете ли вы в рабочих проектах модульное тестирование (а возможно и вообще TDD)
и какие мысли у вас есть на этот счет. Стоит ли игра свечь или нет?
В последнее время сталкиваюсь с большим колличеством советов обязательно использовать unit testing — проскакивает во многих подкастах .NET Rocks и Hanselminutes, но также
часто слышу, что это ерунда — с изменением кода необходимо менять тесты, трата времени и т.д.
(пример — Unit testing is teh suck, Urr.)
Хочется послушать людей, которые удачно применяли TDD или просто использовали Unit testing, а также тех, кто является его противником.
P.s. быстро прошелся поиском, вроде похожей темы небыло. В любом случае освежить не помешает
Здравствуйте, BokiyIS, Вы писали:
BIS>Привет всем. BIS>Хотел узнать, применяете ли вы в рабочих проектах модульное тестирование (а возможно и вообще TDD) BIS>и какие мысли у вас есть на этот счет. Стоит ли игра свечь или нет? BIS>В последнее время сталкиваюсь с большим колличеством советов обязательно использовать unit testing — проскакивает во многих подкастах .NET Rocks и Hanselminutes, но также BIS>часто слышу, что это ерунда — с изменением кода необходимо менять тесты, трата времени и т.д. BIS>(пример — Unit testing is teh suck, Urr.) BIS>Хочется послушать людей, которые удачно применяли TDD или просто использовали Unit testing, а также тех, кто является его противником.
BIS>P.s. быстро прошелся поиском, вроде похожей темы небыло. В любом случае освежить не помешает
Юнит-тесты применяю, ТДД — нет.
Юнит-тесты в мней практике во многих случаях доказали свою полезность.
Стандартный сценарий, в котором они полезны — ты разрабатываешь класс, естественно, как-то его тестируешь, понемножку класс обрастает функциональностью, ты его, естественно, рефакторишь и, естественно, не проверяешь, не сломалась ли старая функциональность, потому что ты ее уже тестировал.
Так вот когда ты с классом закончил и класс готов к коммиту, ты начинаешь писать тесты и вдруг обнаруживаешь, что работает не все, а только то, что ты тестил в последнее время. Заодно, когда ты концентрируешься на тестах, ты начинаешь писать тесты на всякие исключительные ситуациии и прочие граничные случаи, и тоже иногда оказывается, что какой-то конкретный случай ты не обрабатываешь.
Для рефакторинга юнит-тесты вообще вещи незаменимая, потому что рефакторинг по определению — это изменение когда без изменения функциональности, и юнит-тесты для контроля этого аспекта подходят как нельзя лучше.
Плюс юнит-тесты заставляют делать много маленьких независимых классов, потому что универсальный всемогутер осмысленному тестированию практически не поддается — количество тестов, которые нужно написать, растет экспоненциально с каждой лишней мелкой функциональностью.
А когда у тебя есть маленькие простые классы, то, во-первых, тесты для них пишутся элементарно и написать их неправильно затруднительно, а во-вторых, у простых классов гораздо больше шансов быть переиспользованными без переписывания вообще (и как следствие — без переписывания тестов): изменится лишь код, компонующий эти классы вместе; и в-третьих, писать тесты на скомпонованный класс, основываясь на том, что более мелкие компоненты уже оттестированы своими тестами, гораздо проще.
А идеология "сначала тесты, потом код", имхо — это уже экстремизм: слишком многое может поменяться в процессе написания этого самого кода.
BokiyIS wrote:
> Хотел узнать, применяете ли вы в рабочих проектах модульное тестирование > (а возможно и вообще TDD)
Да, если это только возможно.
> и какие мысли у вас есть на этот счет. Стоит ли игра свечь или нет?
Да. 100%
> часто слышу, что это ерунда — с изменением кода необходимо менять тесты, > трата времени и т.д.
0) не во всех случаях изменения кода меняются тесты. Т.е. это просто неправда.
Есть случаи, когда меняется, есть — когда не меняется. Обычно, если интерфейс
и семантика модуля не меняется, то не меняются и тесты.
1) Даже когда тесты надо переписывать, иного способа надёжного тестирования
нет.
J>Для рефакторинга юнит-тесты вообще вещи незаменимая, потому что рефакторинг по определению — это изменение когда без изменения функциональности, и юнит-тесты для контроля этого аспекта подходят как нельзя лучше.
Смотря на какую функциональность ты смотришь.
Если приложения в целом (или подсистемы в целом), то юнит-тесты бесполезны. Если рефакторинг отдельных классов, то этот рефакторинг мало полезен.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
1) TDD не применяю, хотя в свое время разбирался что это такое
2) Unit тестирование скорее не применяю, чем применяю
3) Автоматизированное (при помощи unit фреймворков) функциональное тестирование применяю регулярно.
... << RSDN@Home 1.2.0 alpha 4 rev. 1218 on Windows Vista 6.1.7100.0>>
Здравствуйте, BokiyIS, Вы писали:
BIS>Привет всем. BIS>Хотел узнать, применяете ли вы в рабочих проектах модульное тестирование (а возможно и вообще TDD) BIS>и какие мысли у вас есть на этот счет. Стоит ли игра свечь или нет?
Unit-тестирование без TDD чаще всего бесполезное занятие.
BIS>В последнее время сталкиваюсь с большим колличеством советов обязательно использовать unit testing — проскакивает во многих подкастах .NET Rocks и Hanselminutes, но также BIS>часто слышу, что это ерунда — с изменением кода необходимо менять тесты, трата времени и т.д. BIS>(пример — Unit testing is teh suck, Urr.)
Это от того что люди не понимают зачем пишутся тесты.
BIS>Хочется послушать людей, которые удачно применяли TDD или просто использовали Unit testing, а также тех, кто является его противником.
Я более-менее удачно применяю TDD.
Я не буду писать плюсы-минусы, влом Но отмечу один момент: представьте что у вас проект в несколько сот тысяч строк кода и вам надо сделать пусть даже небольшой рефакторинг? Вообще я заметил что необходимость некоторых вещей понимается только на средних и больших проектах.
Здравствуйте, MozgC, Вы писали:
MC>Я не буду писать плюсы-минусы, влом Но отмечу один момент: представьте что у вас проект в несколько сот тысяч строк кода и вам надо сделать пусть даже небольшой рефакторинг? Вообще я заметил что необходимость некоторых вещей понимается только на средних и больших проектах.
Или на коде, к которому лет пять никто не притрагивался.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, BokiyIS, Вы писали:
BIS>Привет всем. BIS>Хотел узнать, применяете ли вы в рабочих проектах модульное тестирование (а возможно и вообще TDD) BIS>и какие мысли у вас есть на этот счет. Стоит ли игра свечь или нет?
Ответ банальный: зависит от того, что за задача. Я для себя отметил, что если идет разработка самого алгоритма (нетривиального), то Unit-тесты в обычном варианте не самый удачный вариант. Главным образом по следующим причинам: (1) нетривиальный алгоритм тяжело разбить на составные части, каждую из которых легко протестировать (2) часто все части работают по отдельности правильно, но существует расклад, который рушит больше взаимодействие этих частей (3) ошибка проявляется не нетривиальных сущностях (4) алгоритм в разработке часто меняется, мало фиксированных частей.
В этом случае более полезен набор тестовых задач, на которые натравливается алгоритм, и на выходе % решенных задач, затраченное время и т. п.
Здравствуйте, Mystic, Вы писали:
M>Ответ банальный: зависит от того, что за задача. Я для себя отметил, что если идет разработка самого алгоритма (нетривиального), то Unit-тесты в обычном варианте не самый удачный вариант. Главным образом по следующим причинам: (1) нетривиальный алгоритм тяжело разбить на составные части, каждую из которых легко протестировать (2) часто все части работают по отдельности правильно, но существует расклад, который рушит больше взаимодействие этих частей (3) ошибка проявляется не нетривиальных сущностях (4) алгоритм в разработке часто меняется, мало фиксированных частей.
M>В этом случае более полезен набор тестовых задач, на которые натравливается алгоритм, и на выходе % решенных задач, затраченное время и т. п.
В этом случае цельный алгоритм (пусть это будет какой-нибудь поиск на графах) можно принять за юнит. Влезать в него и тестировать каждый оператор правда нет смысла.
А использовать нетривиальные алгоритмы не прогнав по ним набор тестовых задачь — вообще ахтунг!
Здравствуйте, FR, Вы писали:
FR>Здравствуйте, gandjustas, Вы писали:
G>>Unit-тестирование без TDD чаще всего бесполезное занятие.
FR>Очень даже полезное
А потом появляются темы типа "я написал 150 unit-тестов, для своего класса, потом поменял в классе одну строчку и мне пришлось больше половины тестов переписать".
Писать unit-тесты, для кода который не предназачался для такого тестирования очень тяжко. Обычно отдельно класс или функцию протестировать не получается, прходится тестировать большой связный кусок кода или использовать тулзы типа TypeMock.
G>А потом появляются темы типа "я написал 150 unit-тестов, для своего класса, потом поменял в классе одну строчку и мне пришлось больше половины тестов переписать".
G>Писать unit-тесты, для кода который не предназачался для такого тестирования очень тяжко. Обычно отдельно класс или функцию протестировать не получается, прходится тестировать большой связный кусок кода или использовать тулзы типа TypeMock.
А не мог ли бы ты описать примерную твою предметную область и типичные сроки сдачи чего-либо?
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Здравствуйте, thesz, Вы писали:
G>>А потом появляются темы типа "я написал 150 unit-тестов, для своего класса, потом поменял в классе одну строчку и мне пришлось больше половины тестов переписать".
G>>Писать unit-тесты, для кода который не предназачался для такого тестирования очень тяжко. Обычно отдельно класс или функцию протестировать не получается, прходится тестировать большой связный кусок кода или использовать тулзы типа TypeMock.
T>А не мог ли бы ты описать примерную твою предметную область и типичные сроки сдачи чего-либо?
Последнее чем занимался — веб приложения, в основном электронная коммерция, документооборот и все такое. Итерации короткие, неделя-две.
Здравствуйте, jazzer, Вы писали:
J>Плюс юнит-тесты заставляют делать много маленьких независимых классов, потому что универсальный всемогутер осмысленному тестированию практически не поддается — количество тестов, которые нужно написать, растет экспоненциально с каждой лишней мелкой функциональностью. J>А когда у тебя есть маленькие простые классы, то, во-первых, тесты для них пишутся элементарно и написать их неправильно затруднительно, а во-вторых, у простых классов гораздо больше шансов быть переиспользованными без переписывания вообще (и как следствие — без переписывания тестов): изменится лишь код, компонующий эти классы вместе; и в-третьих, писать тесты на скомпонованный класс, основываясь на том, что более мелкие компоненты уже оттестированы своими тестами, гораздо проще.
+1
J>А идеология "сначала тесты, потом код", имхо — это уже экстремизм: слишком многое может поменяться в процессе написания этого самого кода.
Многое меняется в процессе написания потому что заранее неизвестно как оно должно работать. Я верю что есть зубры, которые проводят детальное проектирование в голове, а потом пишут с первого раза нужный код, но таких не встречал.
Именно поэтому тесты и пишутся перед кодом — чтобы понять как оно будет работать.
S>В этом случае цельный алгоритм (пусть это будет какой-нибудь поиск на графах) можно принять за юнит.
Так и получается. Только UNIT-тестирование сводится к разработке внешнего приложения, которое читает последовательно файлы из парки, парсит их на предмет данных и результатов, данные загоняет в алгоритм и проверяет результат...
S>А использовать нетривиальные алгоритмы не прогнав по ним набор тестовых задачь — вообще ахтунг!
Не всегда эти тестовые задачи есть. Ну и бывает когда задачи есть, а ответов нету.
G>>>Unit-тестирование без TDD чаще всего бесполезное занятие.
FR>>Очень даже полезное
G>А потом появляются темы типа "я написал 150 unit-тестов, для своего класса, потом поменял в классе одну строчку и мне пришлось больше половины тестов переписать".
Люблю телепатов
G>Писать unit-тесты, для кода который не предназачался для такого тестирования очень тяжко. Обычно отдельно класс или функцию протестировать не получается, прходится тестировать большой связный кусок кода или использовать тулзы типа TypeMock.
Здравствуйте, thesz, Вы писали:
J>>Для рефакторинга юнит-тесты вообще вещи незаменимая, потому что рефакторинг по определению — это изменение когда без изменения функциональности, и юнит-тесты для контроля этого аспекта подходят как нельзя лучше.
T>Смотря на какую функциональность ты смотришь.
T>Если приложения в целом (или подсистемы в целом), то юнит-тесты бесполезны.
естественно, потому что приложение в целом — это не юнит, если это не приложение типа grep, конечно же.
Но приложение в целом собирается из кусков, и лучше, чтоб эти куски были оттестированы соответствующими юнит-тестами, чем держать пальцы крестиком на тему "надеюсь, что этот компонент в этих условиях не сглючит"
T>Если рефакторинг отдельных классов, то этот рефакторинг мало полезен.
Если у тебя есть класс А, который использует классы Б и В, а ты его рефакторишь на использование классов Г и Д (не говоря уже о микро-рефакторингах типа "вынести метод" и т.п.) — это вполне себе рефакторинг, и юнит-тесты тут очень в тему.
Здравствуйте, gandjustas, Вы писали:
J>>А идеология "сначала тесты, потом код", имхо — это уже экстремизм: слишком многое может поменяться в процессе написания этого самого кода. G>Многое меняется в процессе написания потому что заранее неизвестно как оно должно работать. Я верю что есть зубры, которые проводят детальное проектирование в голове, а потом пишут с первого раза нужный код, но таких не встречал. G>Именно поэтому тесты и пишутся перед кодом — чтобы понять как оно будет работать.
а как насчет того, что ты не учел 50 взаимосвязей, из-за который весь твой тестирующий код не имеет смысла, просто потому что, скажем, невозможно в заданном порядке сконструировать объекты, по каким угодно причинам?
Я несколько раз пробовал подступиться в ТДД, и каждый раз напарывался на это.
Я предпочитаю работать снизу вверх.
Т.е. смотрю на задачу и думаю, чем придется заниматься коду в процессе ее решения.
И пишу простые маленькие компоненты, которые изолированно занимаются именно этими вещами.
Естественно, с тестами.
И когда ты доходишь до момента, когда минимальные сущности уже не выделяются, оказывается, что собрать требуемую подсистему из готовых компонентов сравнительно просто и быстро, так что ты можешь более-менее свободно экспериментировать, и главное, что эти компоненты потому будут использоваться в других местах проекта, уже будучи оттестированными.
А ТДД в этом смысле — это немного наоборот, сверху вниз, потому что ты пишешь тесты сразу для подсистемы, и то, какая будет архитектура этой подсистемы, что в ней универсального и переиспользуемого, остается за скобками — главное ведь, чтоб тесты сходились...