Предположим, у кого-то была относительно большая программа (скажем, 900k SLOC на C #), все тщательно прокомментированы / задокументированы, хорошо организованы и работают хорошо. Вся база кода была написана одним старшим разработчиком, который больше не работает в компании. Весь код тестируется как есть, и IoC используется повсеместно - за исключением какой-то странной причины, они не написали никаких модульных тестов. Теперь ваша компания хочет разветвить код и хочет добавить модульные тесты, чтобы определить, когда изменения нарушают основные функции.
- Является ли добавление тестов хорошей идеей?
- Если так, то как можно начать что-то подобное?
РЕДАКТИРОВАТЬ
Хорошо, поэтому я не ожидал ответов, дающих хорошие аргументы для противоположных выводов. В любом случае, проблема может быть не в моих руках. Я также прочитал «дублирующие вопросы», и общее мнение таково, что «написание тестов - это хорошо» ... да, но не слишком полезно в данном конкретном случае.
Я не думаю, что я одинок в рассмотрении написания тестов для устаревшей системы. Я собираюсь сохранить метрики о том, сколько времени потрачено и сколько раз новые тесты обнаруживают проблемы (и сколько раз они этого не делают). Я вернусь и обновлю это через год или около того с моими результатами.
ЗАКЛЮЧЕНИЕ
Таким образом, оказывается, что в принципе невозможно просто добавить модульный тест в существующий код с каким-либо подобием ортодоксальности. Когда код работает, вы, очевидно, не можете красный / зеленый свет ваших тестов, обычно не ясно, какое поведение важно проверить, не ясно, с чего начать и, конечно, не ясно, когда вы закончите. Действительно, даже задавая этот вопрос, в первую очередь упускается суть написания тестов. В большинстве случаев я обнаружил, что на самом деле проще переписать код с использованием TDD, чем расшифровывать предназначенные функции и задним числом добавлять их в модульные тесты. Исправление проблемы или добавление новой функции - это отдельная история, и я считаю, что сейчас самое время добавить юнит-тесты (как указано ниже). В конце концов, большая часть кода переписывается, часто раньше, чем вы ожидаете - используя этот подход, я
источник
Ответы:
Хотя тесты и являются хорошей идеей, первоначальный кодер намеревался создать их, поскольку он собирал приложение, чтобы получить знания о том, как должен работать код и что может сломаться, что затем было бы передано вам.
При таком подходе высока вероятность того, что вы будете писать тесты, которые с наименьшей вероятностью сломаются, и пропустите большинство крайних случаев, которые были бы обнаружены при создании приложения.
Проблема заключается в том, что большую часть ценности принесут эти «ошибки» и менее очевидные ситуации. Без этих тестов набор тестов теряет практически всю свою эффективность. Кроме того, у компании будет ложное чувство безопасности в отношении их приложения, поскольку это не будет значительно более регрессивным доказательством.
Обычно способ обработки этого типа кодовой базы состоит в написании тестов для нового кода и рефакторинга старого кода до тех пор, пока устаревшая кодовая база не будет полностью реорганизована.
Также см .
источник
Да, добавление тестов, безусловно, хорошая идея.
Вы говорите, что это хорошо задокументировано, и это ставит вас в хорошее положение. Попробуйте создать тесты, используя эту документацию в качестве руководства, ориентируясь на части системы, которые являются либо критическими, либо подверженными частым изменениям.
Первоначально, огромный размер кодовой базы, вероятно, будет подавляющим по сравнению с крошечным количеством тестов, но подход большого взрыва не существует, и начинать с чего- то важнее, чем мучиться с тем, какой будет лучший подход.
Я бы порекомендовал книгу Майкла Фезерса « Эффективная работа с унаследованным кодом» за несколько полезных подробных советов.
источник
Не все модульные тесты имеют одинаковую выгоду. Преимущество юнит-теста приходит, когда оно не проходит. Чем меньше вероятность его провала, тем менее он выгоден. Новый или недавно измененный код, скорее всего, будет содержать ошибки, чем редко измененный код, который хорошо протестирован в производстве. Поэтому модульные тесты для нового или недавно измененного кода, скорее всего, будут более полезными.
Не все юнит-тесты имеют одинаковую стоимость. Намного проще выполнить модульное тестирование тривиального кода, который вы разработали сегодня, чем сложный код, созданный кем-то давно. Кроме того, тестирование во время разработки обычно экономит время разработки. На устаревшем коде эта экономия больше недоступна.
В идеальном мире у вас было бы все время для юнит-тестирования унаследованного кода, но в реальном мире в какой-то момент можно предположить, что затраты на добавление юнит-тестов в унаследованный код перевесят преимущества. Хитрость заключается в том, чтобы определить эту точку. Ваш контроль версий может помочь, показывая вам последний измененный и наиболее часто изменяемый код, и вы можете начать с проверки его на модульный тест. Кроме того, когда вы вносите изменения в будущем, поместите эти изменения и тесно связанный код в модульное тестирование.
Следуя этому методу, в конечном итоге у вас будет довольно хорошее освещение в самых выгодных областях. Если вместо этого вы проводите месяцы, проводя модульные тесты, прежде чем возобновить приносящую доход деятельность, это может быть желательным решением по обслуживанию программного обеспечения, но это паршивое бизнес-решение.
источник
Безусловно, хотя мне трудно поверить, что код чистый и работает хорошо, использует современные методы и просто не имеет модульных тестов. Вы уверены, что они не сидят в отдельном решении?
В любом случае, если вы собираетесь расширять / поддерживать код, то истинные модульные тесты неоценимы для этого процесса.
Один шаг за раз. Если вы не знакомы с модульным тестированием, то учитесь немного. Как только вы освоитесь с концепциями, выберите один небольшой раздел кода и напишите для него тесты. Затем следующий и следующий. Покрытие кода может помочь вам найти места, которые вы пропустили.
Вероятно, лучше сначала выбрать опасные / рискованные / жизненно важные вещи для тестирования, но вам может быть более эффективно тестировать что-то прямолинейное, чтобы сначала попасть в паз, особенно если вы / команда не привыкли к кодовой базе и / или модулю тестирование.
источник
Да, иметь тесты это хорошая идея. Они помогут задокументировать существующую кодовую базу, работающую по назначению, и уловить любое непредвиденное поведение. Даже если тесты изначально не пройдены, разрешите их, а затем выполните рефакторинг кода, чтобы он прошел и вел себя так, как задумано.
Начните писать тесты для небольших классов (те, которые не имеют зависимостей и являются относительно простыми) и переходите к более крупным классам (те, которые имеют зависимости и являются более сложными). Это займет много времени, но будьте терпеливы и настойчивы, чтобы в конечном итоге вы могли охватить как можно больше кода.
источник
Хорошо, я собираюсь дать противоположное мнение ....
Добавление тестов к существующей работающей системе приведет к изменению этой системы, если только это не делается с самого начала, когда система написана с насмешкой. Я сомневаюсь в этом, хотя вполне возможно, что он имеет хорошее разделение всех компонентов с легко определяемыми границами, в которые вы можете вставить свои фиктивные интерфейсы. Но если это не так, то вам придется внести довольно существенные (условно говоря) изменения, которые вполне могут сломать вещи. В лучшем случае вы потратите кучу времени на написание этих тестов, а лучше время, потраченное на написание множества подробных проектных документов, документов анализа влияния или документов конфигурации решения. В конце концов, это работа, которую ваш босс хочет сделать больше, чем модульные тесты. Не так ли?
Во всяком случае, я бы не стал добавлять какие-либо юнит-тесты вообще.
Я бы сконцентрировался на внешних, автоматизированных инструментах тестирования, которые дадут вам разумный охват, ничего не меняя. Затем, когда вы приходите вносить изменения ... тогда вы можете начинать добавлять модульные тесты внутри кодовой базы.
источник
Я часто сталкивался с этой ситуацией, унаследовал большую кодовую базу без адекватного тестирования или без него, и теперь я отвечаю за добавление функций, исправление ошибок и т. Д.
Мой совет - убедиться в том, что вы добавляете, и проверить, а если вы исправите ошибки или измените варианты использования в текущем коде, тогда автор проверяет. Если вам нужно что-то трогать, напишите тесты на этом этапе.
Когда это ломается, это когда существующий код плохо структурирован для модульного тестирования, поэтому вы тратите много времени на рефакторинг, чтобы вы могли добавлять тесты для незначительных изменений.
источник