К основному контенту

"А вы не любите TDD, как не люблю его я?"

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

"TDD есть опиум для народа"

На данный момент, это самый аргументированный и подробный ответ апологетам TDD (из известных мне на русском языке).

Хотите узнать продолжение истории и проникнуться ответами другой стороны - подписывайтесь на дискуссию на страничке "Radio QA"

И как мне теперь с ним на работе общаться? Опасный человек оказывается :)

Да, кстати, подписывайтесь на блог Владимира, он классно пишет. Надо его мотивировать писать чаще :)


Комментарии

  1. Честно говоря, больше похоже на софистику в стиле:

    > Мне тут сказали, что программисты на Западе хорошо зарабатывают, так я сел в машину, поехал на запад и попал в Погорелое Городище - а там для программистов вообще работы нет. Значит, врут всё про работу на Западе! Опиум для народа, понимаешь ли...

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

    ОтветитьУдалить
  2. Интересный комментарий.Я воспринимаю статью (и не только эту, а вообще все что читаю) не как руководство к действию (или набор отмазок для руководства, или бальзам на свои больные места), а как набор аргументов, с которыми часто приходится сталкиваться. Просто тут они удобно собраны в одном месте, что дает возможность попробовать так же аргументированно на них ответить. Я со многим согласен, но вообще скорее получается "it depends on" - у каждого свои проблемы, и нет одного общего инструмента (silver bullet), который все это может решить. Ну и голова с тараканами у каждого своя.

    ОтветитьУдалить
  3. Да простите, фразе про "никогда переписывать не придется" не хватает слова "почти". Я же не взял этот аргумент с потолка, вполне типичный диалог происходит в стиле:
    - В моей практике код часто пишется итерационно, постепенно наращивается мясо, переписываются функции\классы, и если так писать используя TDD, то тесты очень часто ломаются не по делу
    - Вы не правы, ибо TDD помогает рано выявить нюансы, сформировать архитектуру и следовательно в коде будет МИНИМУМ переделок.

    ОтветитьУдалить
  4. Странные у Вас собеседники, конечно. Число переделок кода, на мой взгляд, никак не следует из наличия/отсутствия тестов. Более того, лично я вижу ситуацию ровно наоборот: если код "одноразовый", не предназначенный для изменения (и не слишком сложный), то его можно написать и без автотестов, тупо проверив все варианты работы один раз руками. Если же планируется код развивать и модифицировать, то я напрягусь и поскриплю извилинами, но всё же постараюсь создать для него тестовый сьют - именно потому, что юнит-тесты, как показывает мой опыт, позволяют проще и без большой боли менять код. Именно менять. Итерационно, шаг за шагом.

    Если же у Вас тесты "часто ломаются не по делу", то я вижу два (наиболее возможных) варианта, почему это происходит:


    * Либо в Вашем коде (или тестах) присутствуют паттерны, мешающие удобному тестированию (их много; помочь может каталог Мессароша http://www.ozon.ru/context/detail/id/4127815/, к примеру)

    * Либо Вы меняете сначала код, а потом тесты - но простите, это тогда уже не TDD! И обвинять TDD в Ваших болях уже несколько неэтично.

    ОтветитьУдалить
  5. Написал ответ, а он куда-то пропал :( Ох уж этот Disqus...

    Попробую повторить: мне удивительно, почему апологеты TDD, с которыми Вы спорите, утверждают, будто бы в коде будет минимум переделок при использовании этой техники. Мой опыт говорит, что число переделок редко бывает связано с тем, как именно разрабатывается тот или иной продукт. Более того, для меня связь чаще строится в обратную сторону: если заранее известно, что софтина не будет сильно развиваться, или если она очень простая, то я могу позволить себе не писать для неё тестов. Но если я создаю какой-то софт, который планируется итеративно развивать и дополнять, то лучше дополнительно поднапрягусь и поломаю голову, но создам для него тестовый сьют, который позволит мне развивать его через TDD. Именно потому, что методика разработка через тесты при правильном применении позволяет развивать приложение итеративно.

    В Вашем же случае стоит внимательней посмотреть на причину, из-за которой "тесты очень часто ломаются не по делу". Чаще всего это происходит по одной из двух причин:

    * Либо в коде много "запахов", которые мешают лёгкому тестированию (высокая связность кода, неявные зависимости, смесь высокоуровневой логики с низкоуровневыми деталями реализации и т.п.). С каждым из таких запахов можно разобраться, но без конкретных примеров я мало что могу посоветовать - по фотографии диагноз не ставлю :)

    * Либо Вы меняете тесты только после изменений в коде. Конечно, это может сломать тесты, но в таком случае некорректно утверждать, что применяемый Вами метод называется TDD (и, соответственно, обвинять его в том, что Ваши тесты ломаются).

    В любом случае, я бы посоветовал Вам поглядеть книгу "Шаблоны тестирования xUnit" Месароша http://www.ozon.ru/context/detail/id/4127815/. Довольно долго она была моей настольной книгой при работе с тестами и позволила понять многое из того, что было далеко не очевидно, когда я только начинал осваивать TDD.

    ОтветитьУдалить
  6. Андрей, сори, мой косяк. Сообщение с линком - модерация требовалась. Пусть будет 2 теперь :)

    ОтветитьУдалить
  7. Все про что Вы говорите - верно. И книжка правильная ;) Но жизнь чаще сложнее.
    Я, в последнее время, больше склоняюсь к тестам более высокого уровня, не юнит. Их тоже можно писать "до кода", но с ними проще его модифицировать. Может чуть подробнее на эту тему я писал здесь http://www.maxshulga.ru/2015/04/self-edu-3.html

    ОтветитьУдалить
  8. Эххх, надеялся на ответ Владимира, но что-то не дождался. Интересно было, из-за чего всё же падают его тесты :)

    ОтветитьУдалить
  9. Он там в своем блоге с Солнцевым баталится :) Там вернее дождаться ответа :)
    Но я могу попробовать ответить за него (как я себе это представляю). Скорее всего под его "ломаются" имеется ввиду, что их просто приходится переписывать, если меняется код (причем уже даже не важно в каком порядке). Все логично и ожидаемо: меняется код, меняются (= выбрасываются) тесты.
    А если мы говорим о тестах чуть выше уровнем (не юнит), то чаще всего они остаются без изменений или с минимальными изменениями.

    ОтветитьУдалить
  10. Пропустил уведомление что-то. Попробую объяснить, утрированно и с преувеличениями конечно, куда уж без этого:
    Допустим у нас есть очень хорошая, независимая, легко тестируемая функция. Примерно такого толка (она бессмысленна, просто пример):
    ...
    a = 0
    if x > 0:
    a = 1
    if y > 0:
    a+=1
    if x*y > 100:
    a*=100
    ...
    Мы использовали в ней, ну пусть, 5 if-ов, для качественного и полного покрытия юнит тестами, нужно все комбинации проверить (иначе не получится "спать спокойно") - итого, насколько я помню комбинаторику, 2^5 == 32 теста. Ну и конечно всякие особые случаи нужно проверить и т.п., но опустим. Поскольку в TDD мы тесты пишем до того, как были учтены все текущие требования, функцию мы продолжаем разрабатывать. Допустим следующим шагом мне понадобилось сделать крохотное изменение заменяю "a+=1" на "a+=2", это приведет, для подобного кода, к поломке половины (16) тестов. Одна цифра - ведет к изменению в 16!! тестах. И этот ад будет продолжаться и продолжаться. Штук 10 итераций и уже 160 переписанных тестов.
    А если принять за правило писать тесты после того как код более менее стабилизируется - у нас получится, что нам нужно написать всего навсего 32 теста 1 раз. И что характерно на выходе тоже самое - покрытая тестами функция, а если нет разницы зачем платить больше?

    ОтветитьУдалить
  11. > Поскольку в TDD мы тесты пишем до того, как были учтены все текущие требования...

    Простите, но с этим утверждением я категорически не соглашусь Писать тесты, не учитывая все текущие требования - это нелепо и ошибочно. Суть TDD именно в том, чтобы взять все текущие требования, формализовать их в примеры для кода, а затем создать код, шаг за шагом решая эти примеры. Это тоже достаточно утрированное описание, но всё же...

    Разумеется, такой подход приведёт к лишней работе и недовольству, но в чём здесь на самом деле изъян? Не в использовании TDD, а в игнорировании требований, простите.

    ОтветитьУдалить
  12. Не точно выразил мысль. Имелось ввиду, что тесты пишем до того, как в КОДЕ уже реализованы все текущие требования. Соответственно мы будем менять код, каждое изменение ведет к переписыванию тестов и далее по тексту в предыдущем комментарии...

    ОтветитьУдалить
  13. Владимир, я не понимаю: почему так получается, что требования (выраженные в тестах) остались неизменными, а логика в коде вдруг начинает меняться? ;)

    ОтветитьУдалить
  14. А вы смотрели видео, на которое я давал ссылку в начале? https://www.youtube.com/watch?v=8u6_hctdhqI&feature=youtu.be Просто объяснять долго, а на его примере хорошо видно, что с каждым новым тестом меняется старый код, причем весьма значительно

    ОтветитьУдалить

Отправить комментарий

Популярные сообщения из этого блога

Mock vs Stub

Когда мы начали изучать модульное тестирование, то одними из первых терминов, с которыми пришлось познакомиться, стали Mock и Stub. Ниже попробуем порассуждать в чем их сходство и различие, как и для чего они применяются. Проверять работоспособность тестируемого объекта (system under test - SUT) можно двумя способами: оценивая состояние объекта или его поведение. В первом случае проверка правильности работы метода SUT заключается в оценке состояния самого SUT, а также взаимодействующих объектов, после вызова этого метода. Во-втором, мы проверяем набор и порядок действий (вызовов методов взаимодействующих объектов, других методов SUT), которое должен совершить метод SUT. Собственно, если коротко, то в одном случае используется Stub, а в другом Mock. Это объекты, которые создаются и используются взамен реальных объектов, с которым взаимодействует SUT в процессе своей работы. Теперь подробнее. Gerard Meszaros использует термин Test Double (дублер), как обозначение для объе

Заметки на коленке - 3. Что еще делать, если ваши тесты уже "зеленые"?

"Lately I find I'm working on automated tests that return non-binary results. Tests that neither pass nor fail" by  @noahsussman Отличная мысль, которую я ретвитил еще в 2016. Но давайте вместе подумаем, что за этим может скрываться? ( кстати, не знаю, что при этом думал Noah ) Ваши тесты прошли и прошли "успешно". Все хорошо или все же есть, куда еще посмотреть? Дальше то, что использовал я лично и то, что еще можно прикрутить дополнительно. Естественно все шаги ниже должны быть автоматизированны. 1. Контролируйте время выполнения тестов. Если набор проверок не меняется (а такое часто бывает, к сожалению), то рост времени выполнения может говорить о проблемах в продакшен коде (чаще всего) или проблемах с окружением. 2. Контроль за количеством выполняемых тестов. "Все зеленое" не значит, что сегодня выполняли те же Х тестов, что и вчера. Смешно(нет), но случается такое, что какие-то проверки "исчезают" из запуска из-за того, что у кого-то &qu

Полезные ресурсы для молодых (и не только) тестировщиков

сперто(с) Уже 3 месяца провожу собеседования тестировщиков (март 2016). Поначалу они просто  веселили - после 15-летнего опыта собеседования С++-разработчиков, общение с тестировщиками (чаще были "-цы") было чем-то экзотическим и забавным. Потом становилось все грустнее и грустнее, мимими закончилось. Началась печаль.