Что бы вы сделали, когда собираетесь добавить некоторые новые функции в большую (и грязную) кодовую базу, которая имеет практически * NO * unit-testing code?

Мартин Фаулер говорит, что мы должны делать рефакторинг перед добавлением новых функций (учитывая, что исходная программа не имеет хорошо структурированной структуры).

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

Но это большая база кода. Добавление полного набора тестов к нему кажется неосуществимым.

Что бы вы сделали в этом случае?

Ответ 1

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

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

Ответ 2

Позвольте мне рекомендовать книгу Эффективно работать с устаревшим кодом Michael Feathers. Он содержит множество реалистичных примеров и показывает хорошие методы для борьбы с устаревшим зверьком кода.

Ответ 3

Добавьте модульные тесты к коду, который вы собираетесь в Refactor.

Ответ 5

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

Модульные тесты - отличный сервис для программиста, но они не являются единственным видом тестирования.

Ответ 6

Не думайте об этом как о том или ином. Добавлена ​​добавленная стоимость путем добавления модульных тестов - вам не нужно добавлять полный набор, чтобы получить преимущества добавления некоторых тестов.

Ответ 7

Я часто встречаюсь в этой ситуации, так же как и в том, что я застрял в течение последних двух лет.

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

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

  • Сложность выполненных изменений. Если вы делаете глубоко сложные изменения в кодовой базе (типичный случай в "грязной" кодовой базе, b/c такой источник, как правило, плотно связан и incohesive), некоторые рефакторинги, скорее всего, будут вызваны. Такие изменения не являются результатом того, что они являются ниндзями кода, поскольку они необходимы вам просто для объяснения изменений, которые вы делаете. Это также связано с "плохой" кодовой базы, которую вы изменяете. Практически невозможно создать даже самые простые юнит-тесты для плотно соединенного, бессвязного беспорядка. (Я говорю по опыту. Один из проектов, которые я почти застрял в обслуживании, был длиной около 20 тыс. Строк, исключая сгенерированный код, в двенадцать файлов. Все приложение было одним классом под названием "Form1". Это пример того, как dev злоупотребляет функция частичного класса.)

  • Организационный контроль. Сила и строгость контроля вашей организации вступают в игру здесь. Если ваша группа действительно выполняет некоторые основные передовые методы, такие как обзоры кода, и не просто оплачивает им слова, я бы более склонен не делать обширных рефакторингов. Компромисс между ценностями, вероятно, больше связан с тем, что он трогает как можно меньше, потому что у вас есть еще одна пара свежих глаз, проверяющих, чтобы ни одна из немногих изменений, которые вы сделали, не имела нежелательных побочных эффектов. Точно так же более строгий надзор с большей вероятностью будет хмуриться в тактике "партизанских" кодов внесения изменений, которые не требуют строгого запроса в запросе на изменение.

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

Ключевой вопрос, на который вам нужно ответить при рассмотрении любого такого рода инвестиций, как это: "Где значение лежит?" Затем вам нужно преследовать это значение.

Ответ 8

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

Ответ 9

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

Если это хорошая работа (скажем, год человека или 3 человека в течение 4 месяцев), то вы, вероятно, захотите, чтобы кто-то разорвал код и проанализировал его в первую очередь.

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

Я различаю только статические и динамические языки, потому что гораздо проще делать рефакторинг на статически типизированном языке - они, как правило, намного более предсказуемы. Я не ненавижу Ruby или что-то еще - я провел год на ROR. Я просто думаю, что им нужны разные подходы.

Ответ 10

Фаулер также предполагает, что вы никогда не реорганизуете без безопасности тестов. Но как вы получаете эти тесты на месте? И, как далеко вы идете?

Ранее рекомендованная книга (Эффективная работа с устаревшим кодом Майкла Перса) - это окончательная работа над этой темой.

Нужно быстрее читать? Взгляните на Майкла ранее статью (PDF) с тем же именем.

Ответ 11

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

Ответ 12

Если добавление набора тестов нецелесообразно, у вас есть серьезная проблема с кодовой базой.

Добавление нового кода и наделение его Просто работает плохо.

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

Ответ 13

коснитесь как можно меньше. И молитесь.

Ответ 14

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