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

139

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

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

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

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

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

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

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

Кен Песписа
источник
1
Всем спасибо. Я многому учусь здесь. Несколько вещей о моей ситуации, которые я пропустил: все мои проекты - это веб-приложения. Чтобы покрыть весь мой код, я должен был бы использовать автоматизированные тесты пользовательского интерфейса, и это область, в которой я до сих пор не вижу большого преимущества по сравнению с ручным тестированием.
Кен Песписа
1
Мы добились большого успеха в Transactis, используя инструмент тестирования веб-автоматизации Telerik. У нас уже есть десятки ранее ручных тестов браузера, преобразованных в автоматизацию. Автоматизированные тесты намного быстрее, а также полезны для выявления проблем с производительностью вашего веб-сайта.
Джон Кастер
2
Я видел проект, который пытался автоматизировать браузерное тестирование целых веб-страниц. Насколько я могу судить, он не обнаружил ни одной из сотен серьезных ошибок, обнаруженных нами при ручном тестировании, и его разработка и обслуживание стоили огромного количества времени. (Использование Selenium от NUnit). Хуже того, некоторые тесты часто не работают из-за несовместимости браузера и инфраструктуры тестирования.
О'Руни,
1
Это на самом деле не ответ, а просто наблюдение ... ваш аргумент против юнит-тестирования, потому что "требования меняются слишком часто" напоминает мне обратный аргумент, который я слышу, когда работаю: "наши программы настолько статичны, в чем смысл тестирования это почти никогда не меняется! " ;)
Бэйн
2
Автоматизированные тесты пользовательского интерфейса веб-приложения - это не модульные тесты, это совсем другое животное, и я бы не стал винить вас, если вы не хотите их выполнять. Но весь ваш бизнес-код должен быть в бэкэнде, и это то, что вы должны проверить.
Nyamiou The Galeanthrope

Ответы:

85

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

Так? Вам не нужно проверять все . Просто актуальные вещи.

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

Это на самом деле неверно. Это не более эффективно. Это действительно просто привычка.

То, что делают другие разработчики соло, - это написать эскиз или схему, написать контрольные примеры, а затем заполнить схему окончательным кодом.

Это очень, очень эффективно.

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

Это тоже ложь. Тесты не являются тормозом. Изменения требований - перетаскивание.

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

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

Вы можете пройти ограниченный приемочный тест «вот оно».

Или вы можете пройти несколько юнит-тестов.

Или вы можете иметь оба.

Но независимо от того, что вы делаете, всегда есть тест, чтобы продемонстрировать, что программное обеспечение работает.

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

С. Лотт
источник
8
Мне нравится ваше первое заявление, чтобы проверить только соответствующие вещи. Что касается эффективности ручного и модульного тестирования, я не верю, что мое утверждение полностью ложно, а ваше - полностью верно. Похоже, существует баланс между автоматическим и ручным тестированием для достижения максимальной эффективности.
Кен Песписа
9
@ Кен Песписа: Извините. Я выпил TDD Kool-Aid около двух лет назад (после 30 лет последнего испытания). Теперь я застрял на первом тесте. Это сделало меня намного, намного более продуктивным, потому что я меньше думаю о том, чтобы делать при строительстве
S.Lott
3
@ Кен Песписа: Нет. В ответах есть баланс. Если бы вы спросили, правильно ли делить на ноль, вы получите ошеломляющие ответы, склоняющиеся в одну сторону по какой-то причине. Если бы вы спросили, sqrt(-1)должно ли быть целое число, вы получите ошеломляющие ответы, склоняющиеся в одну сторону. Баланс вокруг «как» и «какой порядок». Сам факт, что вы должны проверить. Поэтому сначала напишите тесты и убедитесь, что они работают.
S.Lott
21
Рассмотрим модульное тестирование интерфейса, а не детали реализации. Проверьте пределы и пограничные случаи. Протестируйте рискованный код. Много кода достаточно просто проверить с помощью проверки, хотя проверка вашего кода более подвержена ошибкам, чем проверка чужого кода. Первое время ручные тесты могут быть более эффективными, а в десятый раз автоматизированные тесты намного впереди.
BillThor
10
«Код не готов, пока тесты не пройдут» - не совсем, ИМО. Код начинается, когда он проходит тесты. Код не выполняется до тех пор, пока он не будет доступен в течение года или двух и не подвергнется стресс-тестам и интеграционным тестам с большой, активной и нетерпеливой базой пользователей. Это единственное испытание, которое действительно имеет значение.
Вектор
108

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

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

Да, вы могли бы сделать все эти вещи! А что будет с вашим кодом со временем? Это будет становиться все чище и чище, потому что не будет никакого риска для его очистки.

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

Как вы думаете, сколько отладки вы бы сделали?

Если это звучит как фантазия, вы правы. Но реальность не сильно отличается. Замените связку глаз несколькими секундами, а фею - дисциплиной TDD, и вы в значительной степени поняли это.

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

Не стоит вложений? Ты наверное шутишь! Как кто-то может НЕ хотеть этот набор тестов? Сделай себе одолжение и прекрати придираться к глупости. Научитесь хорошо выполнять TDD и наблюдайте, насколько быстрее вы идете и насколько чище ваш код.

Дядя Боб.
источник
29
Вау, дядя Боб? Это здорово, чтобы ваши мысли здесь. Я согласен с вами о преимуществах TDD, здесь действительно нет никаких аргументов. Вопрос об инвестициях времени и окупаемости инвестиций. Это не глупо для меня, чтобы рассмотреть эти вещи. Представьте себе, что проект займет у меня на 50% больше времени, чтобы закончить с TDD, чем без, и фея говорит мне, что это сэкономит мне только 10% времени по сравнению с ручным тестированием в течение жизни проекта. Это может показаться фантастикой, но я считаю это вполне правдоподобным в определенных проектах.
Кен Песписа
11
@Ken "Представь, что у меня уйдет на 50% больше времени, чем на TDD, чем без". Это звучит в точности как фантазия для меня. На самом деле, звучит так, будто вы только что создали эту фигуру на месте без малейших доказательств, подтверждающих это.
Рейн Хенрикс
18
@ Рейн Хенрикс - Конечно, я придумал номер, это было гипотетическое утверждение. Я подчеркиваю, что TDD значительно увеличивает время, затрачиваемое на проект, и я должен подумать, получу ли я взамен что-то такое же или лучшее. Вы не должны убеждать меня в ценностях TDD, я убежден. Но это не панацея.
Кен Песписа
11
@ Рейн, что такое «имеющиеся доказательства»? Пожалуйста, дополните.
Кен Песписа
22
@Uncle Bob "Замените глазную ссылку несколькими секундами": Вы, конечно, шутите. TDD - хороший инструмент, но вы должны тестировать только соответствующие части, в противном случае вы тратите больше времени на поддержание тестов, чем на любую серьезную разработку. Это особенно верно, когда требования меняются очень быстро: вы постоянно пишете и выбрасываете тесты для классов, которые постоянно меняются. Я не говорю, что TDD - это плохо, его просто нужно использовать разумно, а не механически, как вы, похоже, предлагаете.
Джорджио
34

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

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

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

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

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

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

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

glenatron
источник
2
@Ken, тестовые наборы - это спецификации в исполняемом виде.
32

У парней из JUnit (фреймворк Java Unit test) есть философия, что если тестирование слишком простое, не тестируйте его . Я настоятельно рекомендую прочитать их часто задаваемые вопросы , так как это довольно прагматично.

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

  1. Написать тест
  2. Смотреть не получится (докажите, что вам есть чем заняться)
  3. Напишите только то, что нужно для прохождения теста - не более.
  4. Смотри, как это проходит (да!)
  5. Рефакторинг (сделать его лучше)
  6. Вымойте, промойте и повторите

Что менее очевидно в применении TDD, так это то, что он меняет способ написания кода . Заставляя себя думать о том, как тестировать / проверять работоспособность кода, вы пишете тестируемый код. И поскольку мы говорим о модульном тестировании, это обычно означает, что ваш код становится более модульным. Для меня модульный и тестируемый код - это большая победа.

Теперь вам нужно протестировать такие вещи, как свойства C #? Представьте себе свойство, определенное так:

bool IsWorthTesting {get; set;}

Ответ будет «нет», его не стоит тестировать, потому что в этот момент вы тестируете языковой компонент. Просто верьте, что ребята на платформе C # поняли это правильно. Кроме того, если это не удалось, то , что может вам сделать , чтобы это исправить?

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

  • Проверены исключения, которые могут возникнуть только в случае неудачной установки. У Java есть тонна этих. Вы должны написать блок перехвата или объявить проверенное исключение, даже если нет способа, как оно может завершиться неудачей, не взломав установленные файлы.
  • Пользовательские интерфейсы. Найти тестируемый элемент управления и вызвать нужные события для имитации действий пользователя очень хлопотно, а в некоторых случаях невозможно. Однако, если вы используете шаблон Модель / Представление / Контроллер, вы можете убедиться, что ваша модель и контроллеры протестированы, и оставить часть вида для ручного тестирования.
  • Клиент-серверные взаимодействия. Это больше не модульный тест, а теперь интеграционный тест. Запишите все части, которые подходят для отправки и получения сообщений по проводам, но на самом деле не переходите по проводам. Хороший подход состоит в том, чтобы уменьшить ответственность кода, который фактически передает по проводам в необработанные коммуникации. В своем коде модульного теста смоделируйте объект связи, чтобы убедиться, что службы работают так, как вы ожидаете.

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

Берин Лорич
источник
24

Вы должны сбалансировать стоимость тестирования со стоимостью ошибок.

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

Функция, которая делает что-то сложное со сложной структурой данных - тогда, очевидно, да.

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

Мартин Беккет
источник
23

Тестирование - это азартная игра.

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

Как и любая ставка, иногда вы выигрываете, иногда вы проигрываете.

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

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

hotpaw2
источник
3
Хороший ответ. Один из немногих, который действительно отвечает на мой оригинальный вопрос. С момента написания этого поста я погрузился в мир тестирования (мне, кстати, нравится). Мне нужно больше понять его, прежде чем я действительно смогу узнать, когда его использовать (или нет). По многим причинам, изложенным здесь, я бы предпочел использовать его постоянно. Но в конечном итоге это будет зависеть от того, насколько быстрее я добьюсь этого, потому что в конечном итоге это игра моего времени, которая находится под контролем моей компании / клиента, и часто они фокусируются на нижних углах треугольника проекта: en. wikipedia.org/wiki/Project_triangle
Кен Песписа,
10

Мой совет - проверять только тот код, который вы хотите работать правильно.

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

Ник Ходжес
источник
9
Напоминает мне высказывание моего дантиста: вам не нужно чистить зубы всеми зубами, только теми, которые вы хотите сохранить.
Кен Песписа
Признаюсь, именно это заставило меня задуматься об этом. ;-)
Ник Ходжес,
8

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

TDD и модульное тестирование - это не одно и то же.

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

TDD - это практика кодирования в петле красного света. Зеленый свет. Рефакторинг итераций.

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

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

Пол Бучер
источник
Не могли бы вы рассказать о том, как исчезают отдельные ошибки? Вы хотите сказать, что сможете быстрее получить ответ о том, является ли индекс массива нулевым или единичным с помощью тестирования, чем при поиске в документации? Кажется маловероятным для меня - я довольно быстро в Google :)
Кен Песписа
1
На самом деле, написание TDD - отличный способ исследовать API (включая унаследованную кодовую базу для целей документирования функциональности).
Фрэнк Шеарар
Также очень полезно, если этот API когда-либо изменится ... У вас вдруг есть несколько неудачных тестов :-)
bitsoflogic
@Ken Pespisa, это определенно быстрее - напиши код, основываясь на том, считаешь ли ты 0 или 1, запусти его, исправь, если нужно. В большинстве случаев вы будете правы, и вы пропустили необходимость искать его, если вы не правы, вы знаете об этом в течение 10 секунд.
Пол Батчер
Очень интересная выгода. Мне это нравится.
Кен Песписа
3

Я работал над системой, где мы тестировали почти все. Примечательными выполнениями для тестирования были выходной код PDF и XLS.

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

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

Сэл
источник
На самом деле, этот вид тестирования, вероятно, является "интеграционным тестированием". И да, интеграционное тестирование намного сложнее, чем модульное тестирование, и одна из причин заключается в том, что иногда правила для того, что является «правильным», очень сложны или даже субъективны.
слеске
2

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

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

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

TL; DR Это действительно никогда не уместно, потому что преимущества слишком хороши.

Стивен Эверс
источник
2

Здесь есть два очень хороших ответа:

  1. Когда проводить юнит-тест против ручного теста
  2. Что не проверить, когда дело доходит до модульного тестирования?

Основания для избежания воспринимаемых накладных расходов:

  • Немедленная экономия времени / средств для вашей компании
  • Потенциальная экономия времени / средств на устранение неисправностей / ремонтопригодность / расширение в долгосрочной перспективе даже после того, как вы ушли.

Вы не хотели бы оставить отличный продукт со своей стороны в качестве доказательства качества своей работы? Если говорить эгоистично, разве тебе не лучше, что ты делаешь?

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

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

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

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

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

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

Стив
источник
Мне нравятся мысли о предотвращении регрессии и добавлении уверенности. Именно поэтому я хотел бы добавить тесты.
Кен Песписа
1

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

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

  1. Частные методы

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

  1. Вещи, которые вы уже знаете, должны работать (или вещи, проверенные кем-то другим)

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

Оба из них могут применяться независимо от того, используете ли вы TDD или нет.

Ravenstine
источник
0

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

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

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

public interface ITest {
    public string Name {
        get;
    }
    public string Description {
        get;
    }
    public List<ITest> SubTests {
        get;
    }
    public TestResult Execute();
}

public class TestResult {
    public bool Succesful {
        get;
        set;
    }

    public string ResultMessage {
        get;
        set;
    }

    private Dictionary<ITest, TestResult> subTestResults = new Dictionary<ITest, TestResult>();
    public Dictionary<ITest, TestResult> SubTestResults {
        get {
            return subTestResults;
        }
        set {
            subTestResults = value;
        }
    }
}

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

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

Удачи!

Адам Карстенсен
источник
Я думаю, что со временем я выясню, какой уровень детализации является лучшим. Приятно слышать от других, которые регулярно создают тесты, что они подходят к нему разумно и не пишут тесты автоматически для каждого возможного результата. Мое первое знакомство с тестами было на том уровне, на котором все должно быть проверено. Фактически, вся концепция TDD, кажется, следует этой мантре.
Кен Песписа
Я думаю, что вы могли бы извлечь выгоду из использования Framework, подобного SubSpec (он основан на BDD), так что это позволит вам получить изоляцию Assert ("SubTest") при совместном использовании настройки контекста.
Йоханнес Рудольф