Подтвердить что ты не робот

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

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

У меня есть метод A, который вызывает метод B, и они находятся в разных слоях.

Итак, я unit test B, который возвращает null в результате. Поэтому я проверяю, что null возвращается, а unit test проходит. Ницца.

Затем я unit test A, который ожидает, что пустая строка будет возвращена из B. Таким образом, я издеваюсь над слоем B, пустая строка возвращается, тест проходит. Приятно снова. (Предположим, я не понимаю отношения A и B, или что, возможно, два разных человека строят эти методы)

Я забочусь о том, что мы не находим реальной проблемы, пока не проверим A и B togther, т.е. тестирование интеграции. Поскольку тест интеграции обеспечивает охват области unit test, кажется, что это пустая трата усилий для создания всех этих модульных тестов, которые действительно не говорят нам ничего (или очень) значимого.

Почему я не прав?

4b9b3361

Ответ 1

Здесь статья о категоризации тестов с некоторыми аргументами

Я не буду упоминать о преимуществах тестирования в целом, как только мы просто сравниваем модульные тесты и функциональные тесты:

  • Тестирование модулей поможет вам уменьшить область видимости при возникновении ошибки.. Включить в этот сценарий классы C, D, E,..., Z. Если у вас есть только тест интеграции, и он терпит неудачу, где вы начинаете искать? Если у вас нет модульных тестов, вам нужно будет выглядеть повсюду внутри каждого из этих классов и "проводки" между ними (что более узкое пространство). Если у вас были модульные тесты, вам просто нужно проверить электропроводка. В этом случае также было бы плохо, если бы не было каких-либо небольших интеграционных тестов, таких как тестирование только A, B, C и D (так что вы уже знаете, действительно ли "проводка" между ними работает).
  • При модульных тестах вы быстрее выполняете. Это даже более верно, если вы TDD. Вероятно, вы пишете свои тесты после того, как создали все классы A и B. Когда вы запускаете свой тест, способ A и B работает не так свежо в памяти (возможно, вы написали их за неделю до этого - надеюсь, вы не начнете тестирование только когда продукт "закончен" ). Затем вы должны помнить, что вы думали, когда вы их написали. Кроме того, unit test работают быстрее, поэтому вы чаще запускаете их чаще (возможно, автоматически запускаете их каждый раз при сохранении?)
  • Модульные тесты обеспечивают лучшую документацию, как ваш класс должен вести себя. Если вы "обычный программист", вы, вероятно, ненавидите писать документацию. Это заставляет вас писать документацию во время программирования, а заставляет документацию никогда не устаревать (если это так, ваши тесты терпят неудачу). И он также помогает, когда вам нужно изменить код другого пользователя.

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

Ответ 2

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

Ответ 3

Тестирование устройства более тонкое и позволяет точно определять ошибки. Что делать, если A или B не удалось? Как вы узнаете, какой из них был неудачным, если ваш интеграционный тест не удался? И это всего 2 метода - представьте, если вы интегрируете тестирование переднего контроллера веб-приложения, которое загружает несколько моделей и называет кучу методов. Это был бы кошмар, пытающийся точно определить, что пошло не так.

Ответ 4

Я думаю, что основными причинами являются:

1: тесты уровня подразделения дают вам больше информации о том, что не удается.

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

Ответ 5

ОК, модульные тесты не найдут никакой проблемы, поэтому у нас тоже есть интеграционные тесты!

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

Ответ 6

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

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

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

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

Ответ 7

Еще одна причина, по которой я не видел никого другого: Вы не всегда будете поддерживать код, который вы пишете. Предположим, что я написал A и B в отдельных модулях, поэтому что каждый находится в отдельной банке и имеет свой собственный файл сборки maven. Пусть далее предположим, что A - метод Дао, а B - своего рода сервисный уровень. Если я написал даже базовый unit test для моего Dao (возможно, используя тестовую разработку, даже!), У меня гораздо больше уверенности в том, что будущие изменения структуры базы данных и запроса, которые могут повлиять на мое dao, пойманы рано. Если, например, в моей команде другой разработчик должен добавить столбцы в таблицу базы данных, которую использует мой dao, я, конечно, хочу, чтобы они сразу узнали, если это нарушит мои методы dao. Если им нужно подождать, чтобы построить все слои и запустить интеграционный тест, чтобы убедиться, что они просто тратят драгоценное время разработки, на мой взгляд. Как разработчик, я бы скорее запустил 10 секунд unit test 10 раз, чтобы исправить и протестировать любые найденные мною перерывы, чем запустить 2-минутный интеграционный сбор и тест интеграции несколько раз. Очевидно, что времена сильно варьируются в зависимости от размера проекта (и вашего оборудования), но это те случаи, когда я занимаюсь своим текущим проектом.

Ответ 8

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

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

Ответ 9

Укрепление (надеюсь) сообщение Сэмюэля Каррихо...


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

Ответ 10

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

Ответ 11

Интеграционные тесты страдают от формы комбинаторного взрыва: Скажем, метод A имеет 5 различных способов поведения (разные граничные случаи и т.д.)., и поэтому имеет метод B. Если вы проверите их вместе, то в теории существует 25 различных случаев, которые вы должны проверить! Да, многие из них могут оказаться одинаковыми или не могут произойти по той или иной причине, но в основном, чем больше вещей вы испытываете вместе, тем более невозможным становится проверка всех случаев с краями.

Ответ 12

Если A - это запрос, который выполняется в течение 2 часов, и готовит данные для B, который является другим запросом, который работает в течение 2 часов, почему я должен ждать 4 часа, чтобы найти проблему, когда я мог ждать 2? Это не так, это новая идея. Считаете ли вы, что автомобильные компании собирают весь автомобиль, прежде чем посмотреть, работает ли двигатель?