Начало работы с TDD?

Мы находимся на начальной стадии попытки внедрения TDD. Я демонстрационный код Visual Studio Team System/TDD, и команда взволнована возможностями. В настоящее время мы используем Devpartner для покрытия кода, но мы хотим его устранить, потому что это дорого. У нас очень ограниченный опыт в TDD и мы хотим убедиться, что мы не ошибаемся. В настоящее время мы используем SourceSafe для управления исходными кодами, но через год будем мигрировать в Team System.

Я могу сказать, что наши приложения очень ориентированы на данные. У нас около 900 таблиц, 6000 хранимых процедур и около 45 ГБ данных. У нас много расчетов, основанных на пользовательских данных и разных скоростях в системе. Также много нашего кода основано на времени (рассчитать интерес к текущей дате). Некоторые из этих расчетов очень сложны и очень интенсивны (лишь некоторые из них знают подробности для некоторых из них).

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

Я боюсь, поскольку наш код настолько ориентирован на данные, что внедрение TDD может быть немного более сложным, чем большинство систем. Я пытаюсь придумать игровой план, который я могу представить руководству, но я хочу, надеюсь, не попасться на некоторые ошибки начинающего TDD. Также, если инструменты/средства в Team System делают TDD более полным, это было бы неплохо, но мы не хотим ждать начала Team System.

Первый вопрос, который мы задаем, - это просто начать с инструментов в визуальной студии? Я прочитал сообщение: люди жалуются на встроенные инструменты в визуальной студии (нужно создать отдельный проект для создания вашего теста), но одна вещь о инструментах в визуальной студии - они свободны, и интеграция хороша. Если мы решим перейти на другой маршрут, используя что-то вроде XUnit, MBUnit или NUnit, то мы, скорее всего, будем иметь некоторые, возможно, значительные затраты:

1) Если мы хотим интегрировать IDE (не упоминается большая часть нашего кода - VB.Net)
---TestDriven.Net или Resharper или?????

2) Если мы хотим получить покрытие кода
--- NCover (кажется довольно дорогим для его функциональности)

Также я видел довольно классную функциональность, продемонстрированную в visual studio 2010. Как и возможность выполнять входное тестирование (данные, введенные в форме), или возможность записывать то, что сделал пользователь, а затем передавать их в ваш unit test для воспроизведения проблемы.

Кроме того, хотя я еще не совсем понимаю концепцию насмешливого объекта, я знаю, что многие люди считают это обязательным. Вопрос в том, могут ли все насмешливые фреймворки подключаться к визуальной студийной версии TDD (MSTEST)?

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

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

Ответ 1

Первое, что нужно сделать, это получить эту книгу:

Эффективно работает с устаревшим кодом

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

Ответ 2

Не спешите и ради Бога не пытайтесь заставить разработчиков делать TDD.

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

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

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

Используемые инструменты практически не важны.

P.s. тонны устаревшего кода и ориентированного на данные приложения = > хорошая форма для бедствия.

Ответ 3

1) Я использую TestDriven.Net, и мне нравится это +1 от меня для этого
2) Охват кода полезен, когда о нем думают в правильном расположении духа:
Высокий охват кода не обязательно означает высококачественные модульные тесты, но...
Высококачественные модульные тесты означают высокий уровень покрытия кода

Я использовал только NCover, поэтому не могу рекомендовать альтернативы.

Что касается насмешек - как только вы поймете, что это значит и что это действительно значит для вас, вы увидите преимущества, которые он может предложить. А именно, это означает, что вы не зависите от интеграции кода, который вы тестируете, с внешней зависимостью, а также помогает сократить время выполнения текста (например, издевательство вашего уровня доступа к данным предотвращает дорогостоящее взаимодействие с БД). На мой взгляд, это важный фактор, так как тесты проходят много времени, люди могут начать не беспокоить их, если это означает, что им нужно слишком долго ждать! Я использую NUnit, который поддерживает встроенный mocks.

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

Когда вы начинаете тестирование TDD/unit, я всегда рекомендую писать тесты для кода, написанного с "сейчас", и не фокусироваться слишком много на написании тестов для устаревшего/существующего кода. Это намного сложнее сделать в целом и намного дороже по времени, особенно если код старый/не свежий ни у кого!

Обновление: Чтобы объяснить мой последний момент немного дальше, в ответ на комментарий Роберта...

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

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

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

Ответ 4

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

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

Эффективная работа с устаревшим кодом, Michael Feathers

Также я бы рекомендовал взглянуть на эту книгу:

Искусство модульного тестирования, Рой Ошерове

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

Надеюсь, что это поможет.

Ответ 5

Что касается начала работы, я бы также рекомендовал прочитать Fowler Рефакторинг. Первая глава дает хорошее представление о том, что значит вводить тесты, а затем безопасно вводить изменения (хотя акцент здесь делается на изменении сохранения поведения). Кроме того, этот говорит о некоторых практиках, которые могут помочь улучшить тестируемость вашего кода. Misko Hevery также имеет это руководство по написанию тестового кода, в котором суммируется разговор.

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

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

Переход от SourceSafe к Team System - большой шаг, насколько большой зависит от того, сколько вы хотите сделать в Team System. Я думаю, вы можете получить большую ценность от использования Visual Studio, встроенной в тестовую среду. Например, в качестве первого шага вы можете реализовать некоторые базовые комплекты тестов для основных случаев использования системы/ядра. Разработчики могут запускать их самостоятельно в Visual Studio по мере их работы и до регистрации. Эти пакеты можно постепенно расширять с течением времени. Позже, когда вы получаете TFS, вы можете посмотреть, как управлять этими наборами при регистрации и как часть процесса автоматической сборки. Вы можете следовать аналогичному пути, независимо от конкретных инструментов.

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

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

Однако, я думаю, важно помнить, что высокий охват блоков - это просто измерение эффективности ваших тестов. Например, скажем, вы пишете класс для очистки файлового архива и сохраняете 5 новых файлов. Затем вы пишете тестовый пример, который проверяет, начинаете ли вы с 10 файлов, а затем запустите очиститель, оставшийся с 5. Реализация, которая проходит тест, может удалить самые новые файлы, но может легко обеспечить 100% охват. Этот тест проверяет только 1 из требований.

Ответ 6

100 палец вверх для эффективной работы с устаревшим кодом, рекомендованным Yishai. Я также рекомендую "Прагматическое тестирование модуля" на С# с помощью NUnit, поскольку вы используете .NET(хотя я предполагаю С#). Это было очень полезно для обучения основам модульного тестирования, обеспечивающего прочную основу для работы.

Ответ 7

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

Вы упомянули много инструментов, чьи рекламные возможности вас волнуют, и задавались вопросом, как их собрать. Я думаю, что эти вопросы очень хорошо рассматриваются "xUnit Test Patterns", от Addison-Wesley (http://xunitpatterns.com/). Эта книга позволила мне собрать все те инструменты и методы, о которых я читал в прошлом.

Книга может лучше обслуживать аудиторию, которая также ценит другие книги, такие как "Банда из четырех шаблонов дизайна", "Рефакторинг" и "Рефакторинг для шаблонов". Эти книги также велики, хотя у них не было так прямого изменения в том, как я закодирован после того, как я их прочитал. Презентация XUnit Test Patterns отражает стиль книг. Вначале их трудно читать, так как они склонны пересекать контрольные главы в произвольных направлениях. Я думаю, что они очень твердые, хотя.

В GoF представлены категории шаблонов - творческие, структурные и поведенческие. Эти категории служат способом связывания и сопоставления описываемых шаблонов. Путем сопоставления шаблонов проектирования с типичным временем жизни unit test шаблоны XUnit Test также объединяют ряд методов, доступных для модульного тестирования. Эти же шаги также используются для сопоставления и сравнения различных инструментов, используемых для построения модульных тестов.

Это поможет с представлением высокого уровня и вступят в реальную реализацию.

Моя единственная критика XUnit Test Patterns заключается в том, сколько текста они используют для критики NUnit. NUnit - прекрасная часть программирования, к ее автору кредит NUNit мы упомянули так заметно в том, что, я думаю, станет классической книгой.