LINUX.ORG.RU

А вы используете TDD в своих проектах?

 


0

3

Не модульные тесты (функциональные, интеграционные), не регресс-тестирование, не test-first, а именно test driven?

Кто-нибудь вообще понимает разницу между этими понятиями?

Странно, что поиск по ЛОРу находит не такие уж древние темы, в которых суровые самоуверенные дядьки только пытаются придумать контраргументы (но не могут, лол). ИРЛ такое сопротивление встречал только в паре контор, что характерно, обе поддерживают цппшные трупопроекты десятилетней давности.

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

Почему «гуру программирования» не сумели разобраться в такой простой технологии? Там же вся методика в 100 страницах разжёвана. Неужели туча лишних телодвижений по проектированию и отладке - это действительно так интересно?

★★★
Ответ на: комментарий от anonymous

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

pulo
()
Ответ на: комментарий от anonymous

новый код пишется только в том объеме, который достаточен для прохождения теста

Вот меня в TDD вечно смущает вот эта часть. Звучит как «пишите любой говнокод, лишь бы позеленело, а внутренние кишки как-нибудь потом порефакторим». Хотя если качественно дробить на мелкие части и писать правильные тесты (что поднимает вопрос, кто будет писать тесты на тесты), то по идее «если оно крякает как утка, то это скорее всего утка».

ilammy ★★★
()
Ответ на: комментарий от pulo

Разница с листочком только в том, что он вас не проверит. И через полгода не закричит, что вы что-то сломали при рефакторинге/внесении новой функциональности.

А так тоже самое. Хотя я и листочками пользуюсь.

anonymous
()
Ответ на: комментарий от ilammy

Вы слишком формально подходите, как мне кажется. Если человек хочет писать говнокод - никакая методика не поможет. А нормальному человеку TDD помогает меньше косячить. Конечно, если вы внимательный и сосредоточенный гений и не ошибаетесь, вам оно может и не надо.

anonymous
()
Ответ на: комментарий от dizza

Неправильные тесты МОГУТ мешать при слепом следовании TDD. Потому что произойдет подмена цели - вместо разработки архитектуры под задачу начнется разработка архитектуры под прохождение тестов.

Тесты нужны, просто не надо их ставить во главу угла, как регулярно пытаются сделать набигатели с хелловордов.

Vit ★★★★★
()
Ответ на: комментарий от ilammy

Звучит как «пишите любой говнокод, лишь бы позеленело

Угу, а потом встречается

в тестах:
equal(plus(2, 3), 5);
equal(plus(1, 2), 3);
equal(plus(3, 4), 7);
equal(plus(-1, 2), 1);

в коде:
int plus(int a, int b)
{
   if(a == 2 && b == 3) return 5;
   if(a == 1 && b == 1) return 3;
   if(a == 3 && b == 4) return 7;
   if(a == -1 && b == 1) return 1;
   return 0;
}

monk ★★★★★
()
Ответ на: комментарий от anonymous

Мне почему-то кажется, что самое зло от оставления прототипов в том, что из-за этого у TDD-шников порвется шаблон :)

Vit ★★★★★
()
Ответ на: комментарий от Vit

Согласен с Vit. Тесты важны, на критически важных частях, а вот писать на каждый чих по тесту - имхо бред.

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

pulo
()
Ответ на: комментарий от Vit

А теперь я попробую перечислить несколько преимуществ TDD, которые я испытал на себе.

  • TDD дает больше уверенности в работоспособности нового кода.
  • TDD дает больше смелости при рефакторинге и исправлении косяков. Если мне что-то не понравилось в модуле, в который я заглянул, то я просто его правлю, а не оставляю по принципу «работает - не трогай».
  • TDD положительно сказывается на архитектуре, в частности на на уменьшение связанности и увеличении связности.
  • TDD снижает плотность дефектов. Это видно и по моей личной статистике, и по исследованиям от IBM, MS, Symantic и пр.(когда только присматривался к TDD, попадались ссылки)
  • Наборы тестов фактически представляют собой документацию по программному коду, причем всегд актуальную.

Но естественно, TDD не панацея от всех бед. Просто удобная методика.

anonymous
()
Ответ на: комментарий от anonymous

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

Нюанс в том, где поставить начало. Потому как при любой разработке есть код. Затем его начинают тестировать. Затем один из тестов не проходит, а значит «пишите тест, который не проходит, а потом код, который заставляет тест проходить»

monk ★★★★★
()
Ответ на: комментарий от anonymous

Вы правда считаете, что в этом виновато TDD?=)

Да. Это буквальное решение по принципу «обеспечить прохождение всех тестов» и «код пишется только в том объеме, который достаточен для прохождения теста».

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

monk ★★★★★
()
Ответ на: комментарий от Vit

Я прототипы писал на выброс еще тогда, когда TDD не было. Так кто вас научил черновики втюхивать?

anonymous
()
Ответ на: комментарий от monk

Если вы используете TDD с самого начала, то кода у вас нет. Вы начинаете с теста.

anonymous
()
Ответ на: комментарий от anonymous

http://ru.wikipedia.org/wiki/Прототипирование_программного_обеспечения

man эволюционное прототипирование

Телефона тренера успеха и сертификата о прохождении курса предъявить, к сожалению, не смогу.

Vit ★★★★★
()
Ответ на: комментарий от anonymous

Выше был код про функцию: int plus(int a, int b); все написано по TDD, хоть и криво. Доходите до реального использования функции plus и понимаете, что интерфейс должен быть: int plus(int a, int b, int c);

начинаете править plus и функции тестирования, вносите ошибки и туда и сюда%)

Или вы с 0 пишите интерфейсы такими какие они должны быть? нет - значит все ваши тесты на начальном этапе лишний оверхед.

pulo
()
Ответ на: комментарий от monk

Да.

Тогда поясните, что мешает писать такой код без TDD?

Это буквальное решение по принципу «обеспечить прохождение всех тестов» и «код пишется только в том объеме, который достаточен для прохождения теста».

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

И поэтому в нормальных конторах тестировщик и программист — два разных человека.

Естественно. У меня тоже так. Это ортоганально с TDD. Они в основном занимаются приемочными тестами и отслеживанием качества на бою.

anonymous
()
Ответ на: комментарий от anonymous

Так в чем вы видите проблему при использовании TDD?

Да, в общем, ни в чем. Просто надо понимать границы применимости метода. Да и метод ли это...

tailgunner ★★★★★
()
Ответ на: комментарий от Vit

Сорри, я вас не так понял=) Спасибо за пояснения.

anonymous
()
Ответ на: комментарий от pulo

Конечно, если вы так ошиблись, то надо переделать и тесты. Но это происходит не так часто, как кажется. Более того, часто как раз при написании теста ты понимаешь, каким должно быть API - ведь тест - это тоже пример использования. Лишнего оверхеда на практике нет.

anonymous
()
Ответ на: комментарий от pulo

Выше был код про функцию: int plus(int a, int b); все написано по TDD, хоть и криво. Доходите до реального использования функции plus и понимаете, что интерфейс должен быть: int plus(int a, int b, int c);

Ты же упоротый тролль. TDD поздразумевает ориентирование на _реальное_ использование: тесты должны быть образцами реального применения API. Такой ситуации, как описываешь ты, при использовании TDD никогда не возникнет.

schizoid ★★★
() автор топика
Ответ на: комментарий от anonymous

Поясню. Кода действительно больше. Но по факту задачи решаются примерно за то же время. Кроме того, багов явно становится меньше.

anonymous
()
Ответ на: комментарий от anonymous

Я только за. Речь шла не о косяках TDD, а о наивных попытках подогнать под него весь мир.

Vit ★★★★★
()
Ответ на: комментарий от anonymous

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

Что то простое тестами можно отловить, взаимодействие потоков? взаимодействие с внешним миром? а если вы используете прерывания, как такое эмулировать в тестах?

pulo
()
Ответ на: комментарий от pulo

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

Сокеты уже оттестированы до тебя. Тестируй свой протокол. Это он должен отлавливать неполные сообщения.

schizoid ★★★
() автор топика
Ответ на: комментарий от anonymous

Тогда поясните, что мешает писать такой код без TDD?

Факт, что тесты, которые будут прогоняться заранее неизвестны.

От таких людей спасут только грамотные собеседования и безжалостные увольнения.

Тем не менее. Бывают краевые случаи. Причём бывают редкие краевые случаи. Например, simcity.exe от какого-то старого SimCity не запускается в WinXP. Что делают программисты из MS. Пишут «if (cmd == „simcity.exe“) ....» и там описывают режим совместимости. Потому как вероятность того, что завтр появится ещё одна настолько же глючная (и так же глючная) программа невелика. В бизнес-процессах сплошь и рядом вместо заведения новой роли стоит «if (user == „Director“) ... ». А потом через полгода выясняется, что такие же права надо дать заму, пишется полтысячи тестов на зама, но добавить условие в полтысячи мест (тем более что сам только что написал эти тесты, значит места уже нашёл) проще, чем создавать ролевую систему прав.

Поэтому единственный метод с этим бороться: даёшь программисту ТЗ и задачу «сделать так, чтобы ТЗ соответствовало». а потом специально обученный человек будет всеми силами стремиться найти комбинацию факторов, при которых программа работает неверно.

monk ★★★★★
()
Ответ на: комментарий от pulo

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

Тестировать на получение информации. Заодно отделите работу с сокетами и логику обработки. Пусть класс работает с данными.

взаимодействие потоков

взаимодействие с внешним миром?

Что конкретно имеется в виду?

а если вы используете прерывания, как такое эмулировать в тестах?

Зачем его эмулировать? Тестируете логику обработки.

anonymous
()
Ответ на: комментарий от anonymous

Годный анонимус, все правильно сказал. Полностью поддерживаю.

unfo ★★★★★
()
Ответ на: комментарий от anonymous

Хорошо, давайте конкретно.

Есть модуль который получает значения с утройства по определенному протоколу, обрабатывает и отсылает результат, ему в зависимости от результата приходят другие данные. Отделили логику обработки от получения данных. Для тестирования необходимо самому написать класс получения данных, правильно? Получаем здоровенный класс который генерит данные как от реальной железки в зависимости от возвращенных данных нашего модуля. Класс тестирования думаю по размерам будет в разы больше нашего модуля, поэтому думаю тут придется писать тесты на класс тестирования.

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

pulo
()
Ответ на: комментарий от monk

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

Чушь собачья

anonymous
()
Ответ на: комментарий от ioway

Конечно неправильное. Бизнес-аналитика с методами написания кода не связана вообще никак. Как и тестирование (которое qa)

anonymous
()
Ответ на: комментарий от anonymous

Нет, быдлокодер - ты. Я свой код формально доказываю, а ты пишешь убогие и ненужные говнотесты. Мой код работает, сразу, всегда. Твой быдлокод валится на первой же нештатной ситуации.

anonymous
()
Ответ на: комментарий от anonymous

Свой не дам, у нас закрытый proof assistant. Но то, что мы делаем, сильно похоже на CompCert, так что смотри туда.

anonymous
()
Ответ на: комментарий от pulo

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

Тут 3 задачи(как минимум)

  • Получение данных с устройства по определенному протоколу
  • Обработка данных
  • Отсылка результата(куда?) и обработка ответа(или вы имели в виду те же данные, что и в первом пункте).

Так что модулей тут явно не один. Модуль оброботки знать о протоколе, всяких передачах, устройствах и пр. не должен. Как его тестировать, думаю, понятно. А на нем лежит основная функциональность.

Далее. Протокол. Протоколы тестируются по разбору данных(т.е. без привязки к транспорту, ибо мы в своих тестах полагаемся на то, что нижележащий уровень работает правильно - это вообще общий инженерный принцип разработки качественных систем).

На счет отсылки данных и обработки ответа - я не до конца вас понял.

anonymous
()
Ответ на: комментарий от anonymous

Тогда снимаю шляпу. Если это правда, то я действительно быдлокодер по сравнению с вами.

anonymous
()
Ответ на: комментарий от anonymous

А я вас понял, спасибо за пояснения, думаю почитаю подробней о TDD для полного осознания нужно оно мне или нет.

pulo
()
Ответ на: комментарий от Vit

Неправильные тесты МОГУТ мешать при слепом следовании TDD.

Согласен.

dizza ★★★★★
()
Ответ на: комментарий от monk

Угу, а потом встречается

Красный-зелёный-рефакторинг.

В приведённом коде отсутствует напрочь стадия «рефакторинг». В этом примере проблема не в методике разработки, а в ДНК автора кода.

TDD просто позволяет приблизить покрытие тестами к ста процентам, но если начитаются изменения в требованиях к программе (например, после очередной итерации и демки клиент решает «немного» поменять API), то тут начинается ад - юнит-тесты начинают реально мешать переделкам, вне зависимости от методик разработки.

P.S. BDD рулит. Причём как Behavior-Driven Development, так и Beer-Driven Development.

Slavaz ★★★★★
()
Ответ на: комментарий от Slavaz

В приведённом коде отсутствует напрочь стадия «рефакторинг»

Так вот я как раз про то, что TDD даёт постановку цели, которая нормальному рефакторингу мешает. Если цель «написать корректную, расширяемую, красивую программу», то стремишься на каждом шаге её улучшать, иногда ради красоты и целостности переделывая всё заново (включая API). А если цель «пройти тесты», то интуитивно будешь писать именно как ответ на непройденный тест, а нормально рефакторить, только окогда на код уже страшно смотреть.

У меня такое «TDD» случается когда сроки ставят нереальные. Тогда делается прототип, прогоняется тестами на основные use-case, где тесты не прошли, ставится минимальная заглушка «чтоб работало и не сильно глючило» и в таком виде сдаётся, а уже потом в более спокойной обстановке приводится к нормальному виду (как правило с почти полным переписыванием).

monk ★★★★★
()
Ответ на: комментарий от anonymous

сильно похоже на CompCert

Прикольно, спасибо. Здорово было узнать что они еще живы и развиваются.

у нас закрытый proof assistant

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

anonymous
()

Если бы Бог, создавая этот мир, применял TDD, то в нём не было бы разработчиков, применяющих TDD. Ибо сказал Он: «Да будет свет!», а «Да будут разработчики, применяющие TDD» - Он не говорил!

anonymous
()
Ответ на: комментарий от anonymous

Ты не знаешь, что Он говорил, кроме того, что Он открыл тебе. Тебе, как клиенту и/или части системы, все равно, использовал он TDD или нет. Впрочем, Ему тесты не нужны, Он не ошибается.

anonymous
()
Ответ на: комментарий от monk

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

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

dizza ★★★★★
()
Ответ на: комментарий от monk

когда сроки ставят нереальные.

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

dizza ★★★★★
()

Кстати да, вот стопудовый кейс, когда TDD не прокатит: дерьмовый менеджмент. Тут вообще никакие практики не катят, только говнокод, только хардкор.

dizza ★★★★★
()
Ответ на: комментарий от anonymous

Область та же - компилятор, ассемблер и линкер. Ну и сама целевая железка тоже формально верифицируется (но и тестов конечно же тоже хватает).

anonymous
()
Ответ на: комментарий от dizza

Тесты - они не мешают, они как раз дают гарантию, что старый API не сломан.

Вот это я и имел в виду. При разработке реализуется функция f(a,b) после написания 60% кода выясняется, что на самом деле должно быть f(a, b, c) (например, добавили контроль доступа). И в этот момент при использовании TDD возникает очень сильное желание прикрутить любой костыль, чтобы не ломать тесты. Например, сделать f2(a, b, c) скопипастив в неё 90% кода из f. Тогда старые тесты не ломаются. Но в коде остаётся неиспользуемая функция

monk ★★★★★
()
Ответ на: комментарий от dizza

Тесты - они не мешают, они как раз дают гарантию, что старый API не сломан.

Stable API is nonsense. Если на него жёстко завязываться, то невозможно почти никакое развитие.

И зачем иметь гарантию фиксированного API до релиза?

monk ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.