Добавление модульных тестов к устаревшему коду

Вы когда-нибудь добавляли модульные тесты после факта к устаревшему коду? Насколько сложным был код и как сложно заглушить и издеваться над всем? Был ли конечный результат стоящим?

Ответ 1

Лучший способ, я нашел, - это постепенно добавлять модульные тесты, а не просто входить и говорить, что мы будем теперь unit test приложение.

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

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

Нет простого способа сделать это.

Этот вопрос может помочь в дополнительных предложениях. Как вы вводите модульное тестирование в большую, устаревшую (C/С++) кодовую базу?

Ответ 2

Книга Майкла Перса "Эффективная работа с устаревшим кодом" - это целая книга, посвященная этой теме. Майкл утверждает, что часто бывает сложно вводить тесты для устаревшего кода, поскольку он не структурирован для проверки. То, что я выбрал из книги, - это несколько паттернов, названных "Функции Sprout" и "Sprout classes". Функция прорастания - это та, которая инкапсулирует изменения, которые необходимо внести в код. Вы тогда unit test только эти функции. Класс sprout - это та же идея, за исключением того, что новая функциональность содержится в классе.

Ответ 3

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

В книге "Искусство модульного тестирования" есть несколько хороших советов по этому вопросу. Он также рекомендует книгу Эффективно работать с устаревшим кодом; Я еще не прочитал последнее, но это в моем стеке.

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

EDIT: я действительно прочитал "Эффективно работаю с устаревшим кодом" и отлично.

Ответ 4

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


Структура unit test, такая как семейство xUnit, может использоваться для записи тестов характеристик.

В таких тестах, написанных после фактов, утверждения проверяют текущее поведение кода. В отличие от модульных тестов, они не доказывают правильность кода, они просто фиксируют (характеризуют) текущее поведение кода.

Процесс аналогичен процессу TDD:

  • написать тест для части кода
  • выполнить его - сбой
  • исправить тест из наблюдаемого поведения кода
  • выполнить его - передать
  • повторить

Тесты потерпят неудачу, если вы измените внешнее поведение кода. Внешнее поведение кода? звучит знакомо? Да, это мы. Теперь вы можете реорганизовать код.

Очевидно, что риск зависит от охвата тестов характеристик.

Ответ 5

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

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

Ответ 6

Взгляните на бесплатную библиотеку утилиты для тестирования модулей с открытым исходным кодом, ApprovalTests. Если вы являетесь разработчиком .NET, создатель Llewellyn Falco сделал серию видеороликов , показывая, как он использует ApprovedTests для улучшения модульного тестирования для обоих новый и устаревший код.

Ответ 7

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

Как упоминалось в подходе ApproachTests в в этой статье:

Часто у вас есть огромный проект кода устаревшего кода, в котором у вас нет тестов на все, но вам нужно изменить код для реализации новой функции или рефакторинг. Интересная вещь о устаревшем коде - это работает! Это работает в течение многих лет, независимо от того, как это написано. И это очень здорово преимущество этого кода. С одобрениями, только с одним тестом, который вы можете получить все возможные выходы (HTML, XML, JSON, SQL или любой другой вывод будьте) и одобрите, потому что вы знаете - это работает! После завершения такой тест и утвердил результат, вы действительно намного безопаснее с рефакторинг, так как теперь вы "заблокировали" все существующее поведение.

Инструмент Asis точно связан с сохранением устаревшего кода путем автоматического создания и запуска тестов характеристик.

Подробнее см.

Ответ 8

Я уже некоторое время говорил о идее "Пирамида перевернутых тестов" в "Legacy Code" в XPDays http://xpdays.com.ua/archive/xp-days-ukraine-2012/materials/legacy-code/

В этой презентации следует ответить на вопрос, почему так важно иногда начинать с интеграционных/функциональных или даже приемочных тестов высокого уровня при работе с устаревшим кодом. А затем медленно, шаг за шагом вводя модульные тесты. Нет примеров кода - извините, но вы можете найти их в книге Михаэля Перса "Эффективно работать с Legacy Code".

Также вы можете проверить Legacy Code Retreat http://www.jbrains.ca/legacy-code-retreat и искать эту встречу в своей области.