Стоит ли проводить модульное тестирование? [закрыто]

572

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

George Stocker
источник
25
Как вы можете спросить такую ​​вещь .. Модульное тестирование так хип :)? Серьезно ... общая идея та же самая ... проводите модульное тестирование, если вы чувствуете, что выгоды перевешивают стоимость ... если у вас есть основания полагать иначе ... найдите что-то еще, что поможет.
Гишу
14
(регулярные утверждения с отладкой \ выпуском сборки + чистый интерфейс к классам + выделенный фиктивный тестер)> модульное тестирование
Виктор Сехр
110
Я был в нескольких командах с таким же отношением, и мой опыт показывает, что ты тратишь время впустую. Скептики просто дают вам возможность обойти вас и саботируют и оглушают, пока вы не расстроитесь и не перейдете в организацию, которая разделяет ваши ценности. Что, вероятно, то, что вы должны сделать. Если «лидер» команды - один из скептиков, серьезно подумайте о том, чтобы выбраться. Я видел такой вид сопротивления юнит-тестированию как лишь верхушку айсберга плохих практик разработки.
Роб
7
@ViktorSehr: модульные тесты не против чистых интерфейсов, на самом деле они противоположны при применении TDD. Либо так, либо место водителя + руль> гараж.
Йонас Быстрем
5
Модульное тестирование - это огромная трата времени, которое редко выявляет ошибки, но затрачивает 30% времени на исправление ошибок, а также время и бюджет на разработку
Доминик,

Ответы:

722

Каждый день в нашем офисе происходит обмен, который выглядит примерно так:

«Чувак, мне просто нравятся юнит-тесты, я только что смог внести кучу изменений в то, как что-то работает, а затем смог подтвердить, что ничего не сломал, запустив тест снова…»

Детали меняются ежедневно, но настроение не меняется. Модульные тесты и разработка через тестирование (TDD) имеют так много скрытых и личных преимуществ, а также очевидные, которые вы просто не можете объяснить кому-то, пока они сами не сделают это.

Но, игнорируя это, вот моя попытка!

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

  2. TDD помогает вам понять, когда прекратить кодирование. Ваши тесты дают вам уверенность в том, что вы уже сделали достаточно, и можете прекратить подстройку и перейти к следующему шагу.

  3. Тесты и код работают вместе для достижения лучшего кода. Ваш код может быть плохим / глючным. Ваш ТЕСТ может быть плохим / глючным. В TDD вы полагаетесь на вероятность того, что оба будут плохими или плохо глючат. Часто это тест, который нужно исправить, но это все же хороший результат.

  4. TDD помогает с запором кодирования. Когда вы столкнетесь с большими и сложными задачами, написание тестов поможет вам быстро двигаться вперед.

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

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

  7. Вопреки распространенному мнению, юнит-тестирование не означает написание вдвое больше кода или медленное кодирование. Это быстрее и надежнее, чем кодирование без тестов, если вы освоили его. Сам тестовый код обычно относительно тривиален и не добавляет больших накладных расходов на то, что вы делаете. Это тот, которому вы будете верить, только когда будете это делать :)

  8. Я думаю, что это был Фаулер, который сказал: «Несовершенные тесты, которые часто выполняются, намного лучше, чем совершенные тесты, которые вообще никогда не пишутся». Я интерпретирую это как предоставление мне разрешения на написание тестов, в которых, я думаю, они будут наиболее полезными, даже если остальная часть моего кода будет ужасно неполной.

  9. Хорошие юнит-тесты могут помочь документировать и определить, что что-то должно делать

  10. Модульные тесты помогают с повторным использованием кода. Перенесите ваш код и ваши тесты в новый проект. Изменяйте код, пока тесты не запустятся снова.

Много работы, с которой я работаю, не очень хорошо подходит для Unit Test (взаимодействие с пользователем веб-приложения и т. Д.), Но, тем не менее, мы все тестируем зараженные в этом магазине, и мы счастливы, когда наши тесты связаны. Я не могу рекомендовать подход достаточно высоко.

reefnet_alex
источник
Является ли презентация, на которую вы ссылаетесь, .xul?
user2427
3
Вопрос был о модульном тестировании. TDD - это совсем не то, что модульное тестирование.
ZunTzu
421

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

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

Вы читаете, чтобы увидеть, если вы делаете что-то не так. Вы начинаете чувствовать себя немного иррациональным, несмотря ни на что, счастливые люди превозносят достоинства упражнений. Вы понимаете, что у вас мало общего. Им не нужно ехать 15 минут, чтобы пойти в спортзал; в их здании есть один. Им не нужно ни с кем спорить о пользе упражнений; это то, что каждый делает и считает важным. Когда приближается Большой Крайний срок, им не говорят, что упражнения не нужны больше, чем ваш начальник попросил бы вас прекратить есть.

Итак, чтобы ответить на ваш вопрос, модульное тестирование обычно стоит усилий, но количество необходимых усилий не будет одинаковым для всех. Модульное тестирование может потребовать огромных усилий, если вы работаете с базой спагетти-кода в компании, которая на самом деле не ценит качество кода. (Многие менеджеры будут петь похвалы Unit Testing, но это не значит, что они поддержат это, когда это будет важно.)

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

benzado
источник
15
потрясающий анекдот!
Сандер Верслуйс
68
Ваши идеи меня заинтриговывают, и я хочу подписаться на вашу рассылку.
Кристофер Паркер
165
Дерьмо, я уже проверил юнит, но теперь ты заставляешь меня чувствовать, что мне нужно идти в спортзал.
Винс
16
Мне тоже не нравится. Я терплю неудачу как выродок и как человек.
Грег
13
+1: Многие менеджеры будут петь похвалы Unit Testing, но это не значит, что они будут поддерживать его, когда это имеет значение ... Возможно, вам придется найти новую работу, чтобы действительно заставить Unit Testing работать на вас. - Замечательные моменты. Очень верно.
Джим Г.
136

Лучший способ убедить ... найти ошибку, написать для нее модульный тест, исправить ошибку.

Эта конкретная ошибка вряд ли когда-либо появится снова, и вы можете доказать это с помощью своего теста.

Если вы сделаете это достаточно, другие быстро поймут.

Эд Гинесс
источник
56
Это работает, только если ваш код построен таким образом, что облегчает модульное тестирование (или вы используете TypeMock). В противном случае вы потратите эоны на построение теста. Большая часть кода без модульных тестов построена с жесткими зависимостями (то есть, новые везде) или статическими методами. Это делает практически невозможным просто запустить быстрый юнит-тест на месте.
Андрей
7
@Rei - Хороший отчет об ошибках, но вы только собираетесь воспроизвести ошибку РАЗ. Спустя 2 года ваш модульный тест все еще будет проверять код, еще долго после того, как отчет об ошибке будет закрыт и забыт.
Орион Эдвардс
4
Сохраняет ошибку исправления 1 ... тест ... хорошо. Пользователи находят ошибку 2 ... исправить ... проверить ... хорошо. Пользователи снова находят ошибку 1 Вспенить, промыть, повторить. Это происходит потому, что исправление одной ошибки вызывает другую, и наоборот.
CaffGeek
1
@ Rei Miyasaka: «Может быть, если у вас есть несколько человек, которые поддерживают проект» - я бы сказал, что почти все нетривиальные проекты делают. Что касается «просто оставить комментарий»: Проблема в том, что могут быть (то есть будут ) взаимодействия с другим кодом, которые могут вызвать появление ошибки. Вот почему вы действительно должны проверить это.
слеске
5
Тем не менее, обратите внимание, что тесты для предотвращения регрессий обычно являются интеграционными тестами, а не модульными тестами (поскольку, по моему опыту, большинство ошибок не только в одной части кода, но возникают из-за комбинации нескольких частей кода, поэтому вы можете только воспроизведите их, объединив все эти части).
Слеське
69

thetalkingwalnut спрашивает:

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

Все здесь собираются на кучу разных причин, почему юнит-тестирование хорошо. Тем не менее, я считаю, что часто лучший способ убедить кого-то в чем-то - это выслушать его аргумент и рассмотреть его пункт за пунктом. Если вы слушаете их и помогаете им выразить свои проблемы, вы можете обратиться к каждому из них и, возможно, преобразовать их в свою точку зрения (или, по крайней мере, оставить их без ноги, чтобы стоять на них). Кто знает? Возможно, они убедят вас, почему юнит-тесты не подходят для вашей ситуации. Не вероятно, но возможно. Возможно, если вы опубликуете свои аргументы против юнит-тестов, мы поможем определить контраргументы.

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

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

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

    • Если разработчик утверждает, что метод кажется слишком простым для сбоя, разве не стоит потратить 60 секунд, необходимых для написания простого 5-строчного модульного теста для него? Эти 5 строк кода будут запускаться каждую ночь (вы делаете ночные сборки, верно?) В течение следующего года или более и будут стоить усилий, даже если однажды случится обнаружение проблемы, для определения которой может потребоваться 15 минут или дольше и отладить. Кроме того, написание простых юнит-тестов увеличивает количество юнит-тестов, благодаря чему разработчик выглядит хорошо.

    • С другой стороны, если разработчик утверждает, что метод кажется слишком сложным для модульного тестирования (не стоящего значительных усилий), это может быть хорошим показателем того, что метод должен быть разделен или подвергнут рефакторингу для тестирования простых частей. Обычно это методы, которые используют необычные ресурсы, такие как синглтоны, текущее время, или внешние ресурсы, такие как набор результатов базы данных. Эти методы обычно должны быть реорганизованы в метод, который получает ресурс (например, вызывает getTime ()), и метод, который принимает ресурс в качестве аргумента (например, принимает метку времени в качестве параметра). Я позволил им пропустить тестирование метода, который извлекает ресурс, и вместо этого они написали модульный тест для метода, который теперь принимает ресурс в качестве аргумента. Обычно это значительно упрощает написание модульного теста и, следовательно, стоит писать.

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

Его важно понимать юнит - тесты не являются панацеей и там есть такая вещь , как слишком много модульного тестирования. На моем рабочем месте, когда бы мы ни делали извлеченные уроки, я неизбежно слышу «нам нужно написать больше юнит-тестов». Менеджмент кивает в знак согласия, потому что его ударили по головам, что «модульные тесты» == «хорошо».

Тем не менее, нам нужно понять влияние «большего количества модульных тестов». Разработчик может писать только ~ N строк кода в неделю, и вам нужно выяснить, какой процент этого кода должен составлять код модульного теста по сравнению с рабочим кодом. На слабом рабочем месте может быть 10% кода в виде модульных тестов и 90% кода в качестве производственного кода, что приводит к продукту с большим количеством (хотя и очень глючных) функций (например, MS Word). С другой стороны, строгий магазин с 90% модульных тестов и 10% производственного кода будет иметь отличный продукт с очень небольшим количеством функций (подумайте «vi»). Вы, возможно, никогда не услышите сообщений о сбое последнего продукта, но это, скорее всего, связано с тем, что продукт не очень хорошо продается, а также с качеством кода.

Что еще хуже, возможно, единственная уверенность в разработке программного обеспечения состоит в том, что «изменения неизбежны». Предположим, что строгий магазин (90% модульных тестов / 10% производственного кода) создает продукт, имеющий ровно 2 функции (при условии, что 5% производственного кода == 1 функция). Если клиент приходит и изменяет одну из функций, то это изменение уничтожает 50% кода (45% модульных тестов и 5% производственного кода). У слабого магазина (10% модульных тестов / 90% производственного кода) есть продукт с 18 функциями, ни одна из которых не работает очень хорошо. Их клиент полностью обновляет требования для 4 своих функций. Несмотря на то, что это изменение в 4 раза больше, уничтожается только половина базы кода (~ 25% = ~ 4,4% модульных тестов + 20% производственного кода).

Я хочу сказать, что вы должны сообщить, что понимаете баланс между слишком маленьким и слишком большим количеством модульных тестов - по сути, что вы продумали обе стороны проблемы. Если вы сможете убедить своих сверстников и / или ваше руководство в этом, вы получите авторитет и, возможно, получите больше шансов победить их.

Bert F
источник
47
Если у Vi очень мало функций, вы его не используете. ;)
Стефан Май
1
+20 за Стефана, если бы я мог :)
Роб Грант
1
Testivus на тестовом освещении - googletesting.blogspot.com/2010/07/…
Берт Ф.
Хороший анализ, хотя я бы сказал, две вещи. Вы, кажется, предполагаете, что изменение функции требует переписывания всего кода, на который она опирается, и это скорее предположение, что существует линейная зависимость между изменением и изменением «количества кода». Кроме того, продукт с низким уровнем тестирования, скорее всего, будет иметь худший дизайн, поэтому продукт с «множеством функций» почти наверняка займет гораздо больше времени для каждой функции (так как тестов практически нет и явно плохой дизайн).
nicodemus13
Написание тестового примера для простого блока кода служит механизмом регрессии - единственный минус, который я видел, это добавление большего количества кадров стека ...
bgs
38

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

Я разрабатываю веб-сайты, где большая часть логики включает создание, извлечение или обновление данных в базе данных. Когда я попытался «смоделировать» базу данных для целей модульного тестирования, она стала очень грязной и казалась немного бессмысленной.

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

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

Ронни
источник
8
Я знаю, что это очень старый, но я вынужден комментировать. Лично я нашел успешные результаты написания тестов для моего уровня сохраняемости. Просто начните транзакцию перед тестированием и откатите ее потом. Не надо издеваться. Иногда у меня есть один класс для извлечения массива данных, затем я передаю этот массив данных второму классу, который «обрабатывает» данные. Этот второй класс не касается базы данных. В этом случае я группирую свои тесты, те, которые тестируют первый класс и касаются базы данных, являются «функциональными тестами» и выполняются нечасто, тесты для последнего класса являются модульными тестами и выполняются часто.
Джош Рибакофф
4
Тестирование это все о счастье. У меня есть пакет из 3900 строк (PL / SQL), который обрабатывает автоматические проводки в систему Главной книги. Теперь я лично ненавижу иметь дело с бухгалтерами - они так разборчивы в мелочах, таких как дробные копейки и прочее. Buncha анально-сохраняющие арифметические гики ... Я не знаю. Мой пакет модульных тестов для пакета учета составляет около 22000 строк и проходит чуть менее 18000 тестов. Это делает главу Honcho в бухгалтерском учете всем счастливым, и до тех пор, пока пропеллер на его маленькой шапочке-счетчике вращается счастливо, я счастлив ... :-)
Боб Джарвис - Восстановить Монику
31

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

pkaeding
источник
26

Юнит-тестирование стоит первоначальных вложений. С тех пор, как пару лет назад я начал использовать модульное тестирование, я обнаружил некоторые реальные преимущества:

  • регрессионное тестирование устраняет страх внесения изменений в код (нет ничего лучше теплого свечения от того, что код работает или взрывается при каждом изменении)
  • примеры исполняемого кода для других членов команды (и вас самих через полгода)
  • беспощадный рефакторинг - это невероятно полезно, попробуйте!

Фрагменты кода могут помочь уменьшить затраты на создание тестов. Нетрудно создать фрагменты, которые позволяют создать схему класса и связанное с ним устройство для модульного теста за считанные секунды.

Джонатан Уэбб
источник
25

Вы должны проверить как можно меньше!

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

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

Кит Николас
источник
23

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

Джон Макинтайр
источник
21

[У меня есть точка зрения, которую я не вижу выше]

«Все юнит-тесты не обязательно осознают это - ФАКТ»

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

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

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

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

Крис Гилл
источник
16

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

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

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

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

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

Curro
источник
12

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

Том Мартин
источник
11

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

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

Классическим примером этого, на мой взгляд, является SqlDataReader, встроенный в страницу ASPX, связанную с GridView. Код все в файле ASPX. SQL находится в хранимой процедуре. Что ты тестируешь? Если страница выполняет то, что должна делать, стоит ли ее переделывать в несколько слоев, чтобы вам было что автоматизировать?

Эрик З Борода
источник
10

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

Есть несколько причин для модульного тестирования вашего кода, но со временем вы обнаружите, что время, которое вы экономите на тестировании, является одной из лучших причин для этого. В системе, которую я только что поставил, я настаивал на проведении автоматического модульного тестирования, несмотря на заявления о том, что я потратил бы гораздо больше времени на тестирование, чем на тестирование системы вручную. Когда все мои модульные тесты выполнены, я выполнил более 400 тестовых примеров менее чем за 10 минут, и каждый раз, когда мне приходилось вносить небольшие изменения в код, все, что мне требовалось, чтобы убедиться, что код по-прежнему работает без ошибок, было десять минут. Можете ли вы представить время, потраченное на выполнение этих 400+ тестов вручную?

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

И последний совет: не только модульное тестирование вашего кода, но и начало тестирования вначале (подробнее см. TDD и BDD ).

Александр Бразил
источник
8

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

killdash10
источник
7

Короче говоря - да. Они стоят каждой унции усилий ... до определенного момента. В конце концов, тесты - это все еще код, и, как и при обычном росте кода, ваши тесты в конечном итоге должны быть реорганизованы, чтобы их можно было поддерживать и поддерживать. Там тонна GOTCHAS! когда речь идет о модульном тестировании, но, о, о, о, человек, ничего, и я имею в виду, что НИЧЕГО не дает разработчику возможность вносить изменения более уверенно, чем богатый набор модульных тестов.

Я сейчас работаю над проектом ... это несколько TDD, и у нас большинство наших бизнес-правил инкапсулированы как тесты ... у нас сейчас около 500 или около того модульных тестов. На прошлой итерации мне пришлось обновить наш источник данных и то, как наше настольное приложение взаимодействует с этим источником данных. Это заняло у меня пару дней, все время я продолжал проводить юнит-тесты, чтобы посмотреть, что я сломал и исправил. Изменить; Сборка и запуск ваших тестов; исправить то, что ты сломал. Вымойте, промойте, повторите при необходимости. То, что традиционно занимало дни QA и нагрузки на лодку, было коротким и приятным опытом.

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

Я купил эту книгу - это Библия знаний по тестированию xUnit - это, вероятно, одна из самых популярных книг на моей полке, и я консультируюсь с ней ежедневно: текст ссылки

Cranley
источник
+1: но, о, о, о, человек, ничего, и я имею в виду, что НИЧЕГО не дает разработчику возможность вносить изменения более уверенно, чем богатый набор юнит-тестов. - Это точно. Я бы хотел, чтобы я понял это раньше.
Джим Г.
7

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

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

Джон Кэхилл
источник
+1: Потратив небольшое количество времени на написание модульного теста, вы сэкономите часы будущей отладки. - Ага!
Джим Г.
7

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

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

mic.sca
источник
Добавляете ли вы модульные тесты для нового кода или исправлений, которые вы делаете?
ɔɯǝɹ
6

Модульное тестирование определенно стоит усилий. К сожалению, вы выбрали сложный (но, к сожалению, общий) сценарий для его реализации.

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

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

Matt
источник
6

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

Кит Элдер
источник
6

Я не знаю. Во многих местах не проводится модульное тестирование, но качество кода хорошее. Microsoft проводит модульное тестирование, но Билл Гейтс дал синий экран на своей презентации.

BigTiger
источник
Обратите внимание, что это было почти 15 лет назад, когда модульное тестирование было не таким популярным, как сегодня.
fwielstra 19.10.10
1
И Internet Explorer по-прежнему не удается сохранить многие веб-страницы.
Сис Тиммерман
5

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

Вместо того, чтобы говорить о модульном тестировании с точки зрения проверки «после проверки», мы должны взглянуть на истинное значение, найденное, когда вы намереваетесь написать спецификацию / тест / идею перед реализацией.

Эта простая идея изменила способ, которым я пишу программное обеспечение, и я бы не стал возвращаться к «старому».

Как тестирование первой разработки изменило мою жизнь

Toran Billups
источник
1
+1 - и я должен сказать, что ошеломляет, сколько троллей привлекла эта запись в блоге (если вы не ошиблись, до того, как вы разместите здесь).
Джефф Стерн
хаха, согласился :) </ reddit на главной странице делает то, что кажется>
Toran Billups
3

Да - модульное тестирование определенно стоит усилий, но вы должны знать, что это не серебряная пуля. Модульное тестирование - это работа, и вам придется работать над тем, чтобы тест обновлялся и соответствовал изменениям кода, но предложенное значение стоит усилий, которые вы должны вложить. Возможность рефакторинга безнаказанно является огромным преимуществом, поскольку вы всегда можете проверить функциональность запустив свои тесты после любого изменения кода. Хитрость заключается в том, чтобы не слишком зацикливаться на той единице работы, которую вы тестируете, или на том, как вы строите требования к тестированию, и когда модульный тест действительно является функциональным тестом и т. Д. Люди будут спорить по этому поводу часами. В конце концов, реальность такова, что любое тестирование, которое вы выполняете в качестве кода написания, лучше, чем его отсутствие. Другая аксиома касается качества, а не количества - я видел кодовые базы с 1000 ' тесты, которые по сути бессмысленны, так как остальные на самом деле не тестируют ничего полезного или что-то специфичное для домена, например, бизнес-правила и т. д. конкретного домена. Я также видел кодовые базы с 30-процентным охватом кода, но тесты были релевантными, значимыми и действительно потрясающими, поскольку они проверяли основные функциональные возможности кода, для которого он был написан, и выражали то, как код должен использоваться.

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

Винни Карпентер
источник
3

Недавно я прошел точно такой же опыт на своем рабочем месте и обнаружил, что большинство из них знали теоретические преимущества, но их приходилось продавать именно на этих преимуществах, поэтому вот те моменты, которые я использовал (успешно):

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

и большой ...

  • Вам может не потребоваться модульное тестирование, но когда кто-то еще входит и модифицирует код без полного понимания, он может поймать много глупых ошибок, которые они могут сделать.
оборота дланод
источник
+1: • Вам может не потребоваться модульное тестирование, но когда кто-то еще входит и модифицирует код без полного понимания, он может поймать много глупых ошибок, которые они могут сделать. - Ага. И учитывая объем товарооборота в индустрии программного обеспечения, это огромное преимущество.
Джим Г.
3

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

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

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

Каз Дракон
источник
3

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

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

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

Самуэль Ослунд
источник
2

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

Гарт Гилмор
источник
2

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

Макс Рибл Каен
источник
2

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

Шинвари
источник