Хорошо, поэтому большая часть обзора кода довольно обычная. Но иногда происходят изменения, которые в значительной степени влияют на существующий сложный, хрупкий код. В этой ситуации время, необходимое для проверки безопасности изменений, отсутствия регрессии и т. Д., Является чрезмерным. Возможно, даже превышение времени, затраченного на разработку.
Что делать в этой ситуации? Слиться и надеяться, что ничего не ускользнет? (Не пропагандируя это!) Делать все возможное и пытаться только выявить какие-либо очевидные недостатки (возможно, это все-таки рецензия кода, к которой следует стремиться в любом случае?) Объединить и тщательно протестировать как лучшую альтернативу, чем обзор кода вообще?
Вопрос не в том, следует ли проводить тестирование как часть обзора кода. Это вопрос, задающий вопрос о том, каковы наилучшие варианты в описанной ситуации, особенно в связи с крайним крайним сроком, отсутствием полного набора модульных тестов или модульных тестов, не пригодных для измененного фрагментированного кода.
РЕДАКТИРОВАТЬ: у меня сложилось впечатление, что некоторые из ответов / комментариев до сих пор подхватили мою фразу «широкое влияние», и, возможно, принял это, чтобы означать, что изменение включает в себя большое количество строк кода. Я могу понять это, будучи интерпретацией, но это не было моим намерением. Под «широким воздействием» я имею в виду, например, вероятность регрессии высока из-за взаимосвязанности кодовой базы или масштабов побочных эффектов, а вовсе не обязательно, что само изменение является значительным. Например, разработчик может найти способ исправить ошибку одной строкой, вызвав существующую подпрограмму высокого уровня, которая каскадно обращается ко многим подпрограммам более низкого уровня. Тестирование и проверка работоспособности исправленной ошибки просты. Вручную проверить (посредством проверки кода) влияние всех побочных эффектов гораздо сложнее.
источник
what if there is no pre-existing test suite?
- Как насчет написания одного?Merge and hope nothing slips through?
Это общеизвестно плохая идея.Ответы:
Суть вопроса, прямо скажем, поразительна. Мы полагаем, что в хрупкий и сложный код внесены большие изменения, и что просто не хватает времени для его правильного просмотра . Это самый последний код, который вы должны тратить меньше времени на просмотр! Этот вопрос указывает на то, что у вас есть структурные проблемы не только в самом коде, но и в вашей методологии управления изменениями.
Так как бороться с этой ситуацией? Начните с того, что не входите в него в первую очередь:
Определите источники сложности и примените тщательный, тщательно проверенный, правильный рефакторинг для повышения уровня абстракции. Код должен быть понятен новому сотруднику, который только что окончил колледж и знает кое-что о вашей бизнес-сфере.
Определить источники хрупкости; это может быть сделано путем обзора самого кода, изучения истории исправлений ошибок в коде и т. д. Определите, какие подсистемы являются хрупкими, и сделайте их более устойчивыми . Добавьте логику отладки. Добавьте утверждения. Создайте медленную, но, очевидно, правильную реализацию того же алгоритма, и в своей отладочной сборке запустите оба и убедитесь, что они согласны. В вашей отладочной сборке, чтобы редкие ситуации возникали чаще. (Например, создайте распределитель памяти, который всегда перемещает блок при перераспределении, или всегда выделяет блок в конце страницы, или что-то еще.) Сделайте код устойчивым перед лицом изменений в его контексте. Теперь у вас больше нет хрупкого кода; теперь у вас есть код, который находит ошибки, а не вызывает ошибки.
Написать набор автоматизированных тестов. Очевидно.
Не делайте широких изменений. Сделайте серию небольших целенаправленных изменений, каждое из которых можно увидеть правильными.
Но, по сути, ваш сценарий таков: «мы зарылись в дыру технического долга, и каждое сложное, не прошедшее обзор изменение углубляет нас; что нам делать?». Что вы делаете, когда попадаете в эту дыру? Хватит копать . Если у вас так много долгов, что вы не можете выполнять базовые задачи, такие как просмотр кода друг друга, вам нужно прекратить делать больше долгов и тратить время на их погашение.
источник
Одной из основных целей обзора кода является повышение качества и обеспечение надежного кода . Надежный, потому что 4 глаза обычно обнаруживают больше проблем, чем 2. И рецензент, который не написал дополнительный код, с большей вероятностью оспаривает (потенциально ошибочные) предположения.
Отказ от рецензирования в вашем случае только увеличит хрупкость вашего кода. Конечно, усиление тестирования с помощью надежного и повторяемого набора тестов, безусловно, может улучшить качество. Но это должно быть дополнением к экспертной оценке, а не заменой .
Я думаю, что сложность должна быть понята и освоена, и полная рецензия дает возможность поделиться знаниями и достичь этого. Инвестиции, которые вы вкладываете в то, чтобы как можно больше людей понимали сильные и слабые стороны хрупкого кода, со временем помогут сделать его лучше.
Цитата, чтобы сделать вывод:
источник
Добро пожаловать в мир разработки устаревшего программного обеспечения.
У вас есть сотни тысяч, миллионы, десятки миллионов строк кода.
Эти строки кода ценны тем, что они генерируют поток доходов, а их замена неосуществима.
Ваша бизнес-модель основана на использовании этой базы кода. Так что ваша команда маленькая, а кодовая база большая. Добавление функций необходимо для того, чтобы люди покупали новую версию вашего кода или чтобы клиенты были довольны.
В идеальном мире ваша огромная кодовая база тестируется на модуле wazoo. Вы не живете в идеальном мире.
В менее совершенном мире у вас есть бюджет, чтобы исправить техническую задолженность - разбейте код на части, тестируемые модулем, проведите сложное интеграционное тестирование и выполняйте итерации.
Это, однако, погашает долг без производства новых функций. Что не соответствует бизнес-случаю «пожинать прибыль от существующего кода, изменяя его, чтобы создать стимул для обновления».
Вы можете взять огромные куски кода и переписать его, используя более современные методы. Но везде, где вы взаимодействуете с существующим кодом, вы будете выставлять возможные точки останова. Тот взлом в системе, от которого вы избавились, компенсировал причуду в подсистеме, которую вы не переписывали. Всегда.
Что вы можете сделать, это действовать осторожно. Вы можете найти некоторую часть кода, которую вы на самом деле понимаете, и чье поведение и взаимодействие с остальной частью системы хорошо изучены. Вы можете модернизировать это, добавляя модульные тесты и делая его поведение еще более понятным.
Затем найдите части остальной части приложения, которые в основном взаимодействуют с ним, и атакуйте их по одному.
Делая это, вы можете улучшить подсистему, добавив функции, за которые клиенты готовы платить.
Короче говоря, это искусство возможного - вносить изменения, не ломая вещи, которые обеспечивают экономическое обоснование.
Но это не твой вопрос. Ваш вопрос таков: «Я делаю что-то грандиозное и, вероятно, ломаю вещи, и как мне следовать передовым методам?»
Делая что-то огромное, это правда, что если вы хотите сделать это надежно, вы в конечном итоге тратите больше усилий на поиск ошибок и их исправление, чем на написание. Это общее правило разработки программного обеспечения: писать вещи легко, заставить работать безупречно сложно.
Вероятно, у вас над головой висит бизнес-кейс, в котором вы пообещали какой-то заинтересованной стороне, что это масштабное изменение вступит в силу. И оно «сделано», поэтому вы получаете отпор, говоря: «Нет, это не сделано, это просто выглядит нравится это".
Если у вас есть власть и бюджет, на самом деле тратите усилия на то, чтобы создать уверенность в том, что изменение работает, или просто отклоните изменение. Это будет степень, а не вид.
Если у вас не так много энергии, но все еще есть, попытайтесь настаивать на том, что новая система может быть проверена модулем . Если вы переписываете какую-то подсистему, настаивайте на том, что новая подсистема состоит из небольших частей с четко определенным поведением и модульных тестов вокруг них.
Тогда есть худший случай. Вы идете глубже в долг. Вы одалживаете будущее программы, имея больше хрупкого кода и больше ошибок, чтобы вывести эту функцию сейчас и проклясть последствия. Вы проводите тестирование на основе развертки, чтобы найти худшие проблемы и игнорировать остальные. На самом деле это иногда правильный ответ с точки зрения бизнеса, так как сейчас он самый дешевый. Погружение в долги с целью получения прибыли является действительной бизнес-стратегией, особенно если на столе лежит очистка долга посредством банкротства (отказ от кода).
Большая проблема состоит в том, что редко стимулы владельцев компании совпадают с лицами, принимающими решения, и программистами. Как правило, существует большое давление, чтобы «доставить», и сделать это путем создания почти невидимого (для вашего начальства) технического долга - это отличная краткосрочная и иногда среднесрочная стратегия. Даже если ваш начальник / заинтересованные стороны будут лучше обслуживать, не создавая весь этот долг.
источник
Решите более крупные проблемы, которые делают проверку кода слишком сложной.
Те, которые я заметил до сих пор:
источник
Вы можете отправить обзор кода назад и попросить разработчика разбить его на более мелкие, более инкрементальные наборы изменений и отправить меньший обзор кода.
Вы по-прежнему можете проверять запахи кода, шаблоны и анти-шаблоны, стандарты форматирования кода, принципы SOLID и т. Д., Не обязательно просматривая каждую деталь кода.
Вы все еще можете выполнять тактические проверки кода для правильной проверки ввода, блокировки / управления потоками, возможных необработанных исключений и т. Д. На детальном уровне, не обязательно понимая общее намерение всего набора изменений.
Вы можете предоставить оценку общих областей риска, на которые, как вам известно, может повлиять код, и попросить разработчика подтвердить, что эти области риска прошли модульное тестирование (или попросить его написать автоматические модульные тесты, а также представить их на рассмотрение). ).
источник
Проверка кода не должна быть в первую очередь направлена на правильность. Они здесь, чтобы улучшить читаемость кода, удобство обслуживания и соблюдение стандартов команды.
Обнаружение ошибок правильности во время проверки кода - хороший побочный результат их выполнения, но разработчик должен убедиться, что их код работает идеально (включая отсутствие регрессии), прежде чем отправлять его на проверку .
Корректность должна быть заложена с самого начала. Если один разработчик не может достичь этого, попросите его объединить программу или составить план для всей команды, но не относитесь к нему как к чему-то, что вы можете добавить как запоздалую мысль.
источник
Если вы считаете, что проверка кода слишком сложна, поскольку она изменила хрупкий код, который почти невозможно изменить, не нарушив его, то у вас есть проблема. Но проблема не в обзоре кода. Проблема также не в модульных тестах, потому что хрупкий код не может быть модульным! Если бы ваш код был модульно тестируемым, то он был бы разбит на небольшие независимые блоки, каждый из которых мог бы быть протестирован, и которые хорошо работали бы вместе, а это именно то, чего у вас нет!
Таким образом, у вас есть куча мусорного кода (он же «технический долг»). Худшее, что вы можете сделать, это начать исправлять эту кучу мусорного кода, а не завершить работу, потому что таким образом вы получите еще большую кучу мусорного кода. Поэтому первое, что вы должны сделать, чтобы ваше руководство приняло решение исправить это и закончить работу. Или нет. В этом случае вы просто не трогаете это.
Когда вы исправляете это, вы извлекаете один модуль из кода, превращаете его во что-то, что имеет четко определенное и хорошо документированное поведение, пишите модульные тесты для этого модуля, просматриваете код и молитесь, чтобы ничего не сломалось. И затем вы делаете то же самое со следующим блоком, и так далее.
Сложность возникает, когда вы сталкиваетесь с ошибками. В некоторых случаях ваш код для крыс будет делать неправильные вещи, потому что все настолько хрупко и сложно, что все пойдет не так. По мере извлечения модулей оставшийся код станет более понятным. (У меня был случай, когда после некоторого рефакторинга функция начиналась с «if (condition1 && condition2 && condition3) crash ();», которая была именно таким поведением до рефакторинга, только более понятным. Затем я удалил эту строку :-) Вы увидите странное и нежелательное поведение ясно, так что вы можете это исправить. С другой стороны, именно здесь вы должны изменить поведение существующего кода, так что это нужно делать осторожно).
источник
К сожалению, на самом деле вы ничего не можете с этим поделать в момент проверки кода, кроме как получить еще одну чашку кофе. Фактическим решением этой проблемы является решение проблемы технического долга, который вы накопили: хрупкий дизайн, отсутствие тестов. Надеюсь, у вас есть хоть какой-то функциональный QA. Если у вас этого нет, то всегда молитесь за куриные кости.
источник
Если вы не согласны поставлять с ошибочным / неработающим программным обеспечением и исправлять его позже, тогда усилия по V & V ДОЛЖНЫ быть дольше, чем усилия по разработке!
Если существующий код хрупок, то первый вопрос - «стоит ли его менять?» Руководству необходимо решить, является ли стоимость / риск перепроектирования и повторной реализации этого кода больше, чем стоимость / риск исправления шаткой груды мусора. Если он одноразовый, проще всего его исправить. Если в будущем, вероятно, потребуются дополнительные изменения, лучшим решением будет принятие удара сейчас, чтобы избежать большей боли в будущем. Вы должны повышать это с вашим руководством, потому что предоставление вашим менеджерам хорошей информации является частью вашей работы. Они должны принимать это решение, потому что это стратегическое решение, которое выше вашего уровня ответственности.
источник
Исходя из моего опыта, я настоятельно рекомендую вам покрыть ваш код значительным количеством тестов, как модульных, так и интеграционных, ДО того, как будут внесены какие-либо изменения в данную систему. Важно помнить, что в настоящее время существует очень много инструментов для этой цели, неважно, на каком языке вы разрабатываете.
Кроме того, есть инструмент из всех инструментов для создания интеграционных тестов. Да, я говорю о контейнерах и особенно о Docker и Docker Compose . Он прекрасно предоставляет нам способ быстрой настройки сложной среды приложений с инфраструктурой (база данных, mongodb, серверы очередей и т. Д.) И приложениями.
Инструменты доступны, используйте их! :)
источник
Я не знаю, почему это еще не было упомянуто, но эти 2 - самые важные части:
* Пример: вы заменяете библиотеку A библиотекой B. В одном списке изменений представлена библиотека B, различные списки изменений заменяют использование A на B по частям (например, один список изменений на модуль), а последний список изменений удаляет библиотеку A.
источник
Не стоит недооценивать потенциальную ценность ревизий кода. Они могут быть хороши в обнаружении ошибок:
Они также полезны по другим причинам:
В лучшем / идеальном случае прохождение проверки кода означает не просто «никаких очевидных ошибок»: это означает «явно никаких ошибок» (хотя, конечно, вы также захотите это проверить).
Если вы не можете проверить новую базу кода с помощью проверки кода, тогда потребуется более обширное тестирование «черного ящика». Возможно, вы привыкли к циклу разработки, когда вы вводите код в производство после того, как он прошел проверку, но если он не может «пройти проверку», вы не можете «запустить его в производство», и для него требуется более длительный цикл: например, интеграционные тесты системные тесты, альфа-тесты, приемочные тесты, бета-тесты и т. д.
А как насчет интеграционных, системных и приемочных испытаний?
В любом случае, вы, вероятно, должны сказать менеджеру проекта и менеджеру по продукту, что код почти наверняка содержит ошибки с неизвестным количеством ошибок; и что они «получат то, что проверяют» вместо того, чтобы просто «получить то, что ожидают», то есть качество кода не лучше, чем их тестирование (поскольку качество кода не было и не может быть гарантировано проверкой кода) ,
Возможно, им следует передать это сообщение клиенту или пользователям, чтобы они провели бета-тестирование (если они хотят быть первыми пользователями), или используют старую версию, пока новая версия не выйдет из бета-версии (если они этого не делают).
источник
Много кода написано и объединено без надлежащего рассмотрения кода. Это может работать. Есть причина, почему это называется запахом кода, а не «неработающим кодом» или чем-то в этом роде. Отсутствие проверки кода - это предупреждающий знак, а не предвестник гибели.
Решение этой проблемы заключается в том, что не существует единого решения, подходящего для всех случаев, которые мы можем упаковать в ответ в стиле StackExchange. Сообщество разработчиков программного обеспечения твердо придерживается мнения, что проверка кода является критически важной «лучшей практикой», и в этом случае она пропускается. Ваше развитие больше не находится в этом узком канале «следования всем лучшим практикам». Вам нужно будет найти свой путь.
Что такое "лучшая практика" в любом случае? Когда вы приступаете прямо к этому, это набор практик, которые, как обычно думают, делают код лучше. Они делают код правильно? Черт возьми нет! Интернет изобилует историями компаний, которые следовали «передовым методам» и запутались в этом. Возможно, лучшая точка зрения на «лучшие практики» заключается в том, что они являются решениями «запускай и забывай» в мире программного обеспечения. Я ничего не могу знать о вашей компании, вашем проекте, вашей команде и смогу использовать «лучшие практики», которые помогут вам. Это общий совет "не навреди".
Вы явно отклонились от этого плана. К счастью, вы узнаете это. Отличная работа! Они говорят, что знание - это полдела; если это так, осознание - это больше половины! Теперь нужно решение. Из вашего описания становится ясно, что бизнес-среда, в которой вы находитесь, эволюционировала до такой степени, что скучный совет «иди делайте обзор кода, это лучшая практика» не собирается его сокращать. Для этого я рекомендую ключевое правило, которое я использую, когда дело доходит до лучших практик программного обеспечения:
Честно говоря, они платят вашу зарплату, и выживание бизнеса, как правило, гораздо важнее, чем качество программного обеспечения. Мы не хотим признавать это, но идеально написанное программное обеспечение бесполезно, если оно находится в ловушке компании, умирающей от своих усилий по поддержке этого идеально написанного программного обеспечения.
Так куда ты идешь? Следуйте по следу силы. Вы указали, что по какой-то неустановленной причине нецелесообразно проходить проверку кода для какой-либо задачи. По моему опыту, эта причина всегда временна. Это всегда либо «не хватает времени», либо «недостаточно денег, чтобы удерживать зарплаты, пока вы проводите время». Это бизнес; все в порядке. Если бы это было легко, все бы это сделали. Следуйте по пути силы вверх и найдите руководство, способное помочь вам понять, почему проверка кода не возможна. Язык жесткий, и довольно часто указ выскальзывает из высшего руководства и искажается. Решение вашей проблемы может быть скрыто в этом искажении.
Ответом на это, безусловно, является конкретный сценарий. Это все равно что пытаться предсказать, будут ли подбрасывать монеты головы или хвосты. Лучшие практики говорят, что нужно перевернуть его 100 раз, и ожидается, что он будет примерно 50 голов и 50 хвостов, но у вас нет времени перевернуть его 1 раз. Здесь важны детали вашей ситуации. Знаете ли вы, что монета, как правило, приземляется в той же ориентации, с которой ее подбрасывали примерно в 51% случаев? Вы нашли время, чтобы увидеть, как монета была перед броском? Это может иметь значение.
Одно общее решение, которое может быть доступно вам, - это попытаться найти способ затянуть процесс проверки кода и сделать его очень дешевым. Большая часть затрат на процесс проверки кода заключается в том, что каждый на 100% посвящен проверке кода, пока вы этим занимаетесь. Это должно иметь место, потому что, как только обзор кода сделан, код благословен. Возможно, вы можете поместить код в другую ветку и выполнить обзор кода параллельно с разработкой в основной ствол. Или, возможно, вы даже можете настроить его так, чтобы программное обеспечение выполняло тестирование за вас. Может быть, вы находитесь в бизнес-среде, где ваши клиенты могут запускать «новый» код параллельно со старым и заставлять их сравнивать результаты. Это превращает клиентов в набор устройств для создания вариантов использования.
Ключом ко всем этим работающим «майбам» является то, что вы должны стремиться к тому, чтобы ваш код был легко разбит на части. Возможно, вам удастся «доказать» фрагменты кода, не полагаясь на формальную проверку кода, используя их в менее важных проектах. Это легче сделать, если изменения разбиты на мелкие фрагменты, даже если их общая сумма слишком велика для рецензирования.
В общем, ищите решения, специфичные для вашего проекта, вашей компании, вашей команды. Ответ общего назначения был "лучшими методами". Вы не используете их, поэтому на этот раз вам следует искать более индивидуальные решения этой проблемы. Это бизнес. Если бы все прошло так, как мы ожидали, IPO было бы намного проще назначать значения, не так ли!
Если замена проверки кода представляет собой трудную задачу, помните, что никогда не было ни одного фрагмента кода, который, как было доказано, будет работать при проверке кода. * Все, что делает проверка кода, - это дать вам уверенность в коде и возможность внести исправления прежде чем они станут проблемой. Оба этих ценных продукта обзора кода могут быть получены другими способами. Обзор кода просто признан тем, что он особенно хорош в этом.
* Ну, почти: микроядро L4 некоторое время назад получило обзор кода с помощью автоматической системы проверки, которая проверяет, что его код, если он скомпилирован совместимым компилятором C ++, будет делать именно то, что написано в документации.
источник
Как отмечает @EricLippert в своем превосходном ответе, такого рода изменения требуют большего внимания, а не меньшего . Если вы понимаете, что изменение, над которым вы работаете, станет таким изменением, есть несколько стратегий, которые могут помочь:
источник
Другие ответы касаются того, как вы добрались до этой точки. Многие из них дают некоторые предложения, чтобы исправить ситуацию, но я хотел бы добавить свой ответ, чтобы дать краткий ответ.
Что делать, когда проверки кода «слишком сложны»?
да
Вы разработчики были великолепны! Привет всем!
(или для тех, кто не вырос, смотря « Симпсоны » на американском телевидении: если тесты проходят, пропустите попытку взглянуть на различия и попросите разработчика провести вас по изменениям)
нет
Продолжайте рефакторинг и добавляйте тестовое покрытие, пока тесты не пройдут.
источник
Подобно умножению, обзор кода дает нулевой результат при применении к нулю. Это не увеличивает значение в таком случае, в то время как в большинстве других случаев это будет.
Код, с которым вам нужно работать, слишком плохо спроектирован, чтобы извлечь выгоду из процесса проверки кода во время дальнейшей разработки. Используйте процесс проверки кода для рефакторинга или повторной разработки.
Может также случиться так, что код все еще терпим, но задача не является хорошей. Это слишком широко и должно быть сделано в меньших приращениях.
источник