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

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

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

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

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

Мое беспокойство - то, что мы не находим настоящую проблему, пока мы не тестируем A и B togther, т.е. Интеграционное тестирование. Так как интеграционный тест предоставляет страховую защиту по области модульного теста, это походит на трату усилия создать все эти модульные тесты, которые действительно ничего не говорят нам (или очень) значимый.

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

29
задан Charles 8 August 2012 в 17:57
поделиться

12 ответов

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

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

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

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

23
ответ дан 28 November 2019 в 01:17
поделиться

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

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

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

5
ответ дан 28 November 2019 в 01:17
поделиться

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

3
ответ дан 28 November 2019 в 01:17
поделиться

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

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

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

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

4
ответ дан 28 November 2019 в 01:17
поделиться

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

10
ответ дан 28 November 2019 в 01:17
поделиться

Хорошо, модульные тесты не найдут всех проблем, поэтому у нас есть и интеграционные тесты!

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

5
ответ дан 28 November 2019 в 01:17
поделиться

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

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

3
ответ дан 28 November 2019 в 01:17
поделиться

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


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

2
ответ дан 28 November 2019 в 01:17
поделиться

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

0
ответ дан 28 November 2019 в 01:17
поделиться

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

1
ответ дан 28 November 2019 в 01:17
поделиться

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

2
ответ дан 28 November 2019 в 01:17
поделиться

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

5
ответ дан 28 November 2019 в 01:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: