Юнит тесты и TDD


В очередной раз Joel Spolsky, автор отличных книг из серии Joel on Softwareи одноименного блога JoelOnSoftware, написал потрясающую статью. В этот раз он рассуждает про Test Driven development и, как обычно, делает это без всякого уважения к авторитетам и современным тенденциям.
Должен признаться, что моё отношение к TDD в точности совпадает с тем, что он описал в этой статье. И это радует и успокаивает.
Попробую в этой статье раскрыть мое отношение к юнит тестам и TDD.

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


1. Пишем тест(ы)
2. Если тесты не сработали - пишем код. Нельзя писать код, если все тесты срабатывают.
3. Удаляем дублирование (рефакторинг). После каждого небольшого изменения билдим код и проверяем, что тесты срабатывают.
Переходим к пункту 1.

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

100% покрытие кода юнит тестами

Итак, поводом для статьи Джоеля стали письма от людей, которые призывали его добавить 13-ый пункт в его знаменитые 12 шагов, чтобы писать код лучше. Его призывали добавить пункт Юнит тесты, 100% вашего кода покрыто юнит тестами.
И ведь это сейчас практически индустриальный стандарт - почти все профессиональные книгипишут про то, что вы должны иметь 100% покрытие кода тестами, что писать новый код можно только используя TDD. Что если вы этого не делаете, то обречены вечно создавать дорогие, некачественные и плохо расширяемые программы. Консультанты твердят то же самое. И только разработчики чувствуют себя ущербными, так как НЕ МОГУТ сделать 100% покрытие кода тестами. Они читают книги про TDD, слушают консультантов, тратят время, но 100% покрытия достичь все равно не могут. Вы, например, можете?


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


Еще, что идеологи TDD не указывают обычно - это то, что, если вы имеете 100% покрытие кода тестами, то изменение любого куска кода требует изменения и всех тестов для него. И изменение тестов со временем будет занимать все больше и больше времени. То есть, юнит тесты становятся со временем теми самыми кандалами, которые МЕШАЮТ вам делать рефакторинг или небольшие изменения - ведь для самого простого изменения интерфейса класса или функции вам придется изменить не только клиентов класса или функции, но и все тесты, которых может быть гораздо больше, чем клиентов (мест использования).


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

Почему же так происходит и что делать?

Авторы, пишущие книги по теории программирования и консультанты - это обычно не те люди, которые много занимаются программированием. Они зарабатывают на другом и их можно назвать теоретиками. Даже если у них был когда-то большой опыт программирования, то сейчас они пишут только небольшие тестовые программки, чтобы проверить свои теории и доказать их работоспособность. Но все мы знаем, как огромная разница между программой на 100 строк и на 1 000 000 строк. И экстраполировать на большие проекты методологии, прекрасно работающие на маленьких проектах - это нелепо. Но это то, чем сейчас занимаются все Agile и TDD консультанты и авторы книг.
Они экстраполируют. Они утверждают, что есть огромные проекты, покрытые на 100% юнит тестами, но видел ли кто-нибудь когда-нибудь такие проекты? Я - нет. Зато я видел множество других проектов, где встречались юнит тесты, но процент был далек от 100. Обычно он 0-5%. Причем 5% - это уже очень много и, уверен, достаточно для большинства проектов. Никто из разработчиков не хочет тратить месяцы и годы для покрытия тестами кода, который работает стабильно, уже 5-10 лет не менялся и еще 10 лет не будет меняться. Но руководство нанимает консультантов и те убеждают, то без 100% покрытия тестами невозможно повысить качество продукта. Ставится такая задача, все работают в поте лица, а качество программы падает каждый день.


Почему?


Во-первых написание тестов для legacy кода вносит в него ошибки. От этого не уйти - приходится изменять код, а значит добавлять в него баги.


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


И это нам позволяет сделать главный вывод: 100% покрытие юнит тестами вредно. Даже так: сама идея о 100% покрытии тестами вредна! Покрывать надо только те куски кода, которые будут меняться, причём несерьезно, так как при серьезных изменениях придется переделывать и все тесты, а значит старые станут бесполезной обузой.
А много ли кода, подпадающего под это определение обычно в программе? Это и есть те самые 5-10%. Так что обычно достаточно покрыть тестами 5-10% кода для получения всех преимуществ юнит тестов. Если юнит тестов становится больше, то они перестают приносить пользу, но увеличивают расходы на поддержание их работоспособности.


Например, Michael Feathers в своей книге Working Effectively with Legacy Codeне призывает покрывать все 100% кода тестами. Мало того, он даже не призывает всегда покрывать тестами код, который вы собираетесь изменять. Он призывает думать. Каждый раз делать осознанный выбор - нужны ли вам в данном месте юнит тесты или нет. Всем советую купить и прочитать эту его книгу. Эта книга - лучшее описание теории и практики написания юнит тестов, что я встречал. Причем именно с точки зрения практики - большая часть книги посвящена описанию стандартных приемов работы со старым кодом. А сам автор имеет огромный практический опыт по улучшению legacy кода.

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

 Понравилась статья? Подпишись на RSS!

107 комментариев к Юнит тесты и TDD

  • gineer

    Это называется эффект объевшегося шоколадом. (сам только что придумал ;) )

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

    Идея о 100% покрытии юнит-тестами — на самом деле действительно булшет.
    Потому что юнит тест пишется не для качества кода, и не для рефакторинга (хотя в куче с ним работают отлично). А прежде всего для тестирования своего понимания.

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

    А иакой вопрос. Вы слушаете подкасты? Потому как указанная ссылка — это “распечатка” подкаста. ;)

  • Качество кода зависит от многих факоров.. TDD у нас практикует ровно 1 человек :) Я не за и не против - не возникало реальной потребности. Лично у меня такой подход:

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

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

    TDD для меня - это все-таки способ убедится, что исправляя - ничего не сломали. Это, в первую очередь, способ для заказчика контролировать качество - TDD дает ему хоть какую-то иллюзию контроля :)

    • У вас заказчик разбирается в разработке и знает, что такое TDD? :)


      Лично у меня такой подход:

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

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

      А как можно проверить a)? Тестируешь исполнение всех возможных веток кода? Имхо, нереально. А если еще добавить сюда треды, то вообще невозможно все полностью проверить самому.
      Тут TDD как раз бы помог, но писать тесты для проверки всех веток, всех исключений, хэндлов и других ресурсов - жуть :)

      И про б) тоже интересно было бы почитать. Как определить возможные ошибки на раннем этапе? Составляешь какой-то список с возможными ошибками перед началом работы или как?

  • >>У вас заказчик разбирается в разработке и знает, что такое TDD?

    Нет, мы как раз сами себе заказчик :)

    >>А как можно проверить a)?

    Это надо не совсем проверять, так надо писать сразу. Если в голове держишь все ресурсы - сильно помогает :)
    А если серьезно - освобождать, то что выделил, в случае ошибки. Это вряд ли сложно, так ведь?

    >>Составляешь какой-то список с возможными ошибками перед началом работы или как?

    составляю, но не только. Пишу каждую строчку и думаю что делать если это сработает или если не сработает. Обработку ошибок максимально обобщаю, а код ошибки делаю индивидуальный для каждой ошибки.

    • Понятно.
      Но этот подход работает только до определенного масштаба. Как только подключается еще один программист или появляется нужда дописывать или исправлять чей-то чужой старый код - это уже не сработает.
      Программист не сможет думать, как ты, а ты не сможешь осознать всей глубины мысли того, кто писал этот код 10-ти летней давности. И полезут ошибки из-за недопонимания.
      Юнит-тесты тут бы помогли, но опять же до определенного масштаба. Пролезать через дебри юнит-тестов десятилетней давности - что может быть хуже? :)

  • ага, я как раз и говорю - потребности не возникало.
    А вопрос с масштабом решается делением на отдельные логически законченные бинарники.
    Не во всех же задачах обязательно дописывать код 10-ти летней давности ;-)

  • Неубедительно. То, что вы взяли основную идею(и часть текста :)) у Спольского еще не означает, что вы правы(как и он). Теперь, давайте по пунктам.
    1. [Юнит тесты не имеют ничего общего с качеством]
    а) А обычное тестирование повышает качество?
    б) Может, компиляция и статические проверки тоже не повышают качество?
    2. [Юнит тесты - кандалы]
    а) Приватные члены классов - тоже кандалы. Можно их все делать public и не будет проблем. Также можно не следовать ООП методологии, не реюзать код. Это ведь будет быстрее на начальном этапе
    3. [Покрытие юнит-тестами 100% - НЕВОЗМОЖНО]
    а) Вы утверждаете, что не видели больших таких проектов. Какие объемы для вас кажутся большими? Просто я видел достаточно большие проекты, весь внутренний код в которых был покрыт на 100%. Да и вообще, аргумент “Я не видел такого” даже неприлично использовать в цивилизованной дискуссии
    4. [Достаточно покрыть тестами 5-10% кода для получения всех преимуществ юнит тестов]
    а) Это утверждение аналогично утверждению, что для того, чтобы обеспечить 100% качество продукта достаточно протестировать его по 5-10% тесткейсов, которые мы выделим как основные. Естественно, вы можете получить качественный продукт, также как и 5-10% процентное покрытие обеспечит вам некоторые преимущества, однако абсолютного результата вам не достичь.


    • 1. [Юнит тесты не имеют ничего общего с качеством]
      а) А обычное тестирование повышает качество?
      б) Может, компиляция и статические проверки тоже не повышают качество?

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


      2. [Юнит тесты - кандалы]
      а) Приватные члены классов - тоже кандалы. Можно их все делать public и не будет проблем. Также можно не следовать ООП методологии, не реюзать код. Это ведь будет быстрее на начальном этапе

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


      3. [Покрытие юнит-тестами 100% - НЕВОЗМОЖНО]
      а) Вы утверждаете, что не видели больших таких проектов. Какие объемы для вас кажутся большими? Просто я видел достаточно большие проекты, весь внутренний код в которых был покрыт на 100%.

      Хорошо, большой - хотя бы 200К строк кода. Вы такие видели со 100% покрытием? Можете назвать? Действительно интересно.


      Да и вообще, аргумент “Я не видел такого” даже неприлично использовать в цивилизованной дискуссии

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


      4. [Достаточно покрыть тестами 5-10% кода для получения всех преимуществ юнит тестов]
      а) Это утверждение аналогично утверждению, что для того, чтобы обеспечить 100% качество продукта достаточно протестировать его по 5-10% тесткейсов, которые мы выделим как основные. Естественно, вы можете получить качественный продукт, также как и 5-10% процентное покрытие обеспечит вам некоторые преимущества, однако абсолютного результата вам не достичь.

      Опять же, вы тут смешиваете понятия. 5% тест кейсов и 5% кода, покрытого юнит тестами - это разные вещи.
      Подумайте, сколько функциональности в программе обычно покрыто тесткейзами? Больше 5%? Утверждаю, что меньше!
      Никому и в голову не придет проверять самые базовые тесткейзы типа, “передвинуть иконку на рабочем столе и попробовать запустить приложение” или “в каждый элемент интерфейса попробовать вбить -1, 0, 1, 9999, 32768 и 0xFFFFFFFF и проверить работоспособность”. Тесткейзы всегда проверяют только часть функциональности, которая МОЖЕТ сломаться или работать неправильно. Но не базовые вещи.
      А юнит тесты почему-то должны покрывать все 100%! Почему?
      Почему недостаточно покрыть юнит тестами только самые важные и “глючные” места, но не все подряд типа гуи?

  • Вот Вам и первые баги…Возможно, этот пост обрежется вновь. В этом случае отложу публикацию его на неопределенный срок :)
    1. Так вот, точно также, как и обыкновенное тестирование и статические проверки, юнит-тестирование - шаг на пути к повышению качества, только более основательный. Т.о., ваше высказывание про то, что юнит-тесты не имеют ничего общего с качеством - ложно.
    2. Тесты - такие же кандалы, как и выделение публичных интерфейсов. Т.е., вам нужно менять тесты только в случае если вы поменяли интерфейс.
    3. Вы меряете размеры проектов по количеству строк кода? :D

    Для Вас, возможно, основную роль и играет личный опыт. Но когда Вы выносите свои мысли на суд общественности - тогда стоит и более мудрые аргументы изобрести, а не уподобляться доисторическим людям, которые верили, что Земля плоская исходя из собственного опыта.
    4.
    а) По поводу того, сколько функциональности нужно покрывать тесткейсами - отдельный разговор.
    б) Приведенные вами примеры и в юнит-тесты то не запишешь
    в) GUI покрывать unit-тестами и не надо, потому что в GUI нет логики, а тестировать надо логику. GUI можно накрыть автоматическим тестированием
    г) От того, находится ли баг внутри важного места или он вызван маленькой опечаткой в каком-нибудь маленьком методе, важность бага не меняется. Естественно, для существующего кода имеет смысл начинать покрывать код с самых основных функций, на которых завязаны все остальные. Но для того, чтобы получить максимальный результат, нужно приложить и максимум усилий(и не волнуйтесь, всякая мелочь в итоге покроется автоматически).

    • Xor

      Извините, что влезаю, стало интересно
      >3. Вы меряете размеры проектов по количеству строк кода? :D<

      А что, количество строк кода не имеет значения? Мне всегда казалось, что подходы к проектированию/реализации меняются, в зависимости от размера проекта. В том числе и методы проверки качества проекта.
      По крайней мере (насколько я знаю) подходы значительно меняются в других областях человеческой деятельности, к примеру в большинстве видов инженерных работ.

    • 1. Так вот, точно также, как и обыкновенное тестирование и статические проверки, юнит-тестирование - шаг на пути к повышению качества, только более основательный. Т.о., ваше высказывание про то, что юнит-тесты не имеют ничего общего с качеством - ложно.

      Цитата:
      Юнит тесты не имеют ничего общего с качеством - это просто инструмент, позволяющий проверить, что вы не сломали ничего из прошлой функциональности.

      Это инструмент! Да, любой инструмент помогает повышать качество. У Макконнела в его книге была даже таблица по процентному уменьшению числа багов при внедрении разных методологий и инструментов - рекоммендую.
      Мой пойнт в том, что то, что вы скажете “мы используем TDD” или “100% кода покрыто тестами” - это ничего не говорит о качестве вашего кода.
      Это как плотник скажет: “Я использую только инструменты Bosh!” Круто, но что это говорит про результаты его работы?


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

      Неверно, т.к. тестировать юнит тестами надо функциональность, в том числе и скрытую, используя знание о внутренностях. То есть, проверять все ветки выполнения и т.п.
      Так что ЛЮБОЕ изменение потенциально ведет к изменению тестов, даже если это изменение в приватных членах.


      3. Вы меряете размеры проектов по количеству строк кода? :D

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

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

      А про размер проекта и строки кода - если вы этого не понимаете, то вам еще рано со мной спорить :)


      б) Приведенные вами примеры и в юнит-тесты то не запишешь

      Вы ошибаетесь. Консультанты и книги говорят другое. Почитайте Лармана.


      в) GUI покрывать unit-тестами и не надо, потому что в GUI нет логики, а тестировать надо логику. GUI можно накрыть автоматическим тетированием

      Вы ошибаетесь. Консультанты и книги говорят другое. Почитайте Лармана.


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

      Этот аргумент к чему?

      Еще раз, я не против TDD или юнит тестов. Мой пойнт в том, чтобы не применять их слепо, доверяясь теории.

  • Evgeny

    Было бы здорово, если бы блог подстраивался под экран. У меня разрешение 1680×1050 и в Firefox блок занимает только треть доступного места. Эта проблема многих тем wordpress, но я надеюсь вы с ней справитесь :)

    • Попробую. Хотя у темы тэг Fixed width не спроста, думаю :)
      По крайней мере увеличу размеры.

      • Дмитрий

        Интересная беседа про unit тесты. Но я не об этом. Ширина “сонтентной” области, на мой взгляд хороша и вот почему:
        - количество информации которое воспринимается человеком за один раз равно 7 +/- 2 еденицы информации, в данном случае количество слов в строке, и у вас не многим более, то есть восприятие информации не идеальное, но хорошее
        - опять же количество слов в строке очень близко к тому количеству которое используется в большинстве книг да и блогов.
        Так что мое мнение - ширина достаточная. А если же не убедил - загляните на сайты где текст идет во всю ширину, то увидите что читать тяжело, а если отвлекетесь в середине строки то и найти потом тяжело.
        Так что рекомендую, не делать слишком широко!

        • Ну хоть немного-то расширить стоит? Пикселей на 100-200?

          • Дмитрий

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

    • не, расширять не надо. у меня тоже 1280 и 1440 (на работе и дома). но люблю зумить текст до касания правого бордера - скроллинга браузера. Т.о. можно откинуться подальше от монитора и не напрягать глаза мелким шрифтом.

      • Ну хоть немного-то расширить стоит? Пикселей на 100-200? Или и так хорошо?

      • Evgeny

        Странно, но у меня зуминг ничего толкового не дает. Видимо, это от настроек. У меня стоит настройка “минимальный шрифт” в firefox и все сайты отображаются нужного размера (чтобы не зумить каждую страницу).

  • Xor

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

    А то периодически ощущение, что тесты рекламируются в первую очередь для борьбы с непрозрачным кодом, и гарантии сохранения прозрачных результатов.
    Грубо говоря: “Я не могу точно сказать, КАК оно работает, но я могу гарантировать, какой будет РЕЗУЛЬТАТ”.

  • Вы упускаете из виду одну важную вещ.

    Юниттесты это не просто тесты. Всмысле они конечно предохраняют код от поломки и дают спокойствие в том же плане. 5% покрытия значительно лучше чем 0%.. это все так.

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

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

    PS: Про смену интерфейсов - это конечно да… это заставляет не просто переделывать юниттесты, но кроме того заставляет всех участников проекта переделывать связанные модули. сотни модулей… :D

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

      Я про это не забываю. В последнем абзаце я написал про свое отношение - я не против TDD, я ЗА него. Как раз тогда, когда пишешь новый код, чтобы лучше его понять и спланировать. Да, лучше архитектура и т.п. Для этого и стоит их использовать.
      Но покрывать все 100% кода юнит тестами и писать всё с помощью TDD - я против этого. Есть код, который и без TDD прекрасно пишется.


      PS: Про смену интерфейсов - это конечно да… это заставляет не просто переделывать юниттесты, но кроме того заставляет всех участников проекта переделывать связанные модули. сотни модулей… :D

      Да, но юнит тесты приходится переписывать и при изменении приватной реализации, если она покрыта тестами. А она ДОЛЖНА быть покрыта при 100% покрытии.

      • Вообще нет смысла тупо сидеть и покрывать старый код тестами, исключительно ради тестов. Так же как абсолютно непродуктивным является просто рефакторинг.

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

        Писать тесты надо при изменении старого кода. В принципе, когда нечего делать :), можно покрывать тестами старый код, но эти тесты должны срабатывать. Мантра: Тест-Код-Рефакторинг в данном случае не должна работать.

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

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


          Писать тесты надо при изменении старого кода. В принципе, когда нечего делать :), можно покрывать тестами старый код, но эти тесты должны срабатывать. Мантра: Тест-Код-Рефакторинг в данном случае не должна работать.

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

      • Павел

        Да, но юнит тесты приходится переписывать и при изменении приватной реализации, если она покрыта тестами. А она ДОЛЖНА быть покрыта при 100% покрытии.
        Не совсем так - при правильном подходе тесты тестируют только интерфейс но при это покрывают 100 процентов. На пример, зная что в функции три ветки, можно подобрать данные что бы протестировать все три, но формально тестируется только интерфейс. Да, при изменении внутренней реализации покрытие может стать меньше 100% процентов, но поскольку тесты проверяли только интерфейс они будут продолжать работать.

        • Точно. Очень правильный комментарий.
          Мы тестируем открытые члены, но учитывая приватную реализацию. То есть, грубо говоря, привязываемся к приватной реализации. И очень часто при ее изменении ломаются и тесты. Например, мы можем знать, что внутри функции наращивается какой-то счетчик и проверять это в тесте, хотя счетчик скрыт. А потом решаем его удалить вообще. И тест перестал работать.
          И таких вариантов можно много вспомнить…
          Но в целом верно - тестируем только открытые члены.

          • gineer

            //Мы тестируем открытые члены, но учитывая приватную реализацию. То есть, грубо говоря, привязываемся к приватной реализации. И очень часто при ее изменении ломаются и тесты. Например, мы можем знать, что внутри функции наращивается какой-то счетчик и проверять это в тесте, хотя счетчик скрыт. А потом решаем его удалить вообще. И тест перестал работать.
            И таких вариантов можно много вспомнить…

            Это вы привели классический пример того, как НЕ НУЖНО писать юнит-тесты.
            Юнит-тест который “привязан” к приватной реализации — это НЕ юнит-тест.
            Он может находится в таком состоянии очень небольшое время, как временное решение между добавлением/тестированием другого функционала. Чтобы не плодить лишний геттер.
            Но пропускать его дальше — это булшет из булшетов. :))

            • Это вы привели классический пример того, как НЕ НУЖНО писать юнит-тесты.
              Юнит-тест который “привязан” к приватной реализации — это НЕ юнит-тест.

              Если мы говорим о 100% покрытии кода тестами, то юнит тест просто обязан быть привязан к приватной реализации.
              Кроме того, например, всякие Mock-объекты напрямую позволяют нам проверить реализацию функций через отслеживание вызовов других функий.

              Если тестировать только открытый интерфейс, то большого покрытия не дочтичь. Еще один пример:
              перегружаешь класс и делаешь из него testable класс. При этом перегружаешь, естественно, все приватные функции, какие надо и оставляешь их пустыми или что-то простое там делаешь - вуаля, ты уже привязался к приватной реализации.
              Повторюсь - очень много вариантов есть, когда ПРИХОДИТСЯ привязываться к ней.

              • gineer

                Да, я это понимаю.

                Но мое утверждение состоит в том, что тестирование “потрохов” означает только одно — проблемы с архитектурой.
                Что она недоработана — или человек просто не знает как её доработать, а то и не понимает что её нужно дорабатывать, или же нет возможности/времени над ней работать.
                То есть, попросту — костыли.

                • Если потроха тестируются по всему коду постоянно, то согласен. Если только местами, где это важно - пусть тестируются :)

                  • gineer

                    Если это как исключение из правил — тогда согласен.

                    Всегда есть такие места, в которых опытный специалист понимает что можно сделать и лучше, но это потребует еще кучу времени и нафиг не нужно, потому лучше оставить так как есть.

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

                    Тип как здесь рассуждается о возможности (а то и необходимости) тестирования приватной реализации. ;)

  • 1. TDD подразумевает не только написание тестов, но также и проверку и исполнение их, так что это не инструмент, а подход к работе, где написание тестов - один из шагов.

    • Да как не назови. Подход, средство, в любом случае это не смысл и не цель работы.

      Нужно правильно выбирать цели.

      PS: Хотя если начальство скажет - нужно 100% покрытие тестами - будем покрывать… :D

  • Простите, но я не могу опубликовать полностью свой ответ. В блоге не хватает markdown, древовидных комментариев и безглючного постинга. Поставьте Byteflow. Также не хватает emailа Вашего, куда можно было бы слать жалобы.

  • Что значит 100% покрытие кода тестами? :)

    На первой лекции по тестированию нам привели пример программы из 10 строк кода с двумя вложенными циклами и показали, что чтобы полностью проверить работу этого кода нужно выполнить 10^18 операций :) Я думаю тестировщики знают про это.

    TDD - это вовсе не о тестировании и не о покрытии кода тестами. Я вообще не понимаю откуда возникла цифра 100% - я много читал/смотрел/использовал TDD, но никогда не слышал о связи TDD и покрытии кода тестами.

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

  • Мой комментарий тоже не влез, я опубликовал его у себя в блоге: http://dmitrygusev.blogspot.com/2009/02/tdd.html

    • Спасибо за развернутый комментарий. Отвечаю и тут и там

      Итак, самое главное, на что обратил внимание и я и вы - это 100% покрытие кода тестами. Это и есть камень преткновения и про это моя статья. А не про то, что юнит-тесты вредны или не нужны :)

      100% покрытие юнит тестами значит буквально, что каждая функция и класс в коде должны быть полностью покрыты тестами. “ПОлностью” понятие растяжимое, но обычно это значит “не меньше одного теста на функцию”.
      И вот против этого я написал статью.

      А юнит тесты сами по себе полезны и нужны - с этим я не спорю.

      • “ПОлностью” понятие растяжимое, но обычно это значит “не меньше одного теста на функцию”.

        Помойму “полностью” это значит не менее одной проверки на каждую ветвь алгоритма.

        Ну во всяком случае все мы сходимся в том что тесты полезны. :) но без фанатизма.

  • Сказали уже много и я абсолютно согласна с аргументами Андрея Валяева и Сергея Кищенко.

    Вот еще несколько аргументов в защиту TDD:

    1. Тесты кроме прямого назначения, имею замечательное побочное свойство – это хорошее дополнение к документации. В момент разработки и архитекторы и программисты прекрасно представляют что делают модули, отдельные классы и все вплоть до функций. Но проходит год-два-пять (а иногда и 25) и уже никто ничего не помнит вообще. Есть документация на систему с общим описанием модулей (очень редко классов).
    Для более свежих есть еще UML диаграммы (но и они дают обычно довольно общую картину). Комментарии в коде говорят что делается, а не зачем это делается.
    И в этой ситуации если вдруг что-то потребовалось менять наличие тестов - это спасение. Именно по тестам можно понять что делает этот конкретный класс в конкретно этом месте. А уже потом тесты позволят провести изменения наименее болезненно и убедиться что не поломали что-то в процессе правки.

    2. Тесты очень помогают при работе распределенных команд или найме аутсорсеров/фрилансеров. При большом объеме работ только тесты дадут хоть какую-то гарантию что функционал соответствует ТЗ. Причем желательно чтобы тесты и функционал писали разные люди т.к. если разработчик что-то не правильно понял в ТЗ то от напишет неправильно и
    функционал и тесты.

    3. Xor писал < <И для команд с большим числом малоопытных /особенно, стремящихся поменьше думать/ программистов, важнее для начала реально придти к общим методикам проектирования и кодирования, формализовать
    дальнейшее написание кода.>>

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

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

    • Эх, почему-то все читают только негативную часть и не читают мой вывод в конце. Там всё объяснено:

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

      Я знаю плюсы TDD и люблю TDD. Но не всегда.

      • Elena Makurochkina

        Я прочитала :) Мой комент обрезаля и остаток запостить не смогла, т.ч. выслала его на bishop3000@rambler.ru.
        У Вас в заключении про маленькие проекты, обособленные модули и личное использование. Я же далее написала про большие команды, распределенные команды и длинные проекты.
        У меня такое отношение к Agile, как у Вас к TDD - интересно, но очень ограниченное применение и для небольших проектов.

        • У Вас в заключении про маленькие проекты, обособленные модули и личное использование. Я же далее написала про большие команды, распределенные команды и длинные проекты.

          Да, верно. Прочитал уже после того, как ответил.
          На самом деле мне было бы интересно поработать в большой команде, где используется тотально TDD. Чтобы понять изнутри насколько это полезно и выгодно. И используется ли он именно тотально, на 100% кода.
          Или как раз на 5% основного кода, библиотеках и бизнес логике? Против этих 5-10% я ничего не имею и только за.


          У меня такое отношение к Agile, как у Вас к TDD - интересно, но очень ограниченное применение и для небольших проектов.

          У нас Agile и большие проекты :)

          • Вообще сложно сказать что такое 100%.
            Как выше написал Дмитрий Гусев «На первой лекции по тестированию нам привели пример программы из 10 строк кода с двумя вложенными циклами и показали, что чтобы полностью проверить работу этого кода нужно выполнить 10^18 операций Я думаю тестировщики знают про это.»

            Пример:
            Что-бы оттестировать корректность обработки входящего имени файла надо:
            1. Проверить что в процедуре обрабатывается что
            a. файл не пустой
            b. файл существует
            2. Проверить что корректно работает при
            a. содержании пробелов в имени файла и пути
            b. содержании нелатинских символов в имени файла и пути
            c. наличие одинарных открывающей/закрывающей кавычек
            d. наличие одной одинарной открывающей кавычки
            e. наличие одной одинарной закрывающей кавычки
            f. наличие двойных открывающей/закрывающей кавычек
            g. наличие одной двойной открывающей кавычки
            h. наличие одной двойной закрывающей кавычки
            Вроде ничего не забыла… (про тестирование Exception-ов при вышеперечисленных проблемах даже не упоминаю)
            С такой дотошностью, конечно, не тестируется, а смотрится в каком виде имя файла может придти и если на более ранних этапах система должна была отсечь проблемы с пунктами 2.c-2.h (т.к. обычно это обрабатывает стандартный компонент ввода), а так же весь пункт 1 (например это проверилось в вызывающем классе), то проверяется только 2.a и 2.b.

            Да, и, кстати, TDD «в чистом виде» (это когда только приемы TDD и ничего более) мы не используем. Так же как и любую из double-D методик или других современных buzz word методик.

            У меня про тестирование есть старый пост: http://sundest.blogspot.com/2006/12/agile-testing.html Там как раз про то когда и в какой степени удобен TDD.

            • Пример:
              Что-бы оттестировать корректность обработки входящего имени файла надо:

              Хороший пример. При этом список тестов неполный. Можно было бы добавить проверку путей в NT формате, проверку относительных путей, пути на несуществующие диски, что если вместо имени файла передать имя пайпа и многое другое. Набор почти бесконечен. Поэтому фразы типа 100% покрытия тестами и раздражают, особенно, когда их говорят руководители :)

              У меня про тестирование есть старый пост
              Ага, читал.

              • И еще.

                Немало копий сломано о вопрос – тестировать приватные классы в юнит тестах или не тестировать. Мой однозначный ответ – тестировать. Т.к. это сильно снижает количество тестов. Отдельный класс может иметь всего 1 паблик функцию, но очень сложную логику и для того, чтобы оттестировать все надо не только много написать, но и потратить много времени на планирование тестов (что-бы чего не забыть). А при тестировании приватнх функций функции пишутся маленькие (насколько это возможно), тестики простенькие, писать их может тот же программист, что пишет сам класс (иногда требуется, что бы тесты и код писали разные разработчики, а иногда может писать один – зависит от задачи и разработчика :) ), не тестируется по несколько раз одно и то же (что бывает при тестировании сложных ветвлений публичных функций).

                • > Немало копий сломано о вопрос – тестировать приватные классы в юнит тестах или не тестировать. Мой однозначный ответ – тестировать.

                  Приватные классы или приватные методы?

                  Очень интересно услышать, как вы их тестируете. Приходится открывать?

                  Со статическими классами/методами проще - классы можно открыть и вынести, например, в пакет internal, в который по соглашению клиенты лезть не должны, а методы просто вынести в утилиты.

                  Как быть, если класс/метод зависит от контекста (не является статическим)? Как в этом случае тестировать приватные классы/методы? Ведь нужно иметь возможность установить контекст, который тоже может быть в приватных полях, эти поля тоже открывать или делать специальные инициализирующие методы/конструкторы?

                  Пока писал этот комментарий получил ответы на свои вопросы, но все-равно интересно выслушать, какие подходы используете вы? :)

                  Я знаю, что можно сделать классы/методы открытыми для тестов в c# средствами языка, но в Java, например, такой возможности нет. Зато в Java, как и в c#, можно установить значения полей/вызвать методы (в том числе и приватных) используя рефлексию. Я много раз слышал по Mocks, но ни разу не использовал этот подход - не было необходимости. Я делал методы контекстно-независимыми и открывал их, и это работало :). Собственно, теперь я вижу, что использование Mocks может здесь помочь.

                  • «Приватные классы или приватные методы? »

                    И то и другое.

                    «какие подходы используете вы? »

                    Пишем на Delphi, а там есть «бага/фича» - если тесты писать в том же юните, что и класс, то можно свободно обращаться к приватным методам класса (и, конечно же, к приватным классам).

                    В .net варианты тестирования точно есть, но тонкостей не знаю. Очень хороший блог, там много по тестированию в .net (приемы, тулзы и т.д.): http://weblogs.asp.net/rosherove/default.aspx

                • gineer

                  //Немало копий сломано о вопрос – тестировать приватные классы в юнит тестах или не тестировать. Мой однозначный ответ – тестировать.

                  Если вам приходится тестировать приватные классы — значит у вас серьозные проблемы с архитектурой и пониманием TDD вообще. :) Вполне возможно что вы используете не тот TDD.
                  Я имею личный опыт такой работы, когда в компании вроде бы используется TDD, в том смысле что используется инструментарий юнит-тестирования, но самого ТДД там просто нет, потому как отсутствует понимания архитектуры и рефакторинга как средства улучшения архитектуры.

                  Юнит-тест — это тест который помагает разрабатывать лаконичные и правильные внешние интерфейсы, облегчает процедуру рефакторинга. Это все — вопросы архитектуры.

                  • > Если вам приходится тестировать приватные классы — значит у вас серьозные проблемы с архитектурой и пониманием TDD вообще.

                    Одно другому не мешает. Если я не использую TDD, что же мне теперь - на ощупь писать? :) Тесты сами по себе тоже полезны, независимо от TDD.

                    > Юнит-тест — это тест который помагает разрабатывать лаконичные и правильные внешние интерфейсы

                    Мы все прекрасно понимаем, что одними интерфейсами разработка не заканчивается - интерфейсы нужно еще реализовать :)

                    • gineer

                      //Одно другому не мешает. Если я не использую TDD, что же мне теперь - на ощупь писать?

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

                      //Тесты сами по себе тоже полезны, независимо от TDD.

                      А кто здесь это отрицал???

                      //Мы все прекрасно понимаем, что одними интерфейсами разработка не заканчивается - интерфейсы нужно еще реализовать

                      Если интерфейсы серьозно проработаны, то реализация их, тем более при наличии юнит-тестов — это чисто техническая задача на кодирование.

                      Кроме того, в ходе ТДД ведь разрабатывается и функциональность…

                  • «Если вам приходится тестировать приватные классы — значит у вас серьозные проблемы с архитектурой и пониманием TDD вообще. »

                    Безаргументный постулат «у вас серьезные проблемы с пониманием…» - это доказательство из серии «что лысый может понимать в литературе». Плюс Вы свалили в кучу архитектуру и и методологию разработки (TDD) – это вообще совершенно разные вещи. Архитектура от методологии не зависит (за редкими исключениями). Методология – это способ разработки архитектуры (и реализации кода). Далее в ту же кучу долепили рефакторинг, но это уже не важно.
                    Тестировать или не тестировать приват – это holy wars. И спорить по этому поводу сейчас у меня нет никакого желания. Свои аргументы я привела. А в holy wars пожно поучаствовать на программерских ресурсах.

                    «Я имею личный опыт такой работы, когда в компании вроде бы используется TDD, в том смысле что используется инструментарий юнит-тестирования, но самого ТДД там просто нет»

                    Выше я писала «Да, и, кстати, TDD «в чистом виде» (это когда только приемы TDD и ничего более) мы не используем. Так же как и любую из double-D методик или других современных buzz word методик.
                    У меня про тестирование есть старый пост: http://sundest.blogspot.com/2006/12/agile-testing.html Там как раз про то когда и в какой степени удобен TDD. »

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

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

                    «Юнит-тест — это тест который помагает разрабатывать лаконичные и правильные внешние интерфейсы, облегчает процедуру рефакторинга. Это все — вопросы архитектуры. »

                    Юнит-тест – это просто прием - тестирование одного юнита ограммы, т.е. отдельной маленькой части («мелкость» этой части каждый определяет для себя сам). Чем Юнит-тест помогает в конкретной ситуации зависит от того как его использовать. Если выбрать довольно крупный юнит с большим количеством приватных классов и сложной логикой, то юнит-тесты превращаются в функциональные тесты, а это уже совсем другой подход к написанию тестов.
                    Рефакторинг без тестов проводить вообще нельзя, но к TDD это не имеет никакого отношения. Этот прием вообще не привязан к какой бы то ни было методологии.

                    • gineer

                      \\Безаргументный постулат «у вас серьезные проблемы с пониманием…» - это доказательство из серии «что лысый может понимать в литературе».

                      Ну если лысый понимает, то он и аргумент поймет. :))
                      Здесь просто нет достаточно месте чтобы приводить аргументы с такой степенью детальности, чтобы всем подряд понятно было. sapienti sat
                      Потому — в сад, со своими претензиями к аргументам. :)

                      //Плюс Вы свалили в кучу архитектуру и и методологию разработки (TDD) – это вообще совершенно разные вещи.

                      Вот. Ваши аргументы не лучше.
                      Я нигде не утверждал о тождественности ТДД и архитектуры. Вы сами это приплели.
                      ТДД — это метод, позволяющий интерактивно разрабатывать архитектуру, делать о ней предположения и тут же их проверять. В купе с рефакторингом это еще и методология улучшения архитектуры существующего кода.
                      По аналогии с инженерной практикой, ТДД — это как модельный эксперимент, модельный прототип.
                      И конечно же не может заменить собой всю остальную работу, имеет свои ограничения по разумности применения.

                      //Архитектура от методологии не зависит (за редкими исключениями).

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

                      Разработка архитектуры требует прежде всего опыта разработки вообще.
                      А с другой, методика её разработки имеет ОЧЕНЬ существенное влияние, буде это водопадная, agile или какая еще… каждая оставляет свой отпечаток и имеет свои недостатки применения.

                      А ТДД тем и интересна, что позволяет оставить вопросы архитектуры “на потом”, опробовать сначала её действенность, а потом уже реализовывать.

                      //Далее в ту же кучу долепили рефакторинг, но это уже не важно.

                      Если вы не понимаете что такое рефакторинг, я ли вам доктор? :)

                      //Тестировать или не тестировать приват – это holy wars.

                      Это продукт непонимания.
                      Приватный класс, он хоть и приватный, но имеет такой же, свой собственный внешний интерфейс.
                      И именно этот внешний интерфейс и нужно тестировать (и с использованием ТДД). И тогда это уже не будет называтся тестированием приватной реализации.
                      А то что вы этого момента не понимаете, означает что вы не понимаете коренных вопросов разработки архитектуры таких как ортогональность и инкапсуляция.
                      А holywar, потому что поступающих так же как и вы “специалистов” очень много…

                      Это напомнило мне разговор с одним тим-лидом на прошлой работе.
                      Он мне показал пример кода, в котором стековая переменная созданная внутри функции и отданая по указателю наружу, и там используется (до вызова следующей функции, понятно). :))
                      Он спросил моем мнение — я естественно ответил что это булшет.
                      Он же возразил: “Но оно ведь работает”. :))

                      Вот что мне напоминают ваши возражения. Стиль вашей работы, по тому как он описан здесь — очень напоминает ту шарашку — мою позапрошлую работу. :))

                      //TDD (как и любая из double-D) методологий имеет очень много ограничений и очень небольшое поле проектов, когда можно применять методологию в чистом виде.

                      True. Самое главное из которых, это понимание методологии самими разработчиками.

                      \\Юнит-тест – это просто прием - тестирование одного юнита ограммы, т.е. отдельной маленькой части

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

                    • gineer

                      //Безаргументный постулат «у вас серьезные проблемы с пониманием…» - это доказательство из серии «что лысый может понимать в литературе».

                      Тем не менее, если лысый таки понимает в литературе, то он и аргумент поймет. :))
                      Здесь просто нет достаточно месте чтобы приводить аргументы с такой степенью детальности, чтобы всем подряд понятно было. sapienti sat
                      Потому — в сад, со своими претензиями к аргументам. :)

                      //Плюс Вы свалили в кучу архитектуру и и методологию разработки (TDD) – это вообще совершенно разные вещи.

                      Вот. Ваши аргументы не лучше.
                      Я нигде не утверждал о тождественности ТДД и архитектуры. Вы сами это приплели.
                      ТДД — это метод, позволяющий интерактивно разрабатывать архитектуру, делать о ней предположения и тут же их проверять. В купе с рефакторингом это еще и методология улучшения архитектуры существующего кода.
                      По аналогии с инженерной практикой, ТДД — это как модельный эксперимент, модельный прототип И конечно же не может заменить собой всю остальную работу, имеет свои ограничения по разумности применения.

                      //Архитектура от методологии не зависит (за редкими исключениями).

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

                      Разработка архитектуры требует прежде всего опыта разработки вообще. А с другой, методика её разработки имеет ОЧЕНЬ существенное влияние, буде это водопадная, agile или какая еще… каждая оставляет свой отпечаток и имеет свои недостатки применения.

                      А ТДД тем и интересна, что позволяет оставить вопросы архитектуры “на потом”, опробовать сначала её действенность, а потом уже реализовывать.

                      //Далее в ту же кучу долепили рефакторинг, но это уже не важно.

                      Если вы не понимаете что такое рефакторинг, я ли вам доктор? :)

                      //Тестировать или не тестировать приват – это holy wars.

                      Это продукт непонимания.
                      Это как если бы хирурги после операции “холиварили” — зашивать пациента или нет. :)))
                      Приватный класс, он хоть и приватный, но имеет такой же, свой собственный внешний интерфейс. И именно этот внешний интерфейс и нужно тестировать (и с использованием ТДД). И тогда это уже не будет называтся тестированием приватной реализации.
                      А то что вы этого момента не понимаете, означает что вы не понимаете коренных вопросов разработки архитектуры таких как ортогональность и инкапсуляция. А holywar, потому что поступающих так же как и вы “специалистов” очень много…

                      Это напомнило мне разговор с одним тим-лидом на прошлой работе. Он мне показал пример кода, в котором стековая переменная созданная внутри функции и отданная по указателю наружу, и там используется (до вызова следующей функции, понятно). :))
                      Спросил моем мнение — я естественно ответил что это булшет.
                      Он же возразил: “Но оно ведь работает”. :))

                      Вот что мне напоминают ваши возражения. Стиль вашей работы, по тому как он описан здесь — очень напоминает ту шарашку — мою позапрошлую работу. :))

                      //TDD (как и любая из double-D) методологий имеет очень много ограничений и очень небольшое поле проектов, когда можно применять методологию в чистом виде.

                      True. Самое главное из которых, это понимание методологии самими разработчиками.

                      \\Юнит-тест – это просто прием - тестирование одного юнита ограммы, т.е. отдельной маленькой части

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

              • «Можно было бы добавить проверку путей в NT формате, проверку относительных путей, пути на несуществующие диски, что если вместо имени файла передать имя пайпа и многое другое. »

                Почти все перечисленные проблемы покрываются тестом на наличие файла (1.b) и если не предусмотрено отдельной обработки какого либо из случаев в самой функции, то отдельных тестов на них не требуется. Хотя, зависит, конечно, какой функцией языка проверять наличие файла :) Если встроенная функция языка путает папку и файл – то отдельный тест нужен.

                «Поэтому фразы типа 100% покрытия тестами и раздражают, особенно, когда их говорят руководители :)»

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

    • 2. Тесты очень помогают при работе распределенных команд или найме аутсорсеров/фрилансеров. При большом объеме работ только тесты дадут хоть какую-то гарантию что функционал соответствует ТЗ. Причем желательно чтобы тесты и функционал писали разные люди т.к. если разработчик что-то не правильно понял в ТЗ то от напишет неправильно и
      функционал и тесты.

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

      У вас есть положительный опыт работы с этим подходом?

      • Есть, как раз с привлечением фрилансеров:
        Есть проект. Нужна новая фича для реализации которой нет нужной квалификации ни у кого из команды (т.е. есть общие знания, можно почитать, попробовать самим, но на это требуется много времени), соответственно даже оценить качество реализации довольно затруднительно. Разрабатывается интерфейс новых классов, пишутся к нему тесты, пишется ТЗ и отдается фрилансеру. Собственно все… Без тестов никак.

        Так же была ситуация, когда со старым проектом (своими, не доставшимися по наследству неизвестно от кого) был ступор в разработке т.к. логика сильно запутанная, а тестов не было. В результате пока не разобрали (в своем же коде! причем хорошо откомментированном) для чего каждый if нужен и не написали на каждый if тест дальше двигаться не могли. Если бы тесты писались сразу времени и нервов сэкономили бы очень много.

        • Про фрилансеров - интересный подход. А как вы юнит тесты и правильные интерфейсы пишете до того, как спроектировали код? Ибо, если сами написать не можете, то как можете спроектировать? Или это совместно с фрилансерами делается? Если фрилансеру понадобилось сменить интерфейс - вы сами меняете тесты?


          Так же была ситуация, когда со старым проектом (своими, не доставшимися по наследству неизвестно от кого) был ступор в разработке т.к. логика сильно запутанная, а тестов не было. В результате пока не разобрали (в своем же коде! причем хорошо откомментированном) для чего каждый if нужен и не написали на каждый if тест дальше двигаться не могли. Если бы тесты писались сразу времени и нервов сэкономили бы очень много.

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

          P.S.:
          так всё-таки, судя по примерам, TDD и юнит тесты вы применяете далеко не всегда. Каков процент? :)

          • «Про фрилансеров - интересный подход. А как вы юнит тесты и правильные интерфейсы пишете до того, как спроектировали код? Ибо, если сами написать не можете, то как можете спроектировать?»

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

            «И на самом деле то, что тесты у этого кода уже были бы написаны вам бы не помогло его понять - все равно лучше было бы новых тестов понаписать для лучшего понимания :) »

            Тесты очень помогают понять. Это видно на более свежих проектах, которые обвешаны тестами по сравнению с необвешанными. У меня же в первом комментарии первым же пунктом: «Тесты кроме прямого назначения, имею замечательное побочное свойство – это хорошее дополнение к документации» Но это из серии лучше один раз увидеть, чем 100 раз услышать.

            «так всё-таки, судя по примерам, TDD и юнит тесты вы применяете далеко не всегда. Каков процент? »

            Очень сильно зависит от проекта.
            Если проект планируется большой и длинный (т.е. изменения реализованного функционала будут на протяжении жизни проекта и проекту желается долгое здравие) – стремление к 100% покрытию (с оговорками из примера про имя файла что не тестируется то, что 100% оттестировано в вызывающем классе/функции).
            Если проект (обычно относится к отдельным модулям) разовый (т.е. один раз написали и в течении жизни проекта модификации данного модуля не будет), то тестируются места со сложной логикой. Пример такого модуля – чтение заголовков писем из файлов Outlook Express-а, что-бы мы потом с этими данными не делали, сам Outlook Express – старый формат, меняться не будет, изменения в чтении не предвидится.
            Особый вопрос с БД – там количество тестов сильно зависит от времени настройки данных БД для каждого теста. Если одни и те-же данные подходят для всех требующихся тестов – пишем все. Если под каждый нужны свои данные – выборочный подход.

            Еще от исполнителя зависит. Код аутсорсеров приходится обвязывать тестами по максимуму.

            • Основательный у вас подход к фрилансерам. Но, наверное, только так и можно с ними работать.

              Тесты очень помогают понять. Это видно на более свежих проектах, которые обвешаны тестами по сравнению с необвешанными. У меня же в первом комментарии первым же пунктом: «Тесты кроме прямого назначения, имею замечательное побочное свойство – это хорошее дополнение к документации». Но это из серии лучше один раз увидеть, чем 100 раз услышать.

              Это точно. С удовольствием бы поработал с кодом, обвешанным тестами, чтобы “попробовать”.

            • gineer

              //Особый вопрос с БД – там количество тестов сильно зависит от времени настройки данных БД для каждого теста. Если одни и те-же данные подходят для всех требующихся тестов – пишем все. Если под каждый нужны свои данные – выборочный подход.

              Для этого вам лучше использовать фэйк-реализацию доступа к БД.
              А то гонять тесты на БД — это не очень умно.
              Вы ведь не тестируете работу базы данных. ;)

              • > Для этого вам лучше использовать фэйк-реализацию доступа к БД.
                > А то гонять тесты на БД — это не очень умно.
                > Вы ведь не тестируете работу базы данных. ;)

                Тогда придется еще и тестировать “фейк-реализацию доступа к БД” :) Знаем - проходили.

                Проще использовать разные базы данных (dev/test/production).

                • gineer

                  //Тогда придется еще и тестировать “фейк-реализацию доступа к БД” Знаем - проходили.

                  Типа “Плавали, знаем.” :)) Ню-ню.

                  Если у вас такие способности к программированию, что вам даже фейк-реализацию нужно тестировать на ошибки…. :))

                • Тогда придется еще и тестировать “фейк-реализацию доступа к БД” :) Знаем - проходили.

                  Проще использовать разные базы данных (dev/test/production).

                  Тесты, использующие базы данных - это уже не совсем unit тесты. Это уже system тесты, ибо тестирование идет не на уровне кода, а на уровне работающей системы.

                  Это не значит, что system тесты плохи - просто это более высокий уровень тестов.

                  Unit тесты покрывают код, system тесты - функциональность.

              • Можно гонять тесты на in-memory db, например, это существенно увеличивает скорость.

                • gineer

                  Да. Это лучше.
                  Но все равно — не то.

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

                  Но видно не все это понимают. :))

                  • > копия интерфейса реальной базы данных

                    Зачем делать копию интерфейса реальной базы данных (я правильно понимаю, что это DAO)?

                    Создать тестовые объекты непосредственно в методе теста и передать их на вход тестируемой логике - вот какой подход будет работать.

                    Зачем мне создавать эти объекты в новой “фейк-реализации” DAO? Вы же не будете на каждый тест создавать такую реализацию? Или будете?

                    Дальше. Как вы будете тестировать запросы к базе? На реальной базе? Или SQL, JPA-/EJB-/…-/QL не нуждается в тестировании? Вы запросы пишете раз и наверняка? Дальше, что если результатом работы сервиса является изменение состояния БД - как вы это будете тестировать с вашей фейк-реализацией? А что если там, на дай бог, транзакции? Вы будете реализовывать поддержку транзакций в фейк-реализации?

                    > Можно гонять тесты на in-memory db

                    Тестовую БД можно выбрать какую угодно, лишь бы код запросов не был зависим от реализации SQL в БД. ORM-фреймворки позволяют добиться этого эффекта. Поэтому у меня в проектах часто тестовая БД - Derby, промышленная - любая другая. Это избавляет от необходимости настраивать тестовую БД. Но даже если такая необходимость есть, то лучше сделать тестовую копию БД и заполнять ее тестовыми данными, например, используя DbUnit. test/dev/production режим тестирования БД придумал не я - посмотрите Ruby On Rails, посмотрите методики разработки от Oracle - все говорят об этом. И я их подход разделяю, потому что сам к нему также пришел, использовал его и такое использование было успешным.

                  • Моканье - это хорошо. Вот только в случае с in-memory db для ускорения производительности достаточно написать 20 строк кода(которые уже могут быть и написаны). Фейк-реализация может занять банально больше времени.

  • Denis

    Очень интересная статья. У меня одна маленькая поправка. Мне кажется, что слово “legacy” вполне можно было бы переводить как “унаследованный”.

    • “Унаследованный” не передает всего программерского ужаса, содержащегося в слове “legacy” :)
      Еще одно значение Legacy из словаря: “устаревший, снятый с производства, но всё ещё находящиеся в эксплуатации, унаследованный”
      В программерском же словаре сюда еще можно добавить: плохой код, который никто не понимает.

  • А нельзя ли привести парочку пруфлинков на относительно свежие заявления каких-нибудь уважаемых людей о том, что требуется дескать 100%-е покрытие кода тестами? Мне кажется, что уже давненько никто из TDD-евангелистов не делал таких опрометчивых высказываний.

    • Пару месяцев назад у нас неделю консультировал Ковбой - Craig Larman (http://www.craiglarman.com)
      Он это утверждал.
      Да и у Джоеля в статье это указано.

      • А, так у Вас на Лармана зуб? Ну так он больше по менеджерам специализируется. Да, тамошние консультанты ещё не просекли, что лозунг про 100% устарел :) Менеджерские консультанты почему-то всегда немного отстают. Впрочем, может быть так и должно быть.

        • Он лекции и для менеджеров и для программеров вёл.
          У меня не то, что “зуб” на него.
          Но, скажем так, “он меня не убедил”. И даже больше - некоторые идеи вроде 100% покрытия тестами и постоянного TDD после его лекций и практических занятий, потеряли всю привлекательность для меня.

          • Ну вот, всё таки была польза от его лекций :)

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

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

            И вообще, что такое это покрытие кода, что за священная корова? Тестировщики используют кучу разных метрик, Сэм Канер как-то написал статью, в которой перечислил больше сотни разных полезных метрик — измерять замучишься :)

            Но и это не самое страшное следствие проповедей ларманов! Хорошо, если программист воспринимает всё это разумно. А если ему пофиг, но его работа оценивается по степени покрытия кода юнит-тестами? Тогда он начинает работать на метрику, а не на качество кода! Вот это реально плохо.

            • Но и это не самое страшное следствие проповедей ларманов! Хорошо, если программист воспринимает всё это разумно. А если ему пофиг, но его работа оценивается по степени покрытия кода юнит-тестами? Тогда он начинает работать на метрику, а не на качество кода! Вот это реально плохо.

              Вот и я про то же самое говорю. Не надо воспринимать правила TDD, как евангелие :)
              Основной инструмент программиста - голова.
              К счастью, наши менеджеры все вышли из программистов и понимают что и к чему.

  • >>Но я противник … применения TDD для работы с legacy кодом.

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

  • Виталий Колесников

    Столько умных людей беседовало, право слово, а посоветовать исправить “серебренной” на “серебряной” никто не догадался. Ай-яй-яй. :)
    Моё почтение.
    P.S. В очередной раз наблюдаю, как смысл дискуссии перетекает в комментарии к комментариям. Правда, ничего против не имею, это очень интересно.

  • @bishop: Вы получили моё письмо?

  • Начало прямо стандартное для статьи про TDD.

    Дальше идут перлы:
    1)Первый перл про 100% покртие кода юнит-тестами. Это в принципе невозможно. Часть вашего кода взаимодействует с хранилищами данных, UI, внешними сервисам, этот код не попадает в компетенцию юнит-тестов.
    Кроме того может быть автогенерируемый код в проекте, его также нет смысла покрывать юнит-тестами.

    Далее, даже 100% показатель code coverage, собираемый инструментами не дает гарантии покрытия всех use-case любого модуля\класса\функции.

    Поэтому говорить о 100% покрытии кода юнит-тестами не стоит, стоит говорить о 100% покрытии юнит-тестами сценариев работы основных модулей\классов. Если у вас класс является тривиальным адаптером над БД\UI\сервисом, то писать для него юнит-тест не надо.

    Обычно при 100% покрытии юнит-тестами сценариев работы основных модулей показатель code coverage колеблется в пределах 40%-70%. В зависимости от объема инфрастуктурного кода в приложении.

    Далее впоминаем что кроме юнит-тестов есть и другие виды автоматизированного тестирования, такие как интеграционные тесты и тесты интерфейса.
    Вот при правильном написании интеграционных тестов, работающих в реальном окружении (настоящая БД, настоящие сервисы, UI не трогаем) можно получить 80%-95% code coverage в совокупности с unit-тестами.
    Если еще и писать тесты для интерфейса то можно и все 100% покрытия получить.
    Но, к сожалению, чем более высокуровневый тест, тем сложнее его писать. Поэтому пногие предпочитают пользоватся правилом 80/20 и пишут интеграционные тесты для 20% функционала, а на тесты интерфейса вообще забивют.

    2)Перл номер два: “Юнит тесты не имеют ничего общего с качеством - это просто инструмент, позволяющий проверить, что вы не сломали ничего из прошлой функциональности.”
    Это часто говорят те, кто начитался книжек и сам не использовал TDD.
    Основная ошибка в том, что юнит-тесты рассматривают сами по себе. Но в TDD тесты влияют на процесс написания кода, подталкивая к более хорошему дизайну.
    Кроме того правильно написанные тесты являются очень хорошей документацией коду.

    • 1)Первый перл про 100% покртие кода юнит-тестами.

      Это пёрл не мой, а из статьи Джоеля и из выступлений консультантов :)


      2)Перл номер два: “Юнит тесты не имеют ничего общего с качеством - это просто инструмент, позволяющий проверить, что вы не сломали ничего из прошлой функциональности.”
      Это часто говорят те, кто начитался книжек и сам не использовал TDD.
      Основная ошибка в том, что юнит-тесты рассматривают сами по себе. Но в TDD тесты влияют на процесс написания кода, подталкивая к более хорошему дизайну.
      Кроме того правильно написанные тесты являются очень хорошей документацией коду.

      Возможно я в этой фразе был слишком резок, ее стоило бы перефразировать в “Юнит тесты - не гарантия качества кода и продукта”.

      TDD, как известно - это один из процессов разработки. Как процесс, он статистически дает улучшение качества кода, с этим не поспоришь.
      Я же в этих строках писал про юнит тесты. Юнит тесты - это просто куски кода, а не процесс. И сами юнит-тесты без процесса не обеспечивают никакого качества, даже статистически. А их очень часто применяют без правильного процесса разработки и плюются.

      • Так именно об этои и стоило напписать.
        Я вообще считаю что не стоит применять unit-тесты без TDD ибо только увеличивает накладные расходы.

        Вы пишите про TDD и при этом рассматриваете недостатки юнит-тестов в вакууме.

        Кстати и без юнит-тестов можно достичь 100% code coverage, или близкого к этому значения. Поэтому треть статьи вообще мимо кассы, но непросвещенный мозг может прнять это за истину.

      • gineer

        //А их очень часто применяют без правильного процесса разработки и плюются.

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

        Процессы же разработки — это совсем другое. Вам пока нельзя в тим-лиды, если вы этого не понимаете. :)

        • Процессы же разработки — это совсем другое. Вам пока нельзя в тим-лиды, если вы этого не понимаете. :)

          Есть люди, которые любят вешать ярлыки и обвинять. А есть люди, которым плевать на ярлыки.
          Я проработал достаточно успешно почти 7 лет тимлидом и главным программистом и мне по большому счету плевать кто и что думает про то, можно мне в тимлиды или нет :)

          • gineer

            С другой стороны — нет пределов для совершенства. И критику можно воспринимать как нападки, а можно как подсказку для развития своего личного понимания. ;)

          • gineer

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

            • А вы спешите понимать это как персональный наезд. ;)

              Я люблю критику. Но не в форме “Вам пока нельзя в тим-лиды, если вы этого не понимаете. :)”

              На самом деле этот пост и комменты дали мне много новой интересной пищи для размышлений и изучений и много новых знакомств и блогов.
              Хорошо, что я его таким спорным написал - в этом и была идея :) Так что я на 100% справился с задачей.
              При этом мое личное отношение к TDD и тестам может быть даже не совсем верно описано в этой статье, некоторые высказывания слишком радикальны. Но так надо было.

              • gineer

                Ну так и я, со знакомыми людми не общаюсь в таком форумно-флеймовом стиле. ;)
                Да и смайлик там… опять же намек на подначку. ;)
                Так что, что продатете, то и вам возвращается. :)

  • maxcom

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

    • Пример про меню и GUI - плохой. При правильном дизайне такого возникать не должно, наличие завязок на пункты меню это излишняя связность кода. Цена модификации такого кода велика, и причина не в наличии тестов.

      Верно. Пример потому и плохой, что показывает минусы 100% покрытия тестами. Я бы никогда не стал покрывать гуи тестами. Кто-то покрывает.
      Кто-то завязывается и на пункты в меню, наверняка.

      • Моя плакать…
        Так и напишите в начале: “Если вы хреново пишите программы, то юнит-тесты вам не помогут.”
        Будет чистая правда.

        • В целом это правда. Хотя консультанты утверждают, что толпа обезьянок куча слабых программистов с использованием TDD вполне могут написать хороший код.

          • Правильно утверждают.

            Сравните свое высказываение с “куча слабых программистов с использованием юнит-тестов вполне могут написать хороший код”.
            Почувтсвутек разницу.

            Писать строго по TDD нелегко.
            Многие скатываются к тому что пытаются повысить показатель code coverage всеми правдами и неправдами вместо применения TDD.

          • gineer

            Нельзя так.
            Вы бы сами хотели, чтобы менеджеры рассуждали о вас как об одном из “толпы обезьянок”?

            То что программисты бывают молоды и неопытны — это не их вина.
            А задача для менеджера, так организовать процесс, чтобы они могли развиватся.
            И испорльзование ТДД в этом отношении — очень хорошая практика.
            Особенно с применением ХР практики парного программирования, когда вместе садят новичка и опытного программиста, и тот учит его своим примером как правильно писать юнит-тесты, а новичок помогает ловить баги, как минимум те что на уровне опечаток.

            Но проблема в том, что выше описанная ситуация — идеальная, требует чтобы менеджер такого проекта был опытным и понимал как оно должно работать, а не просто нахвататся “мудрости” у консультантов да из буков по модным методологиям…

  • Отлиный взгляд! Чувствуется что вас достали эти кричащие методолгии. Забавно - накнулся на статью как раз занимаясь чтением книги Физерса.

  • Есть мнение, что “не влезание” может быть связано с openid, с тем, что вы не зарегистрированы на сайте и вас просят подтвердить openid - тут что-то и отрезается.
    Можете попробовать зарегистрироваться - будет тогда обрезаться?

Ответить

 

 

 

Вы можете использовать эти HTML тэги

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>