Как модульное тестирование повышает производительность?
в настоящее время я ищу способы повышения производительности нашей команды. Я читал в нескольких местах, что модульное тестирование может быть использовано для повышения производительности. Я могу представить, что написание модульных тестов сейчас может быть полезно в будущем, но помогает ли это в краткосрочной перспективе? Потому что я не понимаю, как написание большего количества кода (=больше потенциальных ошибок) может помочь нам уложиться в сроки.
15 ответов
модульное тестирование не производить больше строк кода в день.
Это гарантирует, что каждый день ваши новые строки кода не вызывают больше ошибок.
вы должны быть очень осторожны в том, что вы месуре, когда пытаетесь оценить свою "производительность". Однако это может помочь вам уложиться в сроки, так как вы потратите меньше времени на исправление вещей.
Это не то, что нацелено на "краткосрочную перспективу", как в "мы будем использовать модульное тестирование, и наш следующий проект будет сделано в 80% случаев".
Не short термин, а не долго термин либо, автоматизированные тесты позволят вам обнаружить проблемы (регрессий) вызвано неправильным исправлением ошибок или неправильными разработками, быстрее; и это определенно приятно.
Это означает, что когда ваше приложение находится на этапе тестирования, каждый раз, когда ошибка исправлена, у вас меньше риска введения новых.
и это также верно, пока приложение все еще находится в разработке : каждый раз developper фиксирует новый модуль, вы знаете, что он не нарушает остальную часть приложения (или, по крайней мере, то, что он не нарушает то, что покрывается автоматическими тестами)
и чем раньше обнаружена ошибка, тем проще и дешевле его исправить: Если ошибка не успевает повлиять на других разработчиков,это тоже лучше.
Что делать, если разработчик считает некоторые "ошибка"(который он не знает, что это ошибка) как функция и начать полагаться на это ? Что происходит, когда это начинает рассматриваться как ошибка, и исправлена ? Другой код ломается, я полагаю : - (
Приятно также, что разработка автоматизированных тестов может означать, что больше разработчиков знают больше о коде приложения : особенно, если некоторые тесты разрабатываются / рассматриваются другими разработчиками, чем те, кто написал код в первую очередь.
не уверен, что это "хороший pratice", но если это сделано таким образом, это означает, что будет какой-то код-обзор на месте - и они определенно полезны.
и как больше разработчиков знают код, больше разработчиков смогут исправить ошибки в частях, которые они не разработали изначально.
в то время как грубое упрощение, чем скорее вы поймаете ошибку, тем дешевле ее исправить. Таким образом, модульное тестирование, по крайней мере, захватит некоторые ошибки спереди.
Я подозреваю, что с точки зрения производительности вопрос в том, легче ли исправить ошибку в коде, которая свежа в сознании программистов, в отличие от ошибки в коде, которому " n " месяцев и т. д. Однако несколько идеалистично предположить, что модульное тестирование (вне более крупного режима тестирования) - это некоторая форма серебра пуля.
"тест" - неправильное слово для модульных тестов. "Определение поведения", возможно, лучший термин.
модульные тесты и TDD могут улучшить производительность (даже в среднесрочной перспективе) несколькими способами.
- код с четко определенным поведением легче отлаживать, так как известно ожидаемое поведение.
- код, написанный с помощью методологии TDD, имеет тенденцию иметь более четкие "швы", что позволяет независимо проверять части кодовой базы. Это делает его более легким сузить вниз проблемы, когда они возникают.
- из-за сильного набора тестов и четко определенного поведения рефакторинг становится намного проще. Это позволяет решать проблемы проектирования с гораздо меньшим риском, даже если они влияют на ряд отдельных классов.
- из-за вышеизложенного, как правило, легче определить, когда что-то идет не так, где правильное место для исправления на самом деле.
- поскольку TDD-написанный код, как правило, не полагается на одноэлементное / статическое поведение или глобальное состояние так же, как и менее глобальное поведение. При менее глобальном поведении вы получаете меньше побочных эффектов.
самым большим преимуществом, по моему опыту, TDD-написанного кода является тот факт, что это хорошо определенными. Вы начинаете с определения того, что код делать, а затем заставить его сделать это. Это контрастирует с "регулярными" практиками разработки, которые часто включают в себя написание кучу кода, а затем тестирование его, чтобы увидеть, что это на самом деле делает.
другое преимущество использования TDD-подобной методологии заключается в том, что вы получаете рабочий код почти сразу, даже если сквозное решение отсутствует. И почти всегда проще добавить в рабочий код, чтобы получить больше рабочего кода, а не писать кучу кода, который находится в неизвестном состоянии, а затем выяснить, что работает неправильно.
Как вы собирались тестировать без модульных тестов? Щелкая вокруг, визуально проверяя ответы? Является ли написание кода один раз и запуск его много раз стоимостью или экономией?
вы собирались выполнять различные условия ошибки? Могли бы вы найти ошибки позже, если вы не относительные затраты на исправление ошибок раньше, а не позже?
однако для меня самая важная причина-менее очевидная: если вы сначала напишете тесты (действительно TDD) или даже как вы идете, вы почти привели к рассмотрению пограничных случаев. И в результате получается, что код просто лучше. Меньше переделок.
другая теория, люди очень ориентированы на цель. Мы любим награды и повторяем поведение, которое дает нам Награды (МММ репутация мммм ... дайте мне вопрос, чтобы ответить : -) видя эти маленькие зеленые тики, как наши тесты проходят мотивирует нас. Вы можете получить больше кода, но он будет написан гораздо быстрее.
теперь я могу представить себе написание модульных тестов может быть полезно в будущем, но делает это тоже поможет в краткосрочной перспективе?
Да, потому что вы заставляете своих разработчиков и архитекторов решать одну проблему за раз.
потому что я не понимаю, как писать больше кода (=больше потенциальных ошибок) может помочь нам уложиться в сроки.
количество дополнительного кода точно такое же. n строк логики = n строк тестов. Но как вы знаете, сырое кодирование не та часть, которая занимает больше времени, в частности, потому что вы можете распараллелить его очень хорошо. Поэтому написание большего количества кода не является реальной проблемой. Чтобы уложиться в сроки, вы должны произвести top качество код будет выпущен, и без тестирования у вас есть
- нет способа узнать, является ли качество верхним или нет.
- нет способа измерения, когда выпуск может быть сделан. (когда все тесты проходят как первый requisite)
вот некоторые мысли. Для моего ответа я определю производительность как # строк, разделенных на количество ошибок. Если применять хорошо, в среднем, я думаю, что модульные тесты дадут более высокую производительность.
Стюарт Хэллоуэй использует метафору двойной бухгалтерской книги: тест-код может показаться избыточным, но наличие этой другой книги-огромная выгода для получения чувства качества.
с модульными тестами разработчик (или парный программист) является первый клиент программного обеспечения. Вот почему ошибки обнаруживаются быстрее,как отмечали другие. Однако человек также является первым клиентом модели OO, API и т. д. Если вовлечен старший разработчик (выполняющий работу или в паре), качество улучшится с точки зрения дизайна. Это имеет среднесрочные и долгосрочные преимущества. (Это часто упускается из виду.)
хорошие модульные тесты будут выставлять и осуществлять угловые случаи. Эти случаи не могут быть достигнуты с помощью тестов vanilla, которые разработчики запускаются вручную. Если вы думаете об ошибках, обнаруженных в поле: сколько из-за какого-то странного состояния? По моему опыту,много.
Это правда, что в неправильных руках модульные тесты могут чувствовать себя колесами, вращающимися в песке. Но с некоторым опытом, выигрыш стоит того, даже в краткосрочной перспективе. Да, может быть меньше строк производственного кода, но частота ошибок будет намного лучше.
когда вы сосредоточитесь на написании тестов после или даже до написания реального кода, Вы не будете писать слишком большие куски. Когда у вас много небольших тестов, очень вероятно, что вы структурируете свой код так, чтобы вы могли писать эти небольшие тесты.
Это означает, что классы не нужно много инфраструктуры для работы и т. д. Такие вещи, как инъекция зависимостей, тоже пригодятся, потому что вы можете захотеть ввести макетные классы для своих тестов. Это приводит к большему слабо связанные классы, которые улучшат общее качество кода и сделают код более обслуживаемым. Кроме того, сеть безопасности unittests поможет вам во время разработки программного обеспечения (и не только после того, как продукт будет готов).
при кодировании большинства (ака все) люди производят ошибки. Это приводит к более длительному развитию мелких функций. Если вы пишете тесты, вероятность ошибок уменьшается, и если вы найдете ошибку, вы можете быть уверены, что ваше исправление ошибки не будет иметь побочных эффектов (если тестовое покрытие" другого " кода хорошее). Это экономит много времени, потому что вам не нужно искать код, на который может повлиять последнее изменение. Это приводит к более высокой скорости развития.
конечно, разработчик должен практиковать писать тесты, но вы получите быстрее довольно скоро. Особенно, если вы привыкнете к libs, которые помогут вам писать тесты, такие как easymock или что-то в этом роде.
в краткосрочной перспективе я думаю, что модульные тесты не помогают, так как это только сокращает время тестирования. Чем меньше проект, тем меньше эффект от него.
однако самое замечательное в модульных тестах заключается в том, что при их написании вы можете гарантировать, что всегда будет обнаружена определенная ошибка, которую вы закодировали. В долгосрочной перспективе они должны быть, в среднесрочной перспективе я бы рекомендовал их.
и в краткосрочной перспективе они, вероятно, уменьшить производительность, но если сам проект не является краткосрочным, вы обязаны извлечь из них выгоду.
модульное тестирование повышает краткосрочную производительность в следующем смысле: это делает более вероятным, что ваш код решает правильную проблему раньше. Расходы нейронных циклов на создание тестов заставят программиста задуматься о различных вариантах использования и пользовательском интерфейсе (или API) этого кода.
противоположным сценарием было бы закодировать на пару недель, и только тогда понять, что код решает половину проблемы. Теперь вы должны исправить свой код, или, возможно, даже выбросьте его и начните сначала.
как модульное тестирование повышает производительность?
неявное предположение в этом вопросе заключается в том, что модульное тестирование улучшает "производительность". Если мы определяем производительность как производство совершенного результата для данного усилия в человеко-часах, то более продуктивность может быть истолкована как производство этого результата менее чем за данное усилие. Если кодер производит "идеальный" код сразу, то выполнение модульного тестирования снизит производительность.
тестирование не в первую очередь для повышения производительности, это для проверки и проверки программных объектов в том смысле, что вы проверяете правильный продукт построен и что правильный продукт построен правильно. Создание тестов и их выполнение имеют побочные эффекты, Наиболее важным из которых является то, что создатели программного обеспечения понимают проблему, которую они пытаются решить с помощью программного обеспечения.
Если вы под краткосрочным подразумеваете месяц или два, я думаю, что ответ да. Как? Когда мне нужно внести изменения в свой собственный код, который я не трогал, возможно, всего несколько недель, или код, который написал кто-то другой в команде, я чувствую себя намного увереннее, если есть модульные тесты и покрытие кода хорошее. Если бы не было тестов, я был бы более склонен исправлять, обходить и вообще избегать прикосновения к основному алгоритму. Сделайте это пару раз, и код станет непостижимый.
сценарий: встреча проекта
Product owner: "нам нужно сделать измените на X и добавьте функцию Y. Есть это выполнимо?".
команда: "было бы лучше подождать Джо вернется. Он написал этот код."
несколько недель спустя..
Джо: "конечно, это можно сделать, но учитывая все испытания, которые прошли в этот модуль это не быстро устанавливать."
Product owner: "Oh. Так.. давайте отложим это изменение на время..."
Я не уверен, отвечаю ли я на ваш вопрос. Это действительно зависит от того, насколько короткий срок. ;-)
современное модульное тестирование не о ловле ошибок - речь идет о разработке и документировании интерфейсов. Написание тестов помогает продумать, как будет использоваться ваш код, а также документы, как они предназначены для использования.
модульное тестирование может поймать ошибки, введенные во время рефакторинга, но это обычно не является основным источником ошибок для проекта.
Итак, в заключение, модульное тестирование облегчит (т. е. дешевле/быстрее) создание кода лучшего качества. Но это не непосредственно помочь вам получить любую задачу, выполненную быстрее.
читайте статьи о мифах и преимуществах, окружающих модульное тестирование:
легко понять, почему можно изначально озадачиться идеей модульных тестов, повышающих производительность. Как большинство людей представляют модульное тестирование, естественный ответ, кажется,более короткие циклы обратной связи более продуктивны, чем более длинные.
большой. Мы определили хорошую броскую фразу, чтобы определить нашу новую стратегию управления. Работа сделана? Ну, не совсем. Нам нужно определить, в чем на самом деле заключается наша обратная связь чтобы реализовать наши "короткие циклы обратной связи". Давайте представим, что мы работаем на кредитный банк, и код, который мы пишем, заключается в составлении графиков амортизации различных кредитов, выданных банком. Эти графики амортизации используются везде, и очень важно, чтобы они были правильными. Обратная связь, которую мы хотели бы получить, - это то, что говорит нам, производит ли наш код правильные графики амортизации для наших кредитов, и генеральный директор предпочел бы, чтобы обратная связь не приходите в форме коллективного иска, поданного клиентами, которые, по понятным причинам, злятся на то, что их переплачивают за проценты. Поэтому, к сожалению, мы должны придумать способ определить, являются ли графики амортизации правильными, прежде чем мы сможем выпустить наш код.
мы могли бы попытаться утверждать, что для этого и существует бухгалтерия. Итак, мы напишем кучу кода, который, по нашему мнению, должен работать, и отправим его контролеру, чтобы он посмотрел. Они находят куча проблем, и отправь обратно. Это кажется справедливым, поскольку было бы неразумно ожидать, что что-то столь сложное, как кредитное программное обеспечение, будет работать с первой попытки. Поэтому мы вносим некоторые изменения и отсылаем его обратно. Но все равно не совсем идеально. Этот цикл повторяется до 5-го или 6-го раза, когда бухгалтерия вежливо сообщает вам, что они сыты по горло вашим ошибочным кодом и что в книге заработной платы могут быть некоторые меньшие числа в следующем цикле, если вы отправите им еще один плохой график смотреть.
вы можете получить некоторые электронные таблицы некоторых образцов кредитов и их правильные графики амортизации, запустить все эти сценарии через программу, и сравнить платежи и распределения и убедитесь, что все совпадает. Тем не менее, кредиты являются сложным доменом; у вас может быть 40 различных сценариев, которые необходимо проверить, и некоторые из этих кредитов имеют 360 платежей для проверки. Для выполнения всех этих сценариев требуется много времени. У нас есть все эти замечательные идеи о короткие циклы обратной связи, итеративный дизайн и улавливание ошибок как можно раньше в процессе. Мы также знаем, что разбиение проблем на крошечные шаги облегчает их решение. Мы знаем, что рефакторинг делает наш код чище и проще в работе, делая будущие изменения быстрее и менее болезненными. но мы не можем тратить время на проверку всех наших сценариев каждый раз, когда мы меняем несколько строк кода. это где модульные тесты приходят в играть.
без модульных тестов мы должны пойти на компромисс. Нам приходится либо тратить огромное количество времени на проверку того, что наш код действительно работает каждый раз, когда мы меняем несколько строк кода, либо удлинять цикл обратной связи. И согласно нашей аксиоме сверху, более длинные циклы обратной связи будут менее продуктивными. Если мы автоматизируем наше тестирование этих графиков погашения, есть прирост производительности для обеих сторон компромисса. Если бы мы в буквальном смысле проверяли графики амортизации каждый раз, когда мы вносим изменения, тогда выгода от производительности является прямой и происходит от устранения всего этого времени проверки. Если бы мы растянули наш цикл обратной связи, то выгода от производительности была бы косвенной и заключалась бы в том, что она позволила бы нам сократить цикл обратной связи.
в этом смысле модульные тесты-это не что иное, как инструмент производительности. Все из этих преимуществ люди часто цитируют для модульных тестов фактически преимущества более коротких циклов обратной связи и итеративный дизайн, который возникает из этих циклов. Модульные тесты просто делают эти идеи практичными. Вы может практикуйте короткие петли обратной связи и итеративный дизайн, используя только ручные методы тестирования. Однако накладные расходы, связанные с выполнением всей этой ручной проверки, сделали бы такой подход совершенно нереалистичным. Когда вы смотрите на такие вещи, как TDD, как замена многократного запуска вашей программы, чтобы увидеть, сделали ли ваши изменения то, что вы думали, производительность импульс действительно начинает иметь смысл.
есть также интересное следствие моей точки зрения о преимуществах, фактически исходящих от более коротких циклов обратной связи, а не модульного тестирования напрямую:вполне возможно написать модульные тесты и потерять, а не получить производительность от него. Я работал в магазинах карго-культового программирования, где модульное тестирование является требованием, но разработчики никогда не были должным образом обучены практике. В этих типах магазинов, некоторые разработчики, которые делают все свое кодирование старомодным способом, и как только они думают, что они сделали, они начинают писать тесты, чтобы "покрыть" код, который они написали. Затем, как только они модифицировали свои новые тесты, они толкают свою ветвь, и она терпит неудачу в сборке CI, потому что они не выполнили ни одного из существующих тестов. Затем они продолжают тратить часы на отладку и переработку ветки с недельными изменениями, чтобы исправить все тесты, которые они сломали, и рожок для обуви в новом тестовом коде после факта. Люди, которые развиваются таким образом пишутся модульные тесты, но для них модульные тесты-это дополнительная стоимость, а не преимущество производительности, потому что они не охватывают короткие циклы обратной связи.
tldr; модульные тесты делают получение обратной связи менее трудоемким, поэтому вы можете делать это чаще, а получение обратной связи чаще означает, что меньше работы теряется во время моментов "назад к чертежной доске", сложные проблемы могут быть более легко разбиты на более простые, а проекты могут быть более уверенно переработан, чтобы быть более восприимчивым к будущим изменениям. Все эти вещи широко понимаются как более продуктивные подходы к разработке программного обеспечения, и все они включены модульными тестами с короткой обратной связью!