LINUX.ORG.RU

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

 


0

3

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

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

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

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

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

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

Почему? В смысле это сознательный отказ или просто не задумывались?

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

пишу и TDD пишу при надобности таковой, но просвещать тебя не буду, дабы не заражать кошмарностью мышления

Deleted
()

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

Я несколько компонентов так писал. Для пишущихся с нуля автномных модулей достаточно удобно выходит. Но для моей практической работы подходит мало, так как специфика несколько отличается.

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

100 страниц? o_O Мне как-то хватило пары небольших обзоров на Хабре :)

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

Прошу не троллинга же ради, а для вразумления собственного. Я серьезно. Может я что-то не так делаю...

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

Модульные тесты можно начинать писать, когда API уже более менее вырисовывается

Не обязательно, итеративная процедура там нормально вписывается. Пишешь сперва совсем грубые тесты и основные элементы API, потом — уточняешь. Заодно, если при проработке API что-то в совместимости поломал, тест сразу покажет.

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

А как вообще принято проверять сложные запросы?

Вот потому я и люблю ORM. Запросы оказываются за кадром и тестируются отдельно.

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

принято проверять сложные запросы?

Так же как любые объемные данные. Условия до и после вызова (иногда и в рабочем коде). Тестируется, соответственно, на рабочих данных.

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

Тестируется, соответственно, на рабочих данных.

Кхм. Вот уж чего я точно не стану делать — гонять потенциально разрушающие тесты на рабочих данных. Что мешает сделать срез копии рабочей БД перед тестами?

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

Тестируется, соответственно, на рабочих данных.

Надеюсь, «рабочие данные» <> «продакшон база».

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

Условия до и после вызова

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

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

Что мешает сделать срез копии рабочей БД перед тестами

Бэкап делается. Откатить при необходимости можно и одну таблицу, если что. А если пост-условие не выполнится, так транзакция автоматически откатится.

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

Допустим есть развесистый селект на пару экранов.

Живой пример из 1С. Есть запрос на 2800 строк. Считает НДФЛ по предприятию в разрезе людей и месяцев. Есть контроль: итоговая база с начала года, умноженная на процент должна совпадать с суммой, рассчитанной этим огромным запросом.

Заранее посчитанные результаты не помогают, потому что например в этом примере, ошибки округления начинают проявляться при количестве сотрудников более 100. Фактически, нормальный тестовый пример должен содержать несколько иностранцев, несколько договорников, несколько людей получивших материальную помощь, несколько уволенных, у кого-то должен быть вычет за квартиру и должны быть непустые начисленные данные по одному из предыдущих периодов текущего года. Но для таких тестовых данных я вручную ожидаемый результат буду полдня считать.

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

И TDD позволит тебе сразу увидеть фейл в нем.

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

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

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

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

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

Помогут. Они дают тестовые примеры, на которых запрос работает неверно. А вручную я тесты могу до посинения придумывать, всё равно все примеры не охвачу.

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

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

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

Ты 1С «программист»?

Я просто программист. И 1С и C++ и Lisp. Просто задачи для 1C труднее всего уложить в TDD, потому как половина кода событийно-управляемый интерфейс. Вроде как тестировать надо последовательность событий, но этот процесс невозможно автоматизировать. А вторая половина кода — запросы SQL на несколько тысяч строк кода с результатом в виде таблицы, опять же на несколько тысяч строк.

На C++ и Lisp такие задачи реже встречаются. Хотя про вычислительную физику на C++ я уже упоминал. Какой тестовый пример для системы дифуров придумаешь? Пару тривиальных случаев, которые можно решить аналитически и проверки результата на корректность (например прогнав получившиеся результаты через ту же систему уравнений).

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

ты сначала пишешь, а потом думаешь над API?

Думаю над API в процессе написания. То есть черновая заготовка конечно есть, но по ходу дела она уточняется и улучшается. Так чтобы сразу все было гладко с API никогда не получается. Я не против TDD, просто научили так сначала писать код, потом тестировать, теперь сложно перестроиться.

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

О проектировании не слышал?

Обычно параллельно с проектированием создаётся прототип. Иначе можно напроектировать мертворожденное чудовище.

Соответственно нормальная последовательность разработки:

  • прототип
  • тесты
  • улучшение прототипа (иногда со сломом структуры/рефакторингом)

Пример радикального слома: пишешь библиотеку структур данных. Написав половину, понимаешь, что тип данных надо не наследовать а держать параметром, пишешь всё заново. Заранее спроектировать такое невозможно, потому как противоречия в проектировании видишь только при попытке реализации.

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

Вроде как тестировать надо последовательность событий

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

А вот вычислительная математика - это не прикладное ПО. Там есть свои, формальные методы валидации алгоритмов, скорее всего. Мутная тема..

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

Бэкап делается. Откатить при необходимости можно и одну таблицу, если что.

Это если только таблица мелкая и простой не страшен.

В любом случае странным выглядит тестирование на боевой базе. Что-то в консерватории при этом не то...

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

То есть черновая заготовка конечно есть, но по ходу дела она уточняется и улучшается.

Уточняется и улучшается, скорее всего, потому, что в реальном применении API либо находятся лишние вещи, либо не находится нужных, не так ли?

Тесты в TDD - это образцы реального применения API. Всё, что может понадобиться, уже учтено в процессе создания тестов. И изменения в API вносятся, только если изменено само техзадание. В этом самая мякотка - гораздо меньше работы.

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

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

Недостаточно. Под последовательностью я имею в виду именно нажимание кнопок пользователем.

Пример: Строка документа. Поля Количество, Сумма, Цена. «Сумма НДС», Всего. Пишешь обработчики, которые при изменении любого из полей пересчитывают остальные. Потом получаешь багрепорт: «ввели всего = 100 рублей, потом ткнули в сумму, ничего не меняли, а всего стало 100 рублей 01 копейка». Каждая функция отдельно работает верно, а в целом неверно.

Ну или из жизни «больших фирм». На win98 (или 95, не помню) была ошибка: если нажать Alt-Tab, а потом не отпуская первый Alt, нажать второй, а потом первый отпустить, то можно было получить синий экран. Тоже «последовательность событий».

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

В любом случае странным выглядит тестирование на боевой базе.

Так протестировать, чтобы дать гарантию работоспособности, всё равно невозможно. В случае 1С есть хороший ограничитель: запросом update/delete делать нельзя, а то, что пользователь делает привязано к документу. Соответственно, если что-то не так, то откатить достаточно просто. В Oracle хуже. Забыть условие при DELETE страшно. Но при наличии рабочего снапшота и триггеров, проверяющих целостность после изменений, жить можно.

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

А вот вычислительная математика - это не прикладное ПО. Там есть свои, формальные методы валидации алгоритмов.

Проблема не в алгоритме. Он давно написан и доказан. Проблема в опечатках при реализации (написал вместо плюс минус и всё) и в ошибках округления и переполнения на процессоре (их очень тяжело в доказательстве правильно учесть, потому как a/b*b != a, причём иногда сильно неравно). Поэтому корректность всё равно контролируется по результату.

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

Тесты в TDD - это образцы реального применения API. Всё, что может понадобиться, уже учтено в процессе создания тестов. И изменения в API вносятся, только если изменено само техзадание.

Теоретически всё так. Но в процессе реализации вылезают частенько нюансы, требующие переделки API, причем небольшое изменение может потянуть за собой переписывание половины тестов. Выше уже писали об этом. То есть API зависит не только от требований техзадания, но и от реализации (хотя в идеале этого не должно быть наверно), а TDD диктует полное абстрагирование от реализации на момент тестирования.

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

Тесты в TDD - это образцы реального применения API.

У меня обычно тесты = примеры использования = документация. Вот только это не TDD, а скорее модульные и интеграционные тесты.

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

Тесты в TDD - это образцы реального применения API. Всё, что может понадобиться, уже учтено в процессе создания тестов.

Если писать что-то сложнее HelloWorld'a это совсем не так. Любое сложное приложение даст тебе кучу вариантов использования твоего API, о которых ты изначально даже не подозревал. Значит тесты быдут на явные и простые сценарии. А тут разницы между TDD и просто модульным тестированием уже не особо и заметна.

Кроме того, если заниматься разработкой конечного сложного продукта, причем быть разработчиком на всех уровнях(от проектирования до внедрения), то требования к данной системе могут меняться регулярно. Совершенно нормальной является ситуация, когда ты внедряешь какую-то фичу, а после двух недель использования понимаешь, что в таком виде она бесполезна, и надо её переделать, причем переделка может быть координальной и что самое главное не факт что окончательной. Поэтому у нас на работе обычно делается работающий прототип, он внедряется во внутренний релиз, которым пользуются специально обученные люди. По их заключению фича либо оставляется, дописываются для неё тесты и вообще причесывается код, либо переделывается в соответствии с изменившимися требованими. Так происходит регулярно. Если вести разработку через TDD, ты каждый раз будешь писать тесты, которые в итоге будут не нужны.

Daeloce
()

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

Вообще ИМХО TDD применим лишь к небольшим и давольно простым с точки зрения API библиотекам. Во всех остальных случаях оно не имеет смысла.

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

TDD диктует полное абстрагирование от реализации на момент тестирования.

На момент написания тестов то есть.

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

Это был неприкрытый скептицизм. Имхо, весь восторг по поводу сабжа из-за «несколько компаний (в т.ч. довольно серьёзных)». Для лица незаинтересованного метода как метода, с легким налетом сектантства.

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

писать раза в два больше кода

«Набор кода - не есть узкое место разработки» (с) Не помню кто.

Если быть точным, то важен не объем кода, а трудозатраты. Так вот тесты - предельно тупой код, который пишется очень легко, над ним практически не нужно думать, а только писать. По моему опыту код, который пишется где-то день полностью покрывается тестами за час.

_может_ ты выиграешь на отладке и сопровождении

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

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

а рефакторинг может оказаться вдвойне неприятен

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

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

Так вот тесты - предельно тупой код,

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

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

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

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

Вот штрилриц и прокололся. Если бы ты работал по TDD, то это тесты, написанные за час, должны были бы перестать фэйлить после дня работы.

LamerOk ★★★★★
()

А зачем придумывать контраргументы к гербалайфу? Если TDD позволяет кодерам решать проблемы личностного роста, мотивации и повышать ЧСВ от называния своего кодинга проектированием - значит от методики есть смысл. Сектантами проще управлять.

Vit ★★★★★
()

Нет, ибо TDD - несусветная глупость.

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

под TDD нужна архитектура ПО позволяющая такой стиль разработки

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

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

Очень глубокомысленный анализ, что тут скажешь. Просто я хорошую архитектуру априори считаю must have, извини привык к такому уровню разработки.

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

Тесты в TDD - это образцы реального применения API. Всё, что может понадобиться, уже учтено в процессе создания тестов.

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

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

Тесты в TDD - это образцы реального применения API

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

Всё, что может понадобиться, уже учтено в процессе создания тестов.

Ещё напой, что тесты пишет клиент, ага!

И изменения в API вносятся, только если изменено само техзадание.

Ясно! Теоретик!

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

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

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

При всём уважении.

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

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

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

Нет, просто вы неосиляторы TDD и с проектированием у вас плохо...

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

Клиенты вообще ничего не могут. Просто они думают, что их проблемы решают программы. А на самом деле, их проблемы решают тесты. А программы можно вообще не писать.

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

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

Да, нужна соответствующая архитектура. И самый смак в том, что с TDD архитектуру хорошую построить легче.

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

Костность мышления во всей красе. А аргументов у вас таки нет, только самооправдание и повышение ЧСВ.

anonymous
()

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

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

Ни какая-то специальная, а просто хорошая

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

Просто я хорошую архитектуру априори считаю must have, извини привык к такому уровню разработки.

не лопни от зазнайства, после таких знатоков авгиевы конюшни кодонавоза не расчистит даже геракл от архитектуры ПО.

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

с TDD архитектуру хорошую построить легче.

ортогонально, смак это видимо звук издаваемый фанатами TDD при впечатывании в реальность

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