Используете ли вы модульные тесты на работе? Какие преимущества вы получаете от них? [закрыто]

18

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

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

анонимное
источник
13
«Они также утверждают, что лишь немногие компании проводят модульное тестирование с использованием производственного программного обеспечения». Это означает, что только несколько компаний производят высококачественное программное обеспечение. К какой группе вы хотите присоединиться? Как «только несколько компаний» могут быть негативным утверждением? Лишь немногие компании чрезвычайно прибыльны; это делает это плохо? Только несколько компаний - действительно восхитительные места для работы; это делает это плохо? Только несколько компаний минимизируют образование отходов; это делает это плохо? Их комментарий "только несколько компаний" не имеет смысла.
С.Лотт
2
Это также, вероятно, неправильно, по неподтвержденным данным, мне еще не приходилось работать в компании или с компанией, которая, по крайней мере, не провела некоторый уровень юнит-тестирования
jk.
1
Я бы сказал, что программист, который считает, что модульное тестирование "имеет очень мало преимуществ", неопытен или просто не знает, как писать эффективные модульные тесты.
Тоби
Сколько юнит-тестов используют разработчики этого сайта?
Джефф
1
@ S.Lott: бессмысленно, да, тем не менее, он все еще используется в качестве аргумента, чтобы не делать модульное тестирование теми, кто не хочет их делать. Я не защищаю их точку зрения здесь, скорее наоборот. Однако это утверждение все еще сделано, и те, кто делает его, убеждены в его ценности, и, поскольку оно принадлежит им, мы должны убедить себя в том, что реальная выгода от проверки его на чистоте, так как бессмысленное не поможет намного большей цели.
Ньютопия

Ответы:

20

некоторые из них говорят мне, что это не нужно

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

и это имеет очень мало пользы.

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

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

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

Вы применяли юнит-тест на своей работе и что вы получаете от него? (например, лучшее качество кода, сокращение времени в долгосрочной перспективе и т. д.)

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

Петер Тёрёк
источник
14

Я делаю юнит-тесты, но не (или мало) на работе

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

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

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

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

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

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

keppla
источник
1
Прошу прощения за то, что я
звучу
Очень хороший совет. Проблема в том, что если все сделано правильно, вы на самом деле не видите преимущества модульного тестирования. Потенциально вы видите вред только тогда, когда не проводите юнит-тестирование Поэтому, если вам нужно убедить других с помощью статистики, а не теории, вы в значительной степени облажались.
Питер Крайтоф
12
@keppla, я писал модульные тесты в проектах, где мои товарищи по команде даже не слышали о модульном тестировании раньше. Как только мои тесты смогли обнаружить несколько ошибок, которые в противном случае могли бы остаться незамеченными, другие начали замечать это, и вскоре они захотели самостоятельно изучить модульное тестирование. Конкретное доказательство - король.
Петер Тёрёк
1
@keppla, честно говоря, если товарищи по команде склонны к тому, что теряют здравый смысл, нет никакого способа убедить их с помощью логических доказательств :-( В таком случае, при сильной поддержке со стороны руководства, вам все равно удастся протолкнуть идею но без этого надежды нет
Петер Тёрёк
3
Вы часто «ломаете» тесты, меняя интерфейс, удаляя классы и т. Д. Когда вы делаете «первый тест», вы воспринимаете это не как «ломающийся», а как первый шаг «Красный». Но когда вы находитесь в мышлении «Просто добавьте несколько строк, пока он не заработает», тесты - это всего лишь несколько строк. И когда «исправлено» кем-то вроде этого, тесты имеют тенденцию к снижению полезности, пока они действительно не служат никакой цели. Самоисполняющееся пророчество 4tw!
Кеппла
7

Я склонен на сторону ваших коллег, но только до определенной степени.

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

def add(x, y)
  x + y
end

Наряду с дюжиной тестов, чтобы убедиться, что дополнение действительно будет работать для произвольно выбранных вариантов использования. Duh ...

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

  1. Когда вы тестируете
  2. Когда вы отлаживаете
  3. Как вы разрабатываете действительно сложные вещи

Давайте рассмотрим каждый из них, предположим, что вы разрабатываете какое-то веб-приложение.

Вы пишете некоторый код для новой функциональности, и к настоящему времени он должен работать достаточно хорошо. Затем вы обращаетесь к своему браузеру и проверяете его работоспособность, проводя более интенсивное тестирование, верно? Bzzzt! ... Неправильный ответ. Вы пишете юнит-тест. Если вы не сделаете этого сейчас, вы, вероятно, никогда не будете. И это одно из мест, где модульные тесты работают очень хорошо: тестировать функциональность высокого уровня.

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

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

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

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

Дени де Бернарди
источник
Как сказал Кент Бек: «проверь все, что может сломаться».
Петер Тёрёк
1
Сердечно соглашаться с ним. Моя главная надежда состоит в том, что ФП примет к сведению: не забывайте проверять тесты, где это применимо. :-)
Дени де Бернарди
7

Весь код должен быть проверен. Там нет выбора по этому поводу.

Непроверенный код бесполезен: ему нельзя доверять ничего делать.

Вы можете написать модульные тесты или надеяться написать интеграционные тесты более высокого уровня или приемочные тесты.

Модульные тесты легче писать, легче отлаживать и проще в управлении.

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

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

Тестирование обязательно. Все высокоуровневые тесты зависят от реально работающих блоков.

Это делает модульное тестирование логической необходимостью. Другого выбора нет.

С. Лотт
источник
1
Другого выбора нет ... если вы заботитесь о качестве. Большинство организаций, занимающихся разработкой программного обеспечения, на самом деле не заботятся о качестве (поскольку они отказываются поставлять программное обеспечение, о котором известно, что оно неисправно).
Джори Себрехтс
@Joeri Sebrechts: это не проблема качества. Это вопрос «сделано». Даже плохое программное обеспечение должно быть проверено, чтобы доказать, что оно что-то делает - что угодно. Простая логика диктует, что должен быть тест, чтобы доказать, что это работает. Даже плохой тест - это тест. Простая логика диктует, что проверка целого должна включать в себя проверки частей. Модульное тестирование просто требуется по логике, больше ничего. Не из соображений качества, но по определению «сделано».
S.Lott
1
Использование программного обеспечения является проверкой само по себе. Множество организаций рады, чтобы пользователь сделал тестирование. Я не говорю, что это хорошо, но так оно и есть. Вы действительно можете отказаться от тестирования перед доставкой, разгрузив тестирование конечному пользователю. Вы можете, но не должны.
Джори Себрехтс
1
@Joeri Sebrechts: На самом деле, вы не можете. Вы не можете произвольно передать программное обеспечение пользователю для приемочного тестирования. Вы должны запустить программное обеспечение хотя бы один раз, чтобы убедиться, что оно работает. Это тест - плохой тест - но тест. Логично, что этот плохой тест включал в себя плохие юнит-тесты. Они существовали, хотя были очень плохими.
С.Лотт
Ваше определение модульного теста бесполезно для этого обсуждения. Модульный тест - это кодифицированный тест, который совсем не обязателен для поставки программного обеспечения. (но хорошо делать во многих обстоятельствах)
Мартин Ба,
6

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

Это довольно просто: если вы не можете продемонстрировать, что ваш код работает (и что может быть лучше, чем исполняемая спецификация в форме теста?), Тогда он не работает .

Это дает мне:

  • Душевное спокойствие: мой CI-сервер сообщает мне, что вся моя кодовая база работает.
  • Способность улучшить мой код: я могу реструктурировать свой код - реорганизовать его - зная, что после реструктуризации я ничего не сломал.
Фрэнк Шиарар
источник
2
Я бы добавил одно очень важное предостережение: одно только модульное тестирование не гарантирует, что «вся ваша кодовая база работает». Это гарантирует, что все блоки кода работают изолированно, но все еще существует огромная вероятность ошибок интеграции, ошибок при визуальном представлении данных и т. Д.
Райан Бруннер
Если ваша среда не проходит "если вы не можете продемонстрировать, что ваш код не работает, то он работает". : p
Davy8
@Ryan: Конечно, ваши интеграционные тесты должны управлять всем проектом. Вопрос был о модульных тестах, поэтому я говорил о модульных тестах, но, конечно, вы должны продемонстрировать необходимость кода, провалив интеграционный тест. И, конечно, у вас должен быть CI-сервер, автоматически развертывающий вашу кодовую базу и выполняющий все тесты.
Фрэнк Ширар,
@ Davy8: В каком случае у вас есть более серьезные проблемы, которые «работают юнит-тесты?».
Фрэнк Ширар
4

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

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

Я подозреваю, что ваши коллеги, которые рекомендуют не использовать его, не являются программистами. Если это так, давайте просто скажем, что не так много людей, которых я ценю выше, чем таких, как Мартин Фаулер или Кент Бек ;).

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

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

Питер Крайтоф
источник
3

Модульные тесты требуют дружественного для юнит-теста языка, дружественного для юнит-теста дизайна и дружественной для юнит-теста задачи

C ++, многопоточный дизайн и графический интерфейс будут кошмаром, а освещение проблем будет ужасным.

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

Стоит ли это того, я не могу сказать.

Вы много рефакторинг? Много ли вы видите в своем коде «глупых ошибок» типа «по одному»?

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

кодировщик
источник
1
Почему многопоточный дизайн будет кошмаром? Проектируйте точки синхронизации и тестируйте там.
Фрэнк Ширар
1
Потому что время зависит от фаз луны, тактовой частоты процессора, погрешности и чего угодно. При одной регистрации проверка может не пройти, если вам повезет, на 1000 других она не пройдет.
Кодер
1
Я написал тестовые многопоточные вещи. Это определенно выполнимо.
Фрэнк Шиарар
4
мусор, вы можете сдать юнит тест на любом языке.
JK.
1
Трудно написать модульные тесты для взаимодействий с GUI, но именно поэтому мы изолировали что-либо (наш код движка), не имеющее отношения к GUI. Это помогло нам принять правильное решение отделить движок от GUI, плюс модульные тесты выступают в качестве нашего интерфейса вместо GUI, запрашивая и предоставляя информацию, которая нам обычно нужна.
Шанс
3

Я хочу , но мне не повезло, что я почти полностью работал в компаниях, которые просто не заботятся о качестве, и более сосредоточены на сборе мусора, который работает своего рода, может быть, если вы косите. Я упомянул юнит-тесты, и я получил "Ха?" своего рода внешний вид (такой же, как у меня, когда я упоминаю принципы SOLID , или ORM, или шаблоны проектирования за пределами «класса со всеми статическими методами» или следуя соглашениям об именах .NET). Я только когда-либо был в одной компании, которая понимала эти вещи, и, к сожалению, это был краткосрочный контракт, и отдел был урезан, чтобы сократить расходы, поэтому не было достаточно времени, чтобы по-настоящему учиться.

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

Уэйн Молина
источник
2

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

Это отличный способ найти те вещи, которые будут пропущены в обзоре кода.

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

Сравните с более чем 40 минутами для тестов автоматизации на уровне системы и часами / днями для ручного тестирования. Конечно, модульные тесты - это не единственное тестирование, которое вы должны выполнять, но на тонком уровне кода они могут помочь найти ошибки и протестировать те крайние случаи , которых не может коснуться системное / интеграционное тестирование. Наш код должен быть протестирован с охватом решений более 75% и с охватом функций 100%, что было бы очень трудно достичь без модульных тестов.

Хьюго
источник
2

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

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

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

Marthinus
источник
2

Затраты: код медленнее, кривая обучения, инерция разработчика

Преимущества: Как правило, я обнаружил, что пишу лучший код при первом тестировании - SOLID мудрый ...

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

Bob_Mac
источник
0

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

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

Philippe
источник
0

Я увидел реальное преимущество в написании модульных тестов и в том, чтобы сделать выполнение модульных тестов частью ежедневного процесса сборки, в проекте с более чем 30 разработчиками, работающими на 3 разных континентах. На самом деле юнит-тесты показывали, когда кто-то тонко меняет класс, который он поддерживает, не понимая, как люди используют этот класс. Вместо того, чтобы ждать, пока код попадет в группу тестирования, была немедленная обратная связь, когда в результате изменения начали проваливаться чужие юнит-тесты. [Вот почему все модульные тесты должны выполняться регулярно, а не только те, которые вы написали для своего кода.]

Мои рекомендации для модульного тестирования:

  1. Протестируйте все условия, которые вы можете придумать для своего кода, включая неверные входные данные, границы и т. Д.
  2. Все модульные тесты для всех модулей должны выполняться регулярно (т.е. как часть ночных сборок)
  3. Проверьте результаты модульного теста!
  4. Если кто-то обнаружит ошибку в вашем коде, которая прошла ваши тесты, напишите новый тест для нее!
jwernerny
источник
0

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

Сложнее всего написать хорошие юнит-тесты.

Это хороший тест для вашего кода.

Schleis
источник