Test -> Code -> Refactor, когда мы должны начать рефакторинг? - PullRequest
5 голосов
/ 31 августа 2009

Круг TDD:

"Write failing Test" -> "Write Code to fit a Test" -> "Refactor"

На шаге «Кодирование» предполагается, что код написан настолько просто, насколько это возможно, просто чтобы исправить неудачный тест. Мы не должны писать сложный код, пока он действительно не понадобится.

Следующий шаг - Refactor. Должны ли мы рефакторинг только что написанного кода? Я думаю, что нет никакого смысла, так как мы должны быть довольны кодом, поскольку тесты проходят.

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

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

Какие еще причины вы видите, чтобы начать Рефакторинг?

Также правильна ли эта схема:

"Write failing Test" -> "Code" -> "Refactor" -> "Write failing Test"

или, может быть, это следует рассматривать как

"Write failing Test" -> "Code/Refactor" -> "Write failing Test"
+
"External factor (like bad performance)" -> "Refactor".

Ответы [ 6 ]

9 голосов
/ 31 августа 2009

Вы можете написать довольно уродливый код во время прохождения теста; Реактор теперь не потому, что он не работает, но не очень удобен в обслуживании. Это точный случай.

После написания кода, подходящего для нескольких тестов, вы можете начать смотреть более широко - есть ли совпадения между этими частями кода, где вы можете исключить некоторое дублирование?

5 голосов
/ 31 августа 2009

TDD - отличный инструмент, чтобы держать вас в курсе задач. Проблема с:

«Тест при ошибке записи» -> «Код / Refactor» -> «Тест при ошибке записи»

Вы предлагаете, это легко может стать:

«Тест при ошибке записи» -> «Refactor» -> «Код» -> «Тест при ошибке записи»

или затем

«Тест при ошибке записи» -> «Refactor» -> «Refactor» -> «Refactor» -> «Код» -> «Тест записи без ошибок»

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

Кроме того, вы не хотите проводить рефакторинг, когда ваши тесты не зеленого цвета.

Пара других маленьких очков:

  1. Я думаю, что большая часть литературы имеет немного другое определение того, что такое рефакторинг. Это не «некоторые изменения в системе» или улучшения производительности, а конкретные изменения, которые не меняют поведение, но улучшают дизайн. Если вы примете это определение, то улучшения производительности на самом деле не будут подходить: это обычные задачи разработки, которые требуют собственных приемочных тестов. Я обычно пытаюсь оформить их как истории, с которыми сталкиваются конечные пользователи, где выгода от их использования очевидна. Имеет смысл?

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

1 голос
/ 31 августа 2009

Есть ли плохое время для рефакторинга, кроме как за неделю или две до выхода основного выпуска?

1 голос
/ 31 августа 2009

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

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

1 голос
/ 31 августа 2009

Хмм ... Я обычно рассматриваю этот вид "внешних" рефакторингов отдельно от самого цикла TDD. После завершения функции XYZ с использованием TDD необходимо иметь исправный набор тестов, чтобы предотвратить появление ошибок с помощью рефакторинга (при условии оптимального покрытия кода и т. Д.). Как бы то ни было, узкие места в производительности и сложный для понимания код обычно возникают по факту, поэтому рефакторинг на этом этапе был бы идеальным, как мне кажется. Вы можете повысить производительность, упростить понимание кода и делать все остальное, что нужно при использовании тестов, чтобы убедиться, что вы не вносите ошибок в систему.

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

0 голосов
/ 10 мая 2018

Правило трех:

  1. Когда вы делаете что-то в первый раз, просто сделайте это.

  2. Когда вы делаете что-то подобное во второй раз, избегайте повторения, но все равно делайте то же самое.

  3. Когда вы что-то делаете в третий раз, начните рефакторинг.

При добавлении функции:

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

  2. Рефакторинг облегчает добавление новых функций. Гораздо проще вносить изменения в чистый код.

При исправлении ошибки:

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

  2. Менеджеры ценят упреждающий рефакторинг, поскольку он устраняет необходимость в специальных задачах рефакторинга позже. Счастливые боссы делают счастливых программистов!

Во время проверки кода:

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

  2. Лучше всего делать такие обзоры в паре с автором. Таким образом, вы можете быстро решить простые проблемы и измерить время для решения более сложных.

...