Яков Сироткин (yakov_sirotkin) wrote,
Яков Сироткин
yakov_sirotkin

Рефакторинг: тестирование

При рефакторинге вы всё время меняете код, значит у вас есть большие риски, что вы что-то поломаете. Значит, нужно всё время тестировать, что же у вас получилось, и, следовательно, иметь возможность быстро пересобрать проект. Прежде чем начать изменять какой-то участок кода необходимо научиться воспроизводить ситуацию, в которой этот код работает. Это не всегда просто — однажды ко мне пришёл на починку баг, про который я знал, как чинить, но он был в таком далёком месте системы, что мне понадобился целый день, чтобы воспроизвести его у себя, при том что двое коллег мне активно помогали это сделать. Часто в системе много очень похожих друг на друга кусочков и бывает полезно поставить breakpoint и убедиться, что именно на нём остановится выполнение программы. Разумеется, после внесения изменений нужно проверить, что всё работает хорошо. Крайне желательно разбивать задачу на несколько небольших этапов и после каждого контролировать результат.

А как же знаменитые юнит-тесты? А они, извините, не работают. Я много раз видел в проекте папку с тестами, в которой содержались исходные коды разной степени компилируемости, которые даже иногда показывали какие-то результаты. Но скажите, что означают успешно отрабатывающие тесты, если код воняет в каждой строчке и невооружённым глазом видны ошибки с многопоточностью и с кодировками, а исключения методично игнорируются? Рассмотрим пример: есть тесты на парсинг XML, но: париснг сделан через SAX, что в данном случае не имеет смысла и его надо переписать на DOM, после чего он станет на порядок проще, XML из тестов не такой, как сейчас в системе, в результате парсинга хочется получать полноценный объект, а не макароны различных свойств с неправильными именами, которые есть сейчас. Получается, что существующий код должен практически полностью исчезнуть и тянуть за собой в процессе рефакторинга ещё и изменения тестов, которые уже наполовину поломаны, крайне затратно.

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

К счастью, кроме плохо помогающих юнит-тестов, есть живые тестировщики, которые тоже могут писать автоматические тесты. Только тесты эти будут уже функциональными и их прохождение действительно будет свидетельствовать о работоспособности системы.
Tags: refactoring
Subscribe
  • Post a new comment

    Error

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 27 comments