В настоящее время я занимаюсь рефакторингом части большой кодовой базы без каких-либо модульных тестов. Я попытался реорганизовать код грубо, то есть, пытаясь угадать, что делает код, и какие изменения не изменили бы его значения, но безуспешно: он случайным образом нарушает функции по всей базе кода.
Обратите внимание, что рефакторинг включает в себя перевод унаследованного кода C # в более функциональный стиль (в унаследованном коде не используются какие-либо функции .NET Framework 3 и более поздних версий, включая LINQ), добавление обобщений, где код может извлечь из них пользу, и т. Д.
Я не могу использовать формальные методы , учитывая, сколько они будут стоить.
С другой стороны, я предполагаю, что, по крайней мере, следует строго соблюдать правило «Любой переработанный унаследованный код с юнит-тестами» , независимо от того, сколько это будет стоить. Проблема в том, что когда я выполняю рефакторинг крошечной части частного метода 500 LOC, добавление модульных тестов оказывается сложной задачей.
Что может помочь мне узнать, какие модульные тесты актуальны для данного фрагмента кода? Я предполагаю, что статический анализ кода был бы как-то полезен, но какие инструменты и методы я могу использовать для:
Точно знать, какие юнит-тесты я должен создать,
И / или знаете, повлияло ли изменение, которое я сделал, на исходный код так, как он выполняется по-другому?
источник
formal methods in software development
любом случае, вы не захотите использовать его, потому что он используется для доказательства правильности программы, использующей логику предикатов, и не может применяться для рефакторинга большой кодовой базы. Формальные методы, обычно используемые для проверки кода, работают правильно в таких областях, как медицинские приложения. Вы правы, делать это дорого, поэтому его не часто используют.Ответы:
У меня были похожие проблемы. Книга « Работа с устаревшим кодом» - отличный ресурс, но есть предположение, что вы можете использовать ее в модульных тестах для поддержки своей работы. Иногда это просто невозможно.
В моей работе по археологии (мой термин для обслуживания на унаследованном коде как этот), я следую подобному подходу относительно того, что Вы обрисовали в общих чертах.
На этом этапе у вас должен быть список кандидатов на то, что подвергалось и / или манипулировалось этой процедурой. Некоторые из этих манипуляций могут быть непреднамеренными. Теперь я использую
findstr
и IDE, чтобы понять, какие другие области могут ссылаться на элементы в списке кандидатов. Я потрачу некоторое время, чтобы понять, как работают эти ссылки и какова их природа.Наконец, как только я заблуждаюсь, думая, что понимаю последствия оригинальной процедуры, я буду вносить свои изменения по одному и перезапуску этапы анализа, которые я изложил выше, чтобы убедиться, что изменение работает так, как я ожидаю. это на работу. Я специально стараюсь избегать одновременного изменения нескольких вещей, поскольку обнаружил, что это взрывает меня, когда я пытаюсь проверить влияние. Иногда вы можете избежать нескольких изменений, но если я могу следовать по одному маршруту, это мое предпочтение.
Короче, мой подход похож на то, что вы выложили. Это много подготовительной работы; затем сделайте осмотрительные, индивидуальные изменения; а затем проверить, подтвердить, проверить.
источник
Краткий ответ: маленькие шаги.
Рассмотрим эти шаги:
Переместите реализацию в другую (приватную) функцию и делегируйте вызов.
Добавьте код регистрации (убедитесь, что регистрация не завершилась) в исходной функции для всех входов и выходов.
Запустите ваше приложение и сделайте с ним все, что можете (действительное использование, недопустимое использование, обычное использование, нетипичное использование и т. Д.).
Теперь у вас есть
max(call_count)
наборы входов и выходов для написания ваших тестов; Вы можете написать один тест, который перебирает все ваши параметры / наборы результатов и выполняет их в цикле. Вы также можете написать дополнительный тест, который запускает определенную комбинацию (для быстрой проверки прохождения определенного набора ввода / вывода).Переместить
// 500 LOC here
обратно вugly500loc
функцию (и удалить при входе функции).Начните извлекать функции из большой функции (больше ничего не делайте, просто извлекайте функции) и запускайте тесты. После этого у вас должно быть больше мелких функций для рефакторинга, а не 500LOC.
Жить долго и счастливо.
источник
Обычно модульные тесты - это путь.
Сделайте необходимые тесты, которые докажут, что ток работает как положено. Не торопитесь, и последний тест должен сделать вас уверенным на выходе.
Вы находитесь в процессе рефакторинга фрагмента кода, вы должны точно знать, что он делает и на что он влияет. Таким образом, в основном вам нужно проверить все зоны воздействия. Это займет у вас много времени ... но это ожидаемый результат любого процесса рефакторинга.
Тогда вы можете разорвать все на части без проблем.
AFAIK, для этого нет техники пуленепробиваемости ... вам просто нужно быть методичным (в зависимости от того, какой метод вам удобнее), много времени и терпения! :)
Ура и удачи!
Alex
источник