стоит ли проводить модульное тестирование?

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

<p>каждый день в нашем офисе происходит обмен, который выглядит примерно так:</p><blockquote> <p>"чувак, мне просто нравятся юнит-тесты, я только что смог внести кучу изменений в то, как что-то работает, а затем смог подтвердить, что я ничего не сломал, запустив тест снова…"</p> </blockquote><p>детали меняются ежедневно, но настроение не меняется. модульные тесты и разработка через тестирование (tdd) имеют так много скрытых и личных преимуществ, а также очевидные, которые вы просто не можете объяснить кому-то, пока они сами не сделают это.</p><p>но, игнорируя это, вот моя попытка!</p><ol> <li> <p>модульные тесты позволяют быстро вносить большие изменения в код. вы знаете, что это работает сейчас, потому что вы запускаете тесты, когда вы вносите необходимые изменения, вам нужно, чтобы тесты снова заработали. это экономит часы.</p> </li> <li> <p>tdd поможет вам понять, когда прекратить кодирование. ваши тесты дают вам уверенность в том, что вы уже сделали достаточно, и можете прекратить подстройку и перейти к следующему шагу.</p> </li> <li> <p>тесты и код работают вместе для достижения лучшего кода. ваш код может быть плохим/глючным. ваш тест может быть плохим/глючным. в tdd вы рассчитываете на вероятность того, что <strong>оба</strong> будут плохими, а глючные будут низкими. часто это тест, который нужно исправить, но это все же хороший результат.</p> </li> <li> <p>tdd помогает с запором кодирования. когда вы столкнетесь с большими и сложными задачами, написание тестов поможет вам быстро двигаться вперед.</p> </li> <li> <p>модульные тесты помогут вам по-настоящему понять дизайн кода, над которым вы работаете. вместо того, чтобы писать код для чего-то, вы начинаете с описания всех условий, которым вы подвергаете код, и того, какие результаты вы ожидаете получить от этого.</p> </li> <li> <p>модульные тесты дают вам мгновенную визуальную обратную связь, нам всем нравится ощущение всех этих зеленых огней, когда мы закончили. это очень приятно. также намного легче подобрать, где вы остановились после перерыва, потому что вы можете видеть, куда вы попали - следующий красный свет, который нужно исправить.</p> </li> <li> <p>вопреки распространенному мнению, юнит-тестирование не означает написание вдвое больше кода или медленное кодирование. это быстрее и надежнее, чем кодирование без тестов, если вы освоили его. сам тестовый код обычно относительно тривиален и не добавляет больших накладных расходов на то, что вы делаете. это тот, которому вы будете верить, только когда будете это делать :)</p> </li> <li> <p>я думаю, что это был фаулер, который сказал: "несовершенные тесты, которые часто выполняются, намного лучше, чем совершенные тесты, которые вообще никогда не пишутся". я интерпретирую это как предоставление мне разрешения на написание тестов, где я думаю, что они будут наиболее полезными, даже если остальная часть моего кода покрыта ужасно неполным.</p> </li> <li> <p>хорошие юнит-тесты могут помочь документировать и определить, что что-то должно делать</p> </li> <li> <p>модульные тесты помогают с повторным использованием кода. перенесите оба кода <strong>и</strong> ваши тесты в новый проект. изменяйте код, пока тесты не запустятся снова.</p> </li> </ol><p>много работы, с которой я работаю, не очень хорошо подходит для unit test (взаимодействие с пользователем веб-приложения и т.д.), но, тем не менее, мы все тестируем зараженные в этом магазине, и мы счастливы, когда наши тесты связаны. я не могу рекомендовать подход достаточно высоко.</p>

<p><strong>модульное тестирование очень похоже на поход в спортзал.</strong> вы знаете, что это хорошо для вас, все аргументы имеют смысл, поэтому вы начинаете тренироваться. есть первоначальный раш, и это здорово, но через несколько дней вы начинаете задумываться, стоит ли оно того. вы тратите час своего дня, чтобы переодеться и бегать на колесе хомяка, и вы не уверены, что действительно получаете что-то кроме болей в ногах и руках.</p><p>затем, спустя, может быть, одну или две недели, когда болезненность проходит, начинается большой крайний срок. вы должны проводить каждый час бодрствования, пытаясь выполнить "полезную" работу, чтобы вы исключали посторонние вещи, например, ходили в спортзал. вы выходите из привычки, и к тому времени, когда большой крайний срок заканчивается, вы возвращаетесь к исходной точке. если вам вообще удастся вернуться в спортзал, вы почувствуете себя так же больно, как и в первый раз.</p><p>вы читаете, чтобы увидеть, если вы делаете что-то не так. вы начинаете чувствовать себя немного иррациональным, несмотря ни на что, счастливые люди превозносят достоинства упражнений. вы понимаете, что у вас мало общего. им не нужно ехать 15 минут, чтобы пойти в спортзал; в их здании есть один. им не нужно ни с кем спорить о пользе упражнений; это то, что каждый делает и считает важным. когда приближается большой крайний срок, им не говорят, что упражнения не нужны больше, чем ваш начальник попросил бы вас прекратить есть.</p><p><strong>итак, чтобы ответить на ваш вопрос, модульное тестирование обычно стоит усилий, но количество требуемых усилий не будет одинаковым для всех.</strong> модульное тестирование может потребовать огромных усилий, если вы имеют дело с базой спагетти-кода в компании, которая <em> на самом деле </em> не оценивает качество кода. (многие менеджеры будут петь похвалы unit testing, но это не значит, что они поддержат это, когда это будет важно.)</p><p>если вы пытаетесь внедрить модульное тестирование в свою работу и не видите всего того солнечного света и радуги, которых вы ожидали, не вините себя. возможно, вам придется найти новую работу, чтобы действительно сделать модульное тестирование для вас.</p>

<p>лучший способ убедить ... найти ошибку, написать для нее модульный тест, исправить ошибку.</p><p>эта конкретная ошибка вряд ли когда-либо появится снова, и вы можете доказать это с помощью своего теста.</p><p>если вы сделаете это достаточно, другие быстро поймут.</p>

<blockquote> <p>thetalkingwalnut спрашивает:</p> <blockquote> <p>какие есть хорошие способы убедить скептически настроенных разработчиков в ценности модульного тестирования?</p> </blockquote> </blockquote><p>все здесь собираются на кучу разных причин, почему юнит-тестирование хорошо. тем не менее, я считаю, что часто лучший способ убедить кого-либо в чем-либо - это <em> выслушать </em> их аргументы и обратиться к ним по пунктам. если вы слушаете их и помогаете им выразить свои проблемы, вы можете обратиться к каждому из них и, возможно, преобразовать их в свою точку зрения (или, по крайней мере, оставить их без ноги, чтобы стоять на них). <em> кто знает? возможно, они убедят вас, почему модульные тесты не подходят для вашей ситуации. </em> не вероятно, но возможно. возможно, если вы опубликуете свои аргументы против юнит-тестов, мы поможем определить контраргументы.</p><p>важно выслушать и понять обе стороны аргумента. если вы попытаетесь принять модульные тесты слишком рьяно, не обращая внимания на проблемы людей, вы закончите религиозной войной (и, вероятно, действительно бесполезными модульными тестами). если вы примете его медленно и начнете применять его там, где вы увидите наибольшую выгоду при наименьших затратах, вы сможете продемонстрировать ценность модульных тестов и иметь больше шансов убедить людей. я понимаю, что это не так просто, как кажется - обычно требуется некоторое время и тщательные метрики, чтобы создать убедительный аргумент.</p><p>модульные тесты являются инструментом, как и любой другой, и должны применяться таким образом, чтобы выгоды (отлов ошибок) перевешивали затраты (усилия по их написанию). не используйте их, если/где они не имеют смысла, и помните, что они являются лишь частью вашего арсенала инструментов (например, проверки, утверждения, анализаторы кода, формальные методы и т.д.). мои разработчики говорят следующее:</p><ol> <li> <p>они могут пропустить написание теста для метода, если у них есть хороший аргумент, почему это не нужно (например, слишком просто, чтобы стоить или слишком сложно, чтобы стоить) и как метод будет проверен иным способом (например, проверка, утверждения , формальные методы, интерактивные/интеграционные тесты). им необходимо учитывать, что некоторые проверки, такие как проверки и формальные доказательства, выполняются в определенный момент времени, а затем их необходимо повторять каждый раз, когда изменяется производственный код, тогда как модульные тесты и утверждения можно использовать как регрессионные тесты (написанные один раз и впоследствии выполненные повторно). ). иногда я согласен с ними, но чаще я буду спорить о том, действительно ли метод слишком прост или слишком сложен для модульного тестирования.</p> <ul> <li> <p>если разработчик утверждает, что метод кажется слишком простым для сбоя, разве не стоит потратить 60 секунд, необходимых для написания простого 5-строчного модульного теста для него? эти 5 строк кода будут выполняться каждую ночь (вы делаете ночные сборки, верно?) в течение следующего года или более и будут стоить усилий, даже если однажды случится обнаружение проблемы, которая может занять 15 минут или дольше, чтобы идентифицировать и отладить. кроме того, написание простых юнит-тестов увеличивает количество юнит-тестов, благодаря чему разработчик выглядит хорошо.</p> </li> <li> <p>с другой стороны, если разработчик утверждает, что метод кажется слишком сложным для модульного тестирования (не стоящего значительных усилий), это может быть хорошим показателем того, что метод должен быть разделен или подвергнут рефакторингу для тестирования простых частей. обычно это методы, которые полагаются на необычные ресурсы, такие как синглтоны, текущее время, или внешние ресурсы, такие как набор результатов базы данных. эти методы обычно должны быть реорганизованы в метод, который получает ресурс (например, вызывает gettime ()), и метод, который принимает ресурс в качестве аргумента (например, принимает метку времени в качестве параметра). я позволил им пропустить тестирование метода, который извлекает ресурс, и вместо этого они написали модульный тест для метода, который теперь принимает ресурс в качестве аргумента. обычно это значительно упрощает написание модульного теста и, следовательно, стоит писать.</p> </li> </ul> </li> <li> <p>разработчик должен нарисовать "черту в песке" в том, насколько комплексными должны быть их модульные тесты. позже, в процессе разработки, всякий раз, когда мы обнаруживаем ошибку, они должны определить, могут ли более комплексные модульные тесты решить проблему. если это так, и если такие ошибки появляются многократно, им нужно сдвинуть "линию" к написанию более комплексных модульных тестов в будущем (начиная с добавления или расширения модульного теста для текущей ошибки). им нужно найти правильный баланс.</p> </li> </ol><p>важно понимать, что модульные тесты - это не серебряная пуля, и <em> есть </em> такая вещь, как слишком много модульного тестирования. на моем рабочем месте, когда бы мы ни делали извлеченные уроки, я неизбежно слышу "нам нужно написать больше юнит-тестов". менеджмент кивает в знак согласия, потому что его ударили по головам, что "модульные тесты" == "хорошо".</p><p>тем не менее, нам нужно понять влияние "большего количества модульных тестов". разработчик может писать только ~ n строк кода в неделю, и вам нужно выяснить, какой процент этого кода должен составлять код модульного теста по сравнению с рабочим кодом. на слабом рабочем месте может быть 10% кода в виде модульных тестов и 90% кода в качестве производственного кода, что приводит к продукту с множеством (хотя и очень глючных) функций (например, ms word). с другой стороны, строгий магазин с 90% модульных тестов и 10% производственного кода будет иметь непревзойденный продукт с очень небольшим количеством функций (подумайте "vi"). вы можете никогда не услышать сообщения о сбое последнего продукта, но это, скорее всего, связано с тем, что продукт не очень хорошо продается, а также с качеством кода.</p><p>что еще хуже, возможно, единственная уверенность в разработке программного обеспечения состоит в том, что "изменения неизбежны". предположим, что строгий магазин (90% модульных тестов/10% производственного кода) создает продукт, имеющий ровно 2 функции (при условии, что 5% производственного кода == 1 функция). если клиент приходит и изменяет одну из функций, то это изменение уничтожает 50% кода (45% модульных тестов и 5% производственного кода). у слабого магазина (10% модульных тестов/90% производственного кода) есть продукт с 18 функциями, ни одна из которых не работает очень хорошо. их клиент полностью обновляет требования для 4 своих функций. несмотря на то, что это изменение в 4 раза больше, уничтожается только половина базы кода (~ 25% = ~ 4,4% модульных тестов + 20% производственного кода).</p><p>я хочу сказать, что вам нужно сообщить, что вы понимаете баланс между слишком маленьким и слишком большим количеством модульных тестов - по сути, что вы продумали обе стороны проблемы. если вы сможете убедить своих сверстников и/или ваше руководство в этом, вы получите авторитет и, возможно, получите больше шансов победить их.</p>

<p>я несколько раз играл в модульное тестирование, и все еще хочу убедиться, что оно стоит усилий, учитывая мою ситуацию.</p><p>я разрабатываю веб-сайты, где большая часть логики включает создание, получение или обновление данных в базе данных. когда я попытался "смоделировать" базу данных для целей модульного тестирования, она стала очень грязной и казалась немного бессмысленной.</p><p>когда я писал модульные тесты вокруг бизнес-логики, это никогда не помогало мне в долгосрочной перспективе. поскольку я в основном работаю над одними проектами, я, как правило, интуитивно знаю, над какими областями кода может повлиять то, над чем я работаю, и я тестирую эти области вручную. я хочу как можно быстрее доставить решение своему клиенту, и модульное тестирование часто кажется пустой тратой времени. я перечисляю ручные тесты и сам прохожу их, отмечая их галочкой по ходу.</p><p>я вижу, что это может быть полезно, когда команда разработчиков работает над проектом и обновляет код друг друга, но даже тогда я думаю, что если разработчики высокого качества, хорошего общения и хорошо написанного кода часто бывает достаточно ,.</p>

<p>отличительной особенностью модульных тестов является то, что они служат документацией о том, как должен работать ваш код. хорошие тесты похожи на эталонную реализацию, и товарищи по команде могут посмотреть на них, чтобы понять, как интегрировать свой код с вашим.</p>

<p>юнит-тестирование стоит первоначальных вложений. с тех пор, как пару лет назад я начал использовать модульное тестирование, я обнаружил некоторые реальные преимущества:</p><ul> <li><strong>регрессионное тестирование</strong> устраняет страх внесения изменений в код (нет ничего лучше теплого свечения от того, что код работает или взрывается при каждом изменении)</li> <li><strong>примеры исполняемого кода</strong> для других членов команды (и вас самих через шесть месяцев ..)</li> <li><strong><em> беспощадный </em> рефакторинг</strong> - это невероятно полезно, попробуйте!</li> </ul><p>фрагменты кода могут помочь уменьшить затраты на создание тестов. нетрудно создать фрагменты, которые позволяют создать схему класса и связанное с ним устройство для модульного теста за считанные секунды.</p>

<p>вы должны проверить как можно меньше!</p><p>это означает, что вы должны написать достаточно тестов, чтобы выявить намерения. это часто затуманивается. модульное тестирование стоит вам. если вы вносите изменения и вам приходится менять тесты, вы будете менее гибкими. держите юнит-тесты короткими и приятными. тогда они имеют большую ценность.</p><p>слишком часто я вижу множество тестов, которые никогда не сломаются, являются большими и неуклюжими и не представляют большой ценности, они просто заканчивают тем, что замедляют вас.</p>

<p>я не видел этого ни в одном из других ответов, но заметил одну вещь: <strong>я мог бы отлаживать намного быстрее</strong>. вам не нужно детализировать свое приложение, выполнив только правильную последовательность шагов, чтобы добраться до кода, который вы исправляете, только чтобы обнаружить, что вы допустили логическую ошибку и вам нужно сделать все это снова. с помощью модульного теста вы можете просто перейти непосредственно к отлаживаемому коду.</p>

<p>[у меня есть точка зрения, которую я не вижу выше]</p><p>"все юнит-тесты не обязательно осознают это - факт"</p><p>подумайте об этом, вы пишете функцию для анализа строки и удаления символов новой строки. как разработчик-новичок, вы либо запускаете через него несколько случаев из командной строки, внедряя его в main (), либо соединяете визуальный интерфейс с помощью кнопки, связываете свою функцию с парой текстовых полей и кнопкой и видите что просходит.</p><p>это модульное тестирование - базовое и плохо составленное, но вы тестируете кусок кода в нескольких случаях.</p><p>вы пишете что-то более сложное. он выдает ошибки, когда вы пропускаете несколько случаев (модульное тестирование), а затем отлаживаете код и отслеживаете. вы смотрите на ценности по мере прохождения и решаете, правильны они или нет. это в некоторой степени модульное тестирование.</p><p>модульное тестирование здесь действительно принимает это поведение, формализует его в структурированный шаблон и сохраняет его, чтобы вы могли легко перезапустить эти тесты. если вы пишете "правильный" пример модульного теста, а не ручное тестирование, это занимает столько же времени, а может и меньше, чем у вас есть опыт, и у вас есть его, чтобы повторять снова и снова</p>

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

<p>основная часть разработки, основанной на тестировании, которая часто закрывается, - это написание тестируемого кода. сначала это кажется своего рода компромиссом, но вы обнаружите, что тестируемый код также в конечном счете модульный, обслуживаемый и читаемый. если вам по-прежнему нужна помощь, чтобы убедить людей <a href="http://www.masukomi.org/talks/unit\_testing\_talk\_2/index.xul?data=slide\_data.txt#page1">это</a> хорошая простая презентация о преимуществах модульного тестирования.</p>

<p>если ваша существующая кодовая база не подходит для модульного тестирования, и она уже находится в производстве, вы можете создать больше проблем, чем решаете, пытаясь реорганизовать весь код, чтобы он мог быть модульно-тестируемым.</p><p>возможно, вам лучше приложить усилия для улучшения тестирования интеграции. существует много кода, который проще написать без юнит-теста, и если qa может проверить функциональность в соответствии с документом требований, то все готово. отправим его.</p><p>классическим примером этого, на мой взгляд, является sqldatareader, встроенный в страницу aspx, связанную с gridview. код все в файле aspx. sql находится в хранимой процедуре. что ты тестируешь? если страница выполняет то, что должна делать, стоит ли ее переделывать в несколько слоев, чтобы вам было что автоматизировать?</p>

<p>одна из лучших вещей в модульном тестировании - то, что ваш код станет легче тестировать, когда вы это делаете. предварительно существующий код, созданный без тестов, всегда является проблемой, потому что, поскольку они не предназначались для модульного тестирования, нередко бывает высокий уровень связи между классами, трудно настраиваемыми объектами внутри вашего класса - как электронная почта отправка сервисной справки - и так далее. но не позволяйте этому сбить вас с толку! вы увидите, что ваш общий дизайн кода станет лучше, когда вы начнете писать модульные тесты, и чем больше вы будете тестировать, тем увереннее вы станете вносить в него еще больше изменений, не опасаясь сломать свое приложение или допустить ошибки ,.</p><p>есть несколько причин для модульного тестирования вашего кода, но со временем вы обнаружите, что время, которое вы экономите на тестировании, является одной из лучших причин для этого. в системе, которую я только что поставил, я настаивал на проведении автоматического модульного тестирования, несмотря на заявления о том, что я потратил бы гораздо больше времени на тестирование, чем на тестирование системы вручную. когда все мои модульные тесты выполнены, я выполнил более 400 тестовых примеров менее чем за 10 минут, и каждый раз, когда мне приходилось вносить небольшие изменения в код, все, что мне требовалось, чтобы убедиться, что код по-прежнему работает без ошибок, было десять минут. можете ли вы представить время, потраченное на выполнение этих 400+ тестов вручную?</p><p>когда дело доходит до автоматизированного тестирования - будь то модульное тестирование или приемочное тестирование - все думают, что это напрасная попытка написать то, что вы можете сделать вручную, а иногда и так - если вы планируете запускать тесты только один раз. лучшая часть автоматизированного тестирования заключается в том, что вы можете запускать их несколько раз без усилий, а после второго или третьего запуска вы потратили время и усилия <em> </em> уже оплачен.</p><p>последним советом будет не только модульное тестирование вашего кода, но и начало выполнения теста первым (подробнее см. <a href="http://en.wikipedia.org/wiki/test-driven\_development">tdd</a> и <a href="http://en.wikipedia.org/wiki/behavior\_driven\_development">bdd</a> )</p>

<p>модульные тесты также особенно полезны, когда речь идет о рефакторинге или переписывании части кода. если у вас хорошее покрытие модульных тестов, вы можете с уверенностью провести рефакторинг. без юнит-тестов часто трудно убедиться, что вы ничего не сломали.</p>

<p>я работаю инженером по обслуживанию плохо документированной, ужасной и большой базы кода. я бы хотел, чтобы люди, написавшие код, написали для него модульные тесты.<br> каждый раз, когда я делаю изменения и обновляю производственный код, я боюсь, что могу внести ошибку из-за того, что я не учел некоторые условия.<br> если бы они написали тест, внесение изменений в базу кода было бы проще и быстрее. (в то же время база кода была бы в лучшем состоянии) ..</p><p>я думаю, что модульные тесты очень полезны при написании api или сред, которые должны длиться много лет и использоваться/изменяться/развиваться людьми, отличными от оригинальных кодеров.</p>

<p>короче говоря - да. они стоят каждой унции усилий ... до определенного момента. в конце концов, тесты - это все еще код, и, как и при обычном росте кода, ваши тесты в конечном итоге должны быть реорганизованы, чтобы их можно было поддерживать и поддерживать. там тонна gotchas! когда речь идет о модульном тестировании, но, о, о, о, человек, ничего, и я имею в виду, что ничего не дает разработчику возможность вносить изменения более уверенно, чем богатый набор модульных тестов.</p><p>я сейчас работаю над проектом ... это несколько tdd, и у нас большинство наших бизнес-правил инкапсулированы как тесты ... у нас сейчас около 500 или около того модульных тестов. на прошлой итерации мне пришлось обновить наш источник данных и то, как наше настольное приложение взаимодействует с этим источником данных. это заняло у меня пару дней, все время я продолжал проводить юнит-тесты, чтобы посмотреть, что я сломал и исправил. изменить; сборка и запуск ваших тестов; исправить то, что ты сломал. вымойте, промойте, повторите при необходимости. то, что традиционно занимало дни qa и нагрузки на катере, было коротким и приятным опытом.</p><p>подготовьтесь заранее, немного дополнительных усилий, и это окупится в 10 раз позже, когда вам придётся начать разбираться с основными функциями/функциями.</p><p>я купил эту книгу - это библия знаний по тестированию xunit - это, вероятно, одна из самых популярных книг на моей полке, и я консультируюсь с ней ежедневно: <a href="https://rads.stackoverflow.com/amzn/click/com/0131495054">текст ссылки</a> </p>

<p>иногда либо я, либо один из моих сотрудников проводят пару часов, пытаясь найти причину слегка неясной ошибки, и как только причина ошибки обнаруживается в 90% случаев, когда код не тестируется модулем. модульного теста не существует, потому что разработчик сокращает углы, чтобы сэкономить время, но затем теряет это и требует дополнительной отладки.</p><p>потратив небольшое количество времени на написание модульного теста, вы сэкономите часы на дальнейшей отладке.</p>

<p>когда вы сказали, что "наша кодовая база не поддается легкому тестированию", это первый признак запаха кода. написание модульных тестов означает, что вы обычно пишете код по-другому, чтобы сделать его более тестируемым по моему мнению, это хорошо, так как то, что я видел на протяжении многих лет при написании кода, для которого мне приходилось писать тесты, заставило меня предложить лучший дизайн.</p>

<p>я не знаю. во многих местах не проводится модульное тестирование, но качество кода хорошее. microsoft проводит модульное тестирование, но билл гейтс дал синий экран на своей презентации.</p>

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

<p>я написал очень большой пост в блоге на эту тему. я обнаружил, что одиночное модульное тестирование не стоит работы и обычно сокращается, когда приближаются сроки.</p><p>вместо того, чтобы говорить о модульном тестировании с точки зрения проверки "после проверки", мы должны взглянуть на истинное значение, найденное, когда вы намереваетесь написать спецификацию/тест/идею перед реализацией.</p><p>эта простая идея изменила способ, которым я пишу программное обеспечение, и я бы не стал возвращаться к "старому".</p><p> <a href="http://toranbillups.com/blog/archive/2010/04/22/how-test-first-development-changed-my-life/">как тестирование первой разработки изменило мою жизнь</a> </p>

<p>еще одна вещь, о которой никто не упомянул, - это обязательство всех разработчиков фактически запускать и обновлять любой существующий автоматизированный тест. автоматизированные тесты, к которым вы вернулись и которые были сорваны из-за новых разработок, теряют большую ценность и делают автоматизированное тестирование действительно болезненным. большинство из этих тестов не будут показывать ошибки, так как разработчик тестировал код вручную, поэтому время, потраченное на их обновление, просто напрасно.</p><p>убеждать скептиков в том, что они не разрушают работу, которую делают другие в модульных тестах, гораздо важнее для получения выгоды от тестирования и может быть проще.</p><p>тратить часы на обновление тестов, которые ломаются из-за новых функций, каждый раз, когда вы обновляете из репозитория, не является ни продуктивным, ни забавным.</p>

<p>я обнаружил tdd пару лет назад, и с тех пор написал все мои любимые проекты, используя его. я подсчитал, что для разработки проекта tdd требуется примерно столько же времени, сколько и для ковбойской, но я настолько уверен в конечном продукте, что не могу удержаться от чувства выполненного долга.</p><p>я также чувствую, что это улучшает мой стиль дизайна (гораздо более ориентированный на интерфейс на случай, если мне нужно что-то смешать), и, как пишет зеленый пост вверху, это помогает с "запором кодирования": когда вы не знаете, что чтобы написать дальше, или перед вами стоит непростая задача, вы можете написать маленьким.</p><p>наконец, я обнаружил, что наиболее полезным приложением tdd на сегодняшний день является отладка, хотя бы потому, что вы уже разработали структуру запроса, с помощью которой вы можете подтолкнуть проект к созданию ошибки повторяющимся образом.</p>

<p>да - модульное тестирование определенно стоит усилий, но вы должны знать, что это не серебряная пуля. модульное тестирование - это работа, и вам придется работать над тем, чтобы тест обновлялся и соответствовал изменениям кода, но предложенное значение стоит усилий, которые вы должны вложить. возможность рефакторинга безнаказанно является огромным преимуществом, поскольку вы всегда можете проверить функциональность запустив свои тесты после любого изменения кода. хитрость заключается в том, чтобы не слишком зацикливаться на том, какую именно единицу работы вы тестируете, или на том, как вы строите требования к тестированию, и когда модульный тест действительно является функциональным тестом и т.д. люди будут спорить по этому поводу часами. в конце концов, реальность такова, что любое тестирование, которое вы выполняете в качестве кода написания, лучше, чем его отсутствие. другая аксиома касается качества, а не количества - я видел кодовые базы с тысячами тестов, которые по сути бессмысленны, поскольку остальные на самом деле не тестируют ничего полезного или что-то конкретное для предметной области, например, бизнес-правила и т.д. конкретной области. я также видел кодовые базы с 30% охватом кода, но тесты были релевантными, значимыми и действительно потрясающими, поскольку они проверяли основные функциональные возможности кода, для которого он был написан, и выражали то, как код должен использоваться.</p><p>один из моих любимых приемов при изучении новых фреймворков или кодовых баз - это написание модульных тестов для проверки того, как все работает. это отличный способ узнать больше о чем-то новом, а не читать сухой документ :)</p>

<p>недавно я прошел точно такой же опыт на своем рабочем месте и обнаружил, что большинство из них знали теоретические преимущества, но их приходилось продавать именно на этих преимуществах, поэтому вот те моменты, которые я использовал (успешно):</p><ul> <li>они экономят время при выполнении отрицательного тестирования, когда вы обрабатываете неожиданные входные данные (нулевые указатели, значения за пределами границ и т.д.), поскольку вы можете делать все это в одном процессе.</li> <li>они обеспечивают немедленную обратную связь во время компиляции относительно стандарта изменений.</li> <li>они полезны для тестирования внутренних представлений данных, которые могут не отображаться во время нормальной работы.</li> </ul><p>и большой ...</p><ul> <li>вам может не потребоваться модульное тестирование, но когда кто-то еще входит и модифицирует код без полного понимания, он может поймать много глупых ошибок, которые они могут сделать.</li> </ul>

<p>исходя из моего опыта, модульные тесты и интеграционные тесты "должны быть" в сложных программных средах.</p><p>чтобы убедить разработчиков в вашей команде написать модульные тесты, вы можете рассмотреть возможность интеграции регрессионного анализа модульных тестов в вашу среду разработки (например, в ежедневный процесс сборки).</p><p>как только разработчики узнают, что если модульный тест не пройден, им не нужно тратить так много времени на его отладку, чтобы найти проблему, им будет больше рекомендовано написать их.</p><p>вот инструмент, который обеспечивает такую функциональность:</p><p> <a href="http://www.wisetester.com/">инструмент регрессионного анализа модульных тестов</a> </p>

<p>если вы используете nunit, одной простой, но эффективной демонстрацией является запуск собственных тестовых наборов nunit. наблюдение за настоящим набором тестов, дающим тренировочную базу, стоит тысячи слов ...</p>

<p>о модульном тестировании следует помнить, что это удобство для разработчика.</p><p>напротив, функциональные тесты предназначены для пользователей: всякий раз, когда вы добавляете функциональный тест, вы тестируете то, что увидит пользователь. когда вы добавляете юнит-тест, вы просто облегчаете свою жизнь как разработчик. это немного роскошь в этом отношении.</p><p>помните об этой дихотомии, когда вам нужно сделать выбор между написанием модуля или функциональным тестом.</p>

<p>я согласен с точкой зрения, противоположной большинству здесь: <a href="http://blogs.msdn.com/b/cashto/archive/2009/03/31/it-s-ok-not-to-write-unit-tests.aspx">нормально не писать модульные тесты</a> особенно сложное программирование на прототипах (например, ai) сложно совмещать с модульным тестированием.</p>

<p>модульное тестирование очень помогает в проектах, которые больше, чем любой разработчик может держать в голове. они позволяют запустить пакет модульных тестов перед регистрацией и определить, что вы что-то сломали. это сокращает <em>много</em> в случаях необходимости сидеть и вертеть пальцами в ожидании, пока кто-то еще исправит ошибку, которую они отметили, или в случае необходимости отменить свои изменения, чтобы вы могли получить некоторую работу сделанный. это также очень ценно при рефакторинге, поэтому вы можете быть уверены, что реорганизованный код пройдет все тесты, которые прошел исходный код.</p>

<p>с помощью модульного теста можно вносить изменения в код, оставляя остальные функции без изменений. это большое преимущество. используете ли вы тестовый набор и регрессионные тесты, когда закончите писать новую функцию?.</p>

<p>весь смысл модульного тестирования состоит в том, чтобы сделать тестирование простым. это автоматизировано. "сделать тест" и все готово. если одна из проблем, с которой вы сталкиваетесь, затрудняет тестирование кода, это лучшая причина для использования модульного тестирования.</p>

<p>только сегодня мне пришлось сменить класс, для которого ранее был написан модульный тест.<br> сам тест был хорошо написан и включал тестовые сценарии, о которых я даже не думал.<br> к счастью, все тесты пройдены, и мои изменения были быстро проверены и с уверенностью введены в тестовую среду.</p>

<p>когда вы вручную тестируете программное обеспечение, у вас обычно есть небольшой набор тестов/действий, которые вы используете. в конце концов, вы автоматически измените свои входные данные или действия, чтобы самостоятельно разобраться с известными проблемами. модульные тесты должны быть там, чтобы напомнить вам, что вещи не работают правильно.</p><p>я рекомендую писать тесты перед кодом, добавлять новые тесты/данные, чтобы развивать функциональность основного кода!</p>

<p>будучи студентом-физиком, я очень стремлюсь <em> доказать </em>, что мой код работает так, как он должен. вы можете либо доказать это логически, что значительно усложняет задачу по мере того, как реализация становится все более сложной, либо вы можете сделать (как можно более близкое) эмпирическое доказательство функции с помощью хорошего тестирования.</p><p>если вы не предоставите логическое доказательство функции, вы должны проверить. единственная альтернатива - сказать: "я думаю, что код работает ...."</p>

<p>@ джордж стокер "к сожалению, наша кодовая база не поддается легкому тестированию." все согласны с тем, что есть преимущества для модульного тестирования, но похоже, что для этой кодовой базы затраты высоки. если затраты превышают выгоды, то почему они должны быть в восторге от этого? слушайте своих коллег; возможно, для них воспринимаемая боль модульных тестов больше, чем воспринимаемая ценность модульных тестов.</p><p>в частности, постарайтесь получить значение как можно скорее, а не какое-то чувство "xunit is green", а чистый код, который ценят пользователи и сопровождающие. возможно, вам нужно назначить юнит-тесты для одной итерации, а затем обсудить, стоит ли это усилий или нет.</p>

<p>сделайте первые вещи, которые вы тестируете, не связанные с модульным тестированием я работаю в основном на perl, так что это специфичные для perl примеры, но вы можете адаптироваться.</p><ul> <li> <p>каждый модуль загружается и компилируется правильно? в perl это вопрос создания foo.t для каждого foo.pm в базе кода, который выполняет:</p> <pre><code>use\_ok( 'foo' ); </code></pre></li> <li> <p>правильно ли отформатированы все документы pod? используйте test :: pod для проверки правильности форматирования всех pod во всех файлах.</p> </li> </ul><p>вы можете не думать, что это большие вещи, и это не так, но я могу гарантировать, что вы поймете некоторые помои. когда эти тесты запускаются один раз в час и обнаруживают чей-то преждевременный коммит, люди будут говорить: "эй, это круто".</p>

<p>одним из преимуществ модульного тестирования является предсказуемость.</p><p>перед модульным тестированием я мог с большой точностью предсказать, сколько времени потребуется, чтобы что-то кодировать, но не то, сколько времени мне потребуется для его отладки.</p><p>в наши дни, так как я могу планировать, какие тесты я собираюсь написать, я знаю, сколько времени займет кодирование, и в конце кодирования система уже отлажена! это обеспечивает предсказуемость процесса разработки, который снимает много давления, но все еще сохраняет всю радость !!.</p>

<p>модульное тестирование является одной из наиболее распространенных методологий для высококачественного кода. его вклад в более стабильный, независимый и документированный код хорошо доказан. код модульного тестирования рассматривается и обрабатывается как неотъемлемая часть вашего хранилища, и поэтому требует разработки и обслуживания. однако разработчики часто сталкиваются с ситуацией, когда ресурсы, вложенные в модульные тесты, оказываются не такими плодотворными, как можно было бы ожидать. в идеальном мире каждый метод, который мы кодируем, будет иметь серию тестов, охватывающих его код и подтверждающих его правильность. однако обычно из-за нехватки времени мы пропускаем некоторые тесты или пишем некачественные. в такой реальности, учитывая количество ресурсов, вложенных в разработку и сопровождение модульного тестирования, нужно задаться вопросом, учитывая доступное время, какой код заслуживает наибольшего тестирования? и из существующих тестов, какие тесты на самом деле стоит сохранить и поддерживать? смотрите <a href="http://developer4life.blogspot.com/2012/01/effective-unit-testing-not-all-code-is.html">здесь</a> </p>

<p>модульное тестирование поможет вам выпустить программное обеспечение с меньшим количеством ошибок при одновременном снижении общих затрат на разработку. вы можете нажать на ссылку, чтобы узнать больше о <a href="http://www.typemock.com/benefits\_of\_unit\_testing\_with\_typemock.php">преимущества модульного тестирования</a> </p>

<p>кого ты пытаешься убедить? инженеры или менеджер? если вы пытаетесь убедить своих коллег-инженеров, я думаю, что вам лучше всего обратиться к их желанию создать высококачественное программное обеспечение. есть многочисленные исследования, которые показывают, что он находит ошибки, и если они заботятся о хорошей работе, этого должно быть достаточно для них.</p><p>если вы пытаетесь убедить руководство, вам, скорее всего, придется делать какие-то рассуждения о затратах/выгодах, говоря, что стоимость обнаруженных дефектов больше, чем стоимость написания тестов. обязательно включите также и такие затраты, как потеря доверия клиентов и т.д.</p>

<p>это очень .net-ориентированный, но кто-нибудь пробовал <strong>pex</strong>?</p><p>я был крайне скептически настроен, пока не попробовал - и ничего себе. прежде чем я подумал: "меня не убедит эта концепция, пока я не пойму, что он на самом деле <em> делает </em>, чтобы принести мне пользу". мне потребовалась одна пробежка, чтобы изменить свое мнение и сказать: "мне <em> все равно </em> откуда вы знаете, что существует риск фатального исключения, но там <em> есть </em> и теперь я знаю, что должен с этим справиться "</p><p>возможно, единственным недостатком этого поведения является то, что оно помечает <em> все </em> и дает вам шестимесячное отставание. но если у вас был долг по коду, у вас всегда был долг по коду, вы просто не знали об этом. говоря pm, есть потенциальные двести тысяч точек отказа, когда до того, как вы узнали о нескольких десятках, это неприятная перспектива, а это значит, что жизненно важно, чтобы концепция была <em> объяснил первым. </em></p>