Я - индивидуальный разработчик с довольно ограниченной рабочей средой, где время разработки обычно колеблется от 1-4 недель на проект, в зависимости от требований, срочности или того и другого. В любой момент времени я занимаюсь примерно 3-4 проектами, некоторые из которых имеют временные рамки, которые пересекаются друг с другом.
Как ожидается, качество кода страдает. У меня также нет официального тестирования; это обычно сводится к тому, чтобы пройти через систему, пока она не сломается. В результате в производство попадает значительное количество ошибок, которые я должен исправить, что, в свою очередь, мешает другим моим проектам.
Вот где начинается модульное тестирование. Когда все сделано правильно, оно должно сводить к минимуму ошибки, не говоря уже о тех, которые уходят в производство. С другой стороны, написание тестов может занять значительное количество времени, что не очень хорошо для таких ограниченных во времени проектов, как мой.
Вопрос в том, сколько разницы во времени будет писать проверенный модулем код поверх непроверенного кода, и как эта разница во времени масштабируется по мере расширения области проекта?
источник
Ответы:
Чем позже вы тестируете, тем больше стоит писать тесты.
Чем дольше живет ошибка, тем дороже ее исправить.
Закон убывающей отдачи гарантирует, что вы можете испытать себя в забвении, стараясь не допустить ошибок.
Будда учил мудрости среднего пути. Тесты хорошие. Есть такая вещь, как слишком много хорошего. Ключ в состоянии сказать, когда вы вышли из равновесия.
Каждая строка кода, которую вы пишете без тестов, будет значительно дороже добавлять тесты позже, чем если бы вы написали тесты до написания кода.
Каждая строка кода без тестов будет значительно сложнее отлаживать или переписывать.
Каждый тест, который вы напишите, займет время.
Каждая ошибка займет время, чтобы исправить.
Верующие скажут вам не писать ни единой строки кода, не написав сначала провальный тест. Тест гарантирует, что вы получаете ожидаемое поведение. Это позволяет быстро изменять код, не беспокоясь о влиянии на остальную часть системы, поскольку тест подтверждает то же поведение.
Вы должны сопоставить все это с тем фактом, что тесты не добавляют функций. Производственный код добавляет функции. И особенности - это то, что оплачивает счета.
Прагматично говоря, я добавляю все тесты, с которыми я могу справиться. Я игнорирую комментарии в пользу просмотра тестов. Я даже не доверяю коду делать то, что думаю. Я доверяю тестам. Но я был известен тем, что иногда бросал град Мэри и получал счастье.
Однако многие успешные кодеры не используют TDD. Это не значит, что они не тестируют. Они просто не настаивают на том, чтобы каждая строка кода имела автоматизированный тест. Даже дядя Боб признает, что не проверяет свой интерфейс. Он также настаивает на том, чтобы вы удалили всю логику из пользовательского интерфейса.
В качестве футбольной метафоры (это американский футбол) TDD - хорошая наземная игра. Только ручное тестирование, где вы пишете кучу кода и надеетесь, что это сработает, является проходной игрой. Вы можете быть хорошими в любом. Ваша карьера не попадет в плей-офф, если вы не сделаете оба. Это не сделает суперкубок, пока вы не научитесь выбирать каждый из них. Но если вам нужно подтолкнуть в определенном направлении: официальные звонки идут против меня чаще, когда я прохожу.
Если вы хотите попробовать TDD, я настоятельно рекомендую вам попрактиковаться, прежде чем пытаться делать это на работе. TDD сделали наполовину, наполовину нерешительно, а наполовину задницу - большая причина, почему некоторые не уважают это. Это все равно, что налить один стакан воды в другой. Если вы не совершаете и делаете это быстро и полностью, вы в конечном итоге даете воду по всему столу.
источник
Я согласен с остальными ответами, но чтобы ответить на вопрос о разнице во времени напрямую.
Рой Ошеров в своей книге «Искусство модульного тестирования, второе издание», стр. 200, рассмотрел пример реализации проектов одинакового размера с похожими командами (по навыкам) для двух разных клиентов, где одна команда проводила тестирование, а другая - нет.
Его результаты были такими:
Таким образом, в конце проекта вы получаете меньше времени и меньше ошибок. Это, конечно, зависит от того, насколько большой проект.
источник
Есть только одно исследование, которое я знаю, которое изучало это в «реальных условиях»: достижение улучшения качества посредством разработки, основанной на тестировании: результаты и опыт четырех промышленных групп . Это разумно дорого, поскольку в основном это означает, что вам нужно разрабатывать одно и то же программное обеспечение дважды (или в идеале даже чаще) с аналогичными командами, а затем выбрасывать все, кроме одного.
Результатами исследования стали увеличение времени разработки на 15–35% (что далеко не соответствует 2-кратному значению, которое часто цитируют критики TDD), а также снижение плотности дефектов перед выпуском с 40% до 90% (! ). Обратите внимание, что у всех команд не было предшествующего опыта работы с TDD, поэтому можно предположить, что увеличение времени может, по крайней мере, частично объясняться обучением, и, таким образом, со временем будет снижаться, но это не было оценено в исследовании.
Обратите внимание, что это исследование о TDD, а ваш вопрос о модульном тестировании, это очень разные вещи, но это самое близкое, что я смог найти.
источник
null
, функционально над императивом, контракты кода, статический анализ, автоматический рефакторинг, нет IoC-контейнеров (кроме DI) и т. Д. Бьюсь об заклад, что это значение модульных тестов уменьшится (но не исчезнет).Если все сделано хорошо, разработка с помощью модульных тестов может быть быстрее, даже без учета преимуществ, связанных с обнаружением дополнительных ошибок.
Дело в том, что я не достаточно хороший кодер, чтобы просто заставить мой код работать, как только он скомпилируется. Когда я пишу / изменяю код, я должен запустить код, чтобы убедиться, что он делает то, что, как я думал, он делает. В одном проекте это выглядело как:
И, конечно же, после всего этого обычно требовалось несколько поездок в оба конца, чтобы понять это правильно.
А что если я использую модульные тесты? Тогда процесс выглядит больше как:
Это проще и быстрее, чем тестирование приложения вручную. Мне все еще приходится вручную запускать приложение (поэтому я не выгляжу глупо, когда я превращаюсь в работу, которая на самом деле не работает вообще), но по большей части я уже отработал изломы, и я просто проверка в этот момент. На самом деле я обычно делаю этот цикл еще теснее, используя программу, которая автоматически перезапускает мои тесты при сохранении.
Однако это зависит от работы в удобной для тестирования кодовой базе. Многие проекты, даже те, которые имеют много тестов, затрудняют написание тестов. Но если вы работаете над этим, у вас может быть база кода, которую проще тестировать с помощью автоматических тестов, чем с помощью ручного тестирования. В качестве бонуса вы можете использовать автоматические тесты и продолжать их, чтобы предотвратить регрессию.
источник
Несмотря на то, что ответов уже много, они несколько повторяются, и я хотел бы пойти другим путем. Модульные тесты полезны тогда и только тогда , когда они повышают ценность бизнеса . Тестирование ради тестирования (тривиальные или тавтологические тесты) или попадания в какую-то произвольную метрику (например, покрытие кода) - это грубо-культовое программирование.
Тесты стоят дорого, не только во время их написания, но и в обслуживании. Они должны быть синхронизированы с кодом, который они тестируют, или они бесполезны. Не говоря уже о затратах времени на их запуск при каждом изменении. Это не нарушает условия сделки (или оправдывает неисполнение действительно необходимых), но должно учитываться при анализе затрат и выгод.
Таким образом, вопрос, который нужно задать, решая, следует ли (или какого рода) тестировать функцию / метод, задайте себе вопрос: «Какую ценность для конечного пользователя я создаю / защищаю этим тестом?». Если вы не можете ответить на этот вопрос, не покладая рук , то этот тест, скорее всего, не стоит затрат на написание / сопровождение. (или вы не понимаете проблемную область, которая является гораздо более серьезной проблемой, чем отсутствие тестов).
http://rbcs-us.com/documents/Why-Most-Unit-Testing-is-Waste.pdf
источник
Это зависит от человека, а также от сложности и формы кода, с которым вы работаете.
Для меня в большинстве проектов написание модульных тестов означает, что я выполняю работу примерно на 25% быстрее. Да, даже включая время, чтобы написать тесты.
Дело в том, что когда вы пишете код , программное обеспечение не готово . Это делается, когда вы отправляете его клиенту, и он им доволен. Модульные тесты - безусловно, самый эффективный способ, которым я знаю, чтобы отловить большинство ошибок, изолировать большинство ошибок для отладки и получить уверенность в том, что код хорош. Вы должны делать те вещи , в любом случае , так что их хорошо.
источник
Проблема усугубляется с возрастом проекта: потому что всякий раз, когда вы добавляете новые функциональные возможности и / или всякий раз, когда вы реорганизуете существующую реализацию, вы должны повторно протестировать то, что было ранее протестировано, чтобы убедиться, что оно все еще работает. Таким образом, для долгосрочного (многолетнего) проекта вам может потребоваться не только протестировать функциональность, но и повторно протестировать ее 100 и более раз. По этой причине вы можете воспользоваться автоматизированными тестами. Тем не менее, IMO достаточно (или даже лучше), если это автоматические системные тесты, а не автоматические модульные тесты.
Вторая проблема заключается в том, что ошибки могут быть труднее найти и исправить, если они не были обнаружены раньше. Например, если в системе есть ошибка, и я знаю, что она работала отлично до того, как вы внесли свое последнее изменение, тогда я сконцентрирую свое внимание на вашем последнем изменении, чтобы посмотреть, как это могло привести к появлению ошибки. Но если я не знаю, что система работала до того, как вы сделали ваше последнее изменение (потому что система не была должным образом протестирована до вашего последнего изменения), тогда ошибка может быть где угодно.
Вышесказанное относится, в частности, к глубокому коду и, в меньшей степени, к мелкому коду, например, при добавлении новых веб-страниц, где новые страницы вряд ли повлияют на существующие страницы.
По моему опыту это было бы неприемлемо, и поэтому вы задаете не тот вопрос. Вместо того, чтобы спрашивать, будут ли тесты ускорять разработку, вы должны спросить, что сделает разработку более безошибочной.
Лучший вопрос может быть:
Обучение - это двухэтапный процесс: научитесь делать это достаточно хорошо, а затем научитесь делать это быстрее.
источник
Некоторые аспекты, которые следует учитывать, не упомянуты в других ответах.
Резюме
Начиная с tdd, трудно достичь состояния «больше выгоды, чем затрат», если вы находитесь в «ограниченной рабочей среде», особенно если есть «умные менеджеры», которые говорят вам «избавиться от дорогого, бесполезного тестирование "
Примечание: под «модульным тестированием» я подразумеваю «модули тестирования в изоляции».
Примечание: под «регрессионным тестированием» я имею в виду
источник
Программисты, как и люди, занимающиеся большинством задач, недооценивают, сколько времени на самом деле требуется для их выполнения. Имея это в виду, можно потратить 10 минут на написание теста как на время, потраченное на написание тонны кода, хотя на самом деле вы бы потратили время на то, чтобы придумать то же имя функции и параметры, что и во время теста. , Это сценарий TDD.
Не писать тесты, очень похоже на кредитную карту; мы склонны тратить больше или писать больше кода. Больше кода имеет больше ошибок.
Вместо того, чтобы принимать решение о полном покрытии кода или его отсутствии вообще, я предлагаю сосредоточиться на критической и сложной части вашего приложения и провести там тесты. В банковском приложении это может быть расчет процентов. Инструмент диагностики двигателя может иметь сложные протоколы калибровки. Если вы работали над проектом, вы, вероятно, знаете, что это такое и где ошибки.
Начни медленно. Построй беглость, прежде чем судить. Вы всегда можете остановиться.
источник
Совет программистов продвигал TDD и другие методологии тестирования уже давно, я не буду вспоминать их аргументы и соглашаться с ними, но здесь следует учесть дополнительные моменты, которые должны немного нюансировать:
Я бы сказал, что тестирование это хорошо, но убедитесь, что вы тестируете рано и проверяете, где выигрыш.
источник
mainTest()
которая вызывает все ваши тестовые модули, не так уж сложно.Часто упускаемое преимущество TDD заключается в том, что тесты служат гарантией того, что вы не вносите новые ошибки при внесении изменений.
Подход TDD, несомненно, поначалу отнимает больше времени, но суть в том, что вы напишите меньше кода, а значит, будет меньше ошибок. Все эти навороты, которые вы часто включаете, как само собой разумеющееся, не попадут в основу кода.
В фильме «Рыба-меч» есть сцена, в которой, если память не изменяет, хакеру приходится работать с пистолетом в голове и быть… ну, отвлекаться. Дело в том, что намного легче работать, когда ваше свободное место занято в коде, и у вас есть время на стороне, а не месяцы, когда клиент кричит на вас, а другие приоритеты сжимаются.
Разработчики понимают, что исправление ошибок позже обходится дороже, но переверните это с ног на голову. Если бы вам платили 500 долларов в день за кодирование того, как вы кодируете сейчас, или 1000 долларов, если вы написали в стиле TDD, вы бы оторвали руку от человека, который сделал вам второе предложение. Чем раньше вы перестанете воспринимать тестирование как рутинную работу и увидите, что это экономит деньги, тем лучше для вас.
источник
Я могу сослаться на ваш опыт - наша кодовая база почти не имела тестов и была в основном непроверенной. На разработку чего-то ушли буквально целые века, а исправление ошибок в продуктах заняло драгоценное время из-за новых функций.
Для частичной переписки я пообещал написать тесты для всех основных функций. Вначале это заняло значительно больше времени, и моя производительность заметно снизилась, но впоследствии моя производительность была лучше, чем когда-либо прежде.
Частично это улучшение заключалось в том, что у меня было меньше производственных ошибок, что, в свою очередь, приводило к меньшему количеству прерываний -> У меня была лучшая концентрация в любой момент времени.
Более того, способность тестировать И отлаживать код в отдельности действительно окупается - набор тестов значительно превосходит систему, которую нельзя отлаживать, кроме как с помощью ручной настройки, например, запуска вашего приложения и перехода к экрану и выполнения чего-либо ... возможно несколько десятков раз
Но обратите внимание, что в начале наблюдается снижение производительности, поэтому начните изучать тестирование в каком-то проекте, где временное давление еще не безумно. Кроме того, попробуйте запустить его в новом проекте, юнит-тестирование унаследованного кода очень сложно, и это помогает, когда вы знаете, как выглядит хороший набор тестов.
источник
Просто чтобы дополнить предыдущие ответы: помните, что тестирование не является самоцелью. Целью создания тестов является то, что ваше приложение будет вести себя так, как ожидается в процессе эволюции, в неожиданных контекстах и т. Д.
Следовательно, написание тестов не означает доказывать все поведения всех конечных точек объекта. Это распространенная ошибка. Многие разработчики считают, что им нужно протестировать все функции / объекты / методы / свойства / и т. Д. Это приводит к высокой рабочей нагрузке и куче неактуального кода и тестов. Этот подход распространен в больших проектах, где большинство разработчиков не знают о целостном поведении, а видят только свою область взаимодействия.
Правильный подход при работе с редкими ресурсами и тестированием довольно очевиден и имеет здравый смысл, но обычно не формализован: сначала инвестируйте ресурсы для разработки тестирования в функциональные возможности высокого уровня и постепенно переходите к специфике . Это означает, что в какой-то момент, будучи разработчиком-одиночкой, вы сосредоточитесь не только на модульном тестировании, но и на функционале / интеграции / и т. Д. Тестирование и, в зависимости от ваших временных ресурсов, постепенно в основные унитарные функции, как вы планировали и рассматривали. Высокоуровневое тестирование предоставит необходимую информацию для выполнения низкоуровневого / унитарного тестирования и для планирования стратегии развития тестирования в соответствии с имеющимися у вас ресурсами.
Например, вы хотели бы сначала проверить цепочку обработки как черный ящик. Если вы обнаружите, что какой-то элемент цепочки выходит из строя из-за поведения, не учитывающего некоторые экстремальные условия, вы пишете тесты, которые гарантируют функциональность не только для этого члена, но и для других. Тогда вы доставляете. В следующем цикле вы обнаружите, что иногда сеть выходит из строя. Таким образом, вы пишете тесты, которые решают эту проблему на модулях, которые могут быть уязвимы. И так далее.
источник