Есть ли какая-то ценность в написании модульных тестов для кода, который уже работает при наследовании приложений?

27

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

Но в некоторых местах, как некоторые вспомогательные методы, которые, вероятно, могут быть модульными, нужно ли мне писать для них модульные тесты?

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

Есть ли какая-то ценность в этом?

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

ROBOSHOP
источник
4
Сделайте себе одолжение и прочитайте « Эффективная работа с устаревшим кодексом» . Это целая книга, посвященная ответам на этот и другие смежные вопросы.
Рейн Хенрикс

Ответы:

15

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

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

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

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

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

Со временем вы создадите набор тестов, которые помогут вам или следующему человеку, унаследовавшему приложение.

Адам Лир
источник
13

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

Винод Р
источник
Напишите тесты на языке высшего уровня, который будет работать. Когда вас попросят оценить время для внесения изменений, укажите время, необходимое для написания отсутствующих тестов. Для внесения изменений может потребоваться больше времени, но в поле будет добавлено гораздо меньше ошибок.
Кевин Клайн
8
 > Is there any value in writing unit tests for code that 
 > already works when inheriting applications?

NO . Исходя из моего опыта, существует плохое соотношение затрат и выгод для написания модульных тестов после написания производственного кода, поскольку весьма маловероятно / трудно найти способы тестирования кода в отдельности без интенсивного рефакторинга. Одним из преимуществ тестовой разработки является то, что вы получаете слабосвязанный код. Если вы напишете тесты впоследствии, высоки шансы, что код тесно связан.

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

ДА с точки зрения качества и разработчика очень важно иметь тесты.

НЕТ с точки зрения бизнеса, потому что очень трудно продать клиенту то, что вам нужно время / деньги, чтобы получить реальную ценность для бизнеса, но смутное обещание, что изменения в бизнесе не сделают ситуацию хуже.

k3b
источник
+1 для интеграционных тестов, а не юнит-тест для этого случая. Очень прагматичный совет
gbjbaanb
5

Если это вообще возможно, есть еще больше оснований для написания тестов для существующего кода, который «уже работает». Если тестов нет, скорее всего, код полон запахов и может быть улучшен путем рефакторинга; тестовый набор поможет вам провести рефакторинг. Это может даже показать, что оригинальный код не работает должным образом; Я помню, как однажды я написал тест для метода, генерирующего отчет о продажах, и обнаружил, что он не рассчитывает вещи должным образом, поэтому продажи были на несколько тысяч долларов больше, чем они были на самом деле, и никто не знал, что за пять лет этот код находился в производстве. (К счастью, это был не фактический финансовый результат, а оценка продаж).

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

Уэйн Молина
источник
Зачем понижать голос за правду?
Уэйн Молина
4

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

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

Итак, напишите все тестовые модули, которые вы можете. Для кода, который не может быть протестирован, проведите рефакторинг своего кода для разделения зависимостей, введя «швы» в код - места, где вы можете отделить код, который вы хотите протестировать, от кода, который вы не хотите тестировать.

Идеи модульных тестов, таких как тесты характеристик и швы, являются главными в книге Майкла Фезерса « Эффективная работа с устаревшим кодом », которую я очень рекомендую.

Мэтью Родатус
источник
2

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

Вы делаете тонкое замечание:

Должен ли я беспокоиться о модульном тестировании, только если я скажу, что его нужно перефакторинг, или я должен написать для них модульные тесты, когда у меня есть время?

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

когда у меня есть время?

У вас есть время, когда это расставляется по приоритетам, верно? :)

Майкл
источник
1

Вы пытаетесь использовать аспекты этой кодовой базы, которые ранее не использовались в производственном приложении? Сначала напишите модульные тесты для этих сценариев. Вы должны быть в состоянии расставить приоритеты в своей работе здесь, и я думаю, что у Art of Unit Testing есть несколько советов в этом отношении (в частности, как подходить к тестированию устаревших кодовых баз).

Джастин Саймон
источник
1

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

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

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

Дейв ДюПлантис
источник
0

От всего сердца я скажу «да», и не только это, но и взломайте, проведите рефакторинг и продолжайте тестирование, но убедитесь, что вы не отстаете в других важных проектах. Как работающий программист, если ваша работа находится под угрозой или если менеджер сказал вам, чтобы стать владельцем, тогда да. Если команда или компания могут пострадать, поговорите с вашим менеджером, чтобы сообщить ему, что необходимо провести тестирование, чтобы предотвратить катастрофу компании. Если он говорит, не волнуйтесь, значит, вы не в курсе (не обязательно, делегирование обвинений - это управленческий навык, поэтому убедитесь, что вы не в курсе ... на самом деле!)

Удачи!

Armando
источник