unit-testing - тесты - интеграционное тестирование




Является ли тестирование единиц стоимостью усилий? (20)

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


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

Каковы некоторые хорошие способы убедить скептически настроенных разработчиков в команде ценности Unit Testing?

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

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

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

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

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

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

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

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

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

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

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


[Я имею в виду, что я не могу видеть выше]

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

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

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

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

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


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

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

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


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

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

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


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

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

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


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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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


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

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

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


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


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

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

и большой ...

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

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


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

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

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

Одним из последних советов было бы не только тестирование вашего кода, но и начало выполнять тест (см. TDD и BDD для более)


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


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

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

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


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

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

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

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


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


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


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

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






unit-testing