Я считаю, что тесты гораздо сложнее и сложнее написать, чем сам код, который они тестируют. Для меня нередко тратить больше времени на написание теста, чем на код, который он тестирует.
Это нормально или я что-то не так делаю?
Вопросы « Стоит ли модульное тестирование или разработка через тестирование? « Мы тратим больше времени на внедрение функционального тестирования, чем на внедрение самой системы, это нормально? И их ответы больше о том, стоит ли тестирование (как в «мы должны вообще пропустить написание тестов?»). Хотя я убежден, что тесты важны, мне интересно, нормально ли я трачу больше времени на тесты, чем реальный код, или это только я.
Судя по количеству просмотров, ответов и откликов на мой вопрос, я могу лишь предположить, что это законная проблема, которая не рассматривается ни на одном другом вопросе на сайте.
источник
Ответы:
Из курса разработки программного обеспечения я помню, что один тратит ~ 10% времени на разработку нового кода, а другие 90% занимаются отладкой, тестированием и документацией.
Поскольку модульные тесты фиксируют отладку и тестирование в (потенциально автоматизируемом) коде, было бы разумно, чтобы в них было вложено больше усилий; фактическое время не должно быть намного больше, чем отладка и тестирование, которые бы обходились без написания тестов.
Наконец тесты также должны быть удвоены как документация! Нужно написать юнит-тесты так, как предназначен код; то есть тесты (и использование) должны быть простыми, помещать сложные вещи в реализацию.
Если ваши тесты сложно написать, то код, который они тестируют, вероятно, трудно использовать!
источник
Это.
Даже если вы проходите только модульное тестирование, вполне обычно иметь больше кода в тестах, чем фактически протестированный код. В этом нет ничего плохого.
Рассмотрим простой код:
Какие будут тесты? Здесь есть как минимум четыре простых случая для тестирования:
Имя людей
null
. Действительно ли выброшено исключение? Это как минимум три строки тестового кода для написания.Имя людей
"Jeff"
. Мы получаем"Hello, Jeff!"
в ответ? Это четыре строки тестового кода.Имя человека - пустая строка. Какой выход мы ожидаем? Каков фактический результат? Дополнительный вопрос: соответствует ли он функциональным требованиям? Это означает еще четыре строки кода для модульного теста.
Имя человека достаточно короткое для строки, но слишком длинное, чтобы его можно было объединить с
"Hello, "
восклицательным знаком. Что происходит?Это требует много тестирования кода. Более того, для самых элементарных фрагментов кода часто требуется установочный код, который инициализирует объекты, необходимые для тестируемого кода, что также часто приводит к написанию заглушек и макетов и т. Д.
Если соотношение очень большое, в этом случае вы можете проверить несколько вещей:
Есть ли дублирование кода в тестах? Тот факт, что это тестовый код, не означает, что код должен дублироваться (копироваться) между аналогичными тестами: такое дублирование усложнит обслуживание этих тестов.
Есть ли лишние тесты? Как правило, если вы удалите юнит-тест, охват ветвления должен уменьшиться. Если это не так, это может означать, что тест не нужен, поскольку пути уже охвачены другими тестами.
Вы тестируете только тот код, который вам нужно протестировать? От вас не требуется тестировать базовую структуру сторонних библиотек, а исключительно код самого проекта.
С помощью тестов дыма, системных и интеграционных тестов, функциональных и приемочных тестов, а также нагрузочных и нагрузочных тестов вы добавляете еще больше тестового кода, поэтому вам не стоит беспокоиться о наличии четырех или пяти LOC тестов для каждого LOC реального кода.
Примечание о TDD
Если вас беспокоит время, необходимое для тестирования кода, возможно, вы делаете это неправильно, то есть сначала код, потом тесты. В этом случае TDD может помочь, поощряя вас работать с итерациями по 15-45 секунд, переключаясь между кодом и тестами. По словам сторонников TDD, он ускоряет процесс разработки, сокращая как количество тестов, которые вам необходимо выполнить, так и, что более важно, количество бизнес-кода, которое нужно написать, и особенно переписать для тестирования.
¹ Пусть n будет максимальной длиной строки . Мы можем вызвать
SayHello
и передать по ссылке строку длины n - 1, которая должна работать очень хорошо. Теперь наConsole.WriteLine
шаге форматирование должно заканчиваться строкой длиной n + 8, что приведет к исключению. Возможно, из-за ограничений памяти даже строка, содержащая n / 2 символов, приведет к исключению. Вопрос, который следует задать, заключается в том, является ли этот четвертый тест модульным тестом (он похож на него, но может иметь гораздо более высокий эффект с точки зрения ресурсов по сравнению со средними модульными тестами) и проверяет ли он реальный код или базовую структуру.источник
personName
соответствует astring
, но значениеpersonName
плюс объединенные значения переполняетсяstring
.As a rule of thumb, if you remove a unit test, the branch coverage should decrease.
Если я напишу все четыре теста, которые вы упомянули выше, а затем уберу третий тест, уменьшится ли покрытие?Я думаю, что важно различать два типа стратегий тестирования: модульное тестирование и интеграционное / приемочное тестирование.
Хотя модульное тестирование необходимо в некоторых случаях, оно часто безнадежно переутомлено. Это усугубляется бессмысленными метриками, навязываемыми разработчикам, такими как «100% охват». http://www.rbcs-us.com/documents/Why-Most-Unit-Testing-is-Waste.pdf предоставляет убедительные аргументы для этого. Рассмотрим следующие проблемы с агрессивным юнит-тестированием:
Интеграционное / приемочное тестирование, с другой стороны, является чрезвычайно важной частью качества программного обеспечения, и, по моему опыту, вы должны потратить значительное количество времени на то, чтобы сделать их правильными.
Многие магазины выпили kool-помощь TDD, но, как показывает ссылка выше, ряд исследований показывает, что его польза неубедительна.
источник
.equals()
методы, сгенерированные Eclipse». Я написал тестовый набор дляequals()
иcompareTo()
github.com/GlenKPeterson/TestUtils. Практически в каждой реализации, которую я когда-либо тестировал, не хватало. Как вы используете коллекции, еслиequals()
иhashCode()
не работаете вместе правильно и эффективно? Я снова болею за ваш остальной ответ и проголосовал за него. Я даже допускаю, что некоторые автоматически сгенерированные методы equals () могут не нуждаться в тестировании, но у меня было так много ошибок с плохими реализациями, что это заставляет меня нервничать.Не может быть обобщено.
Если мне нужно реализовать формулу или алгоритм, основанный на физическом рендеринге, вполне возможно, что я потрачу 10 часов на параноидальные юнит-тесты, так как знаю, что малейшая ошибка или неточность могут привести к ошибкам, которые почти невозможно диагностировать, спустя месяцы ,
Если я просто хочу логически сгруппировать несколько строк кода и дать ему имя, используемое только в области видимости файла, я могу вообще не тестировать его (если вы настаиваете на написании тестов для каждой функции без исключения, программисты могут отступить чтобы написать как можно меньше функций).
источник
Да, это нормально, если вы говорите о TDDing. Когда у вас есть автоматизированные тесты, вы обеспечиваете желаемое поведение вашего кода. Когда вы сначала пишете свои тесты, вы определяете, имеет ли уже существующий код желаемое поведение.
Это значит, что:
(Это не учитывает рефакторинг кода, который направлен на то, чтобы тратить меньше времени на написание последующего кода. Он уравновешивается рефакторингом тестов, который направлен на то, чтобы тратить меньше времени на написание последующих тестов.)
Да, если вы говорите о написании тестов после факта, вы будете тратить больше времени:
Чем вы действительно потратите на написание кода.
Так что да, это ожидаемая мера.
источник
Я считаю, что это самая важная часть.
Модульное тестирование не всегда связано с «проверкой правильности работы», а с обучением. Как только вы что-то тестируете достаточно, это становится «жестко запрограммированным» в вашем мозгу, и вы, в конечном счете, сокращаете время своего юнит-тестирования и можете писать целые классы и методы, ничего не тестируя, пока не закончите.
Вот почему в одном из других ответов на этой странице упоминается, что на «курсе» они провели 90% тестирования, потому что каждый должен был изучить предостережения своей цели.
Модульное тестирование - это не только очень ценное использование вашего времени, поскольку оно буквально улучшает ваши навыки, это хороший способ снова просмотреть свой собственный код и найти логическую ошибку на этом пути.
источник
Это может быть для многих людей, но это зависит.
Если вы пишете тесты в первую очередь (TDD), вы можете испытывать некоторое дублирование во времени, потраченном на написание теста, который на самом деле полезен для написания кода. Рассмотреть возможность:
При написании тестов после написания кода вы можете обнаружить, что ваш код нелегко тестировать, поэтому написание тестов сложнее / занимает больше времени.
Большинство программистов пишут код намного дольше, чем тесты, поэтому я ожидаю, что большинство из них будут не так бегло. Кроме того, вы можете добавить время, необходимое для понимания и использования вашей инфраструктуры тестирования.
Я думаю, что нам нужно изменить свое мышление о том, сколько времени занимает код и как проводится модульное тестирование. Никогда не смотрите на это в краткосрочной перспективе и никогда не сравнивайте общее время для предоставления определенной функции, потому что вы должны учитывать не только то, что вы пишете код лучше / меньше глючных, но и код, который легче изменить, и при этом сделать его лучше / меньше глючит.
В какой-то момент мы все способны писать только такой хороший код, поэтому некоторые инструменты и методики могут предложить только так много для улучшения наших навыков. Я не смог бы построить дом, если бы у меня была только лазерная пила.
источник
Да, это. С некоторыми оговорками.
Прежде всего, это «нормально» в том смысле, что большинство крупных магазинов работают таким образом, поэтому, даже если этот путь был полностью ошибочным и глупым, тем не менее, тот факт, что большинство крупных магазинов работают таким образом, делает его «нормальным».
Под этим я не подразумеваю, что тестирование это неправильно. Я работал в средах без тестирования и в средах с обсессивно-компульсивным тестированием, и я все еще могу сказать вам, что даже обсессивно-компульсивное тестирование было лучше, чем отсутствие тестирования.
И я пока не делаю TDD (кто знает, возможно, в будущем), но я делаю подавляющее большинство циклов редактирования-запуска-отладки, выполняя тесты, а не само приложение, поэтому, естественно, я много работаю на моих тестах, чтобы избежать, насколько это возможно, необходимости запуска фактического приложения.
Однако следует помнить, что при чрезмерном тестировании существуют опасности, особенно в отношении количества времени, затрачиваемого на поддержание тестов. (Я прежде всего пишу этот ответ, чтобы конкретно указать на это.)
В предисловии Роя Ошерова « Искусство модульного тестирования» (Мэннинг, 2009) автор признается, что участвовал в проекте, который в значительной степени потерпел неудачу из-за огромного бремени разработки, налагаемого плохо разработанными модульными тестами, которые должны были поддерживаться на протяжении всего длительность разработки. Таким образом, если вы обнаружите, что тратите слишком много времени, не делая ничего, кроме поддержания своих тестов, это не обязательно означает, что вы находитесь на правильном пути, потому что это «нормально». Возможно, ваши усилия по разработке вошли в нездоровый режим, где радикальное переосмысление вашей методики тестирования может быть необходимо для сохранения проекта.
источник
источник