Что представляет собой интеграционный тест

У меня есть модульные тесты. Каждый метод тестирования проверяет логический БЛОК функциональности в моей системе. В моих модульных тестах внешние зависимости (db, file и т. Д.) Обрабатываются с помощью Mocks и Fakes.

Теперь я не уверен на 100%, как мне подойти к интеграционному тесту. Должен ли я повторить модульные тесты и заменить их фактическими ресурсами (БД, файлы и т. Д.), Или я должен тестировать более низкоуровневые вещи, такие как:

1) Может пинговать базу данных
2) Может получить одну запись
3) Существует ли файл
и т. Д.

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

Спасибо

РЕДАКТИРОВАТЬ: Я был немного ленив при составлении своего вопроса, я также хотел знать, если мне нужно было протестировать бизнес-логику на этапе интеграции, то как мне настроить свои наборы тестов, чтобы минимизировать повторение тестового кода. Возьмем, к примеру:

[TestMethod] //Unit Tests
public void CanGetData()
{
IRepository rep = new MockRepository();
var result = rep.GetData();
Assert.IsTrue(result != null)
}

[TestMethod] //Integration Test
public void CanGetData()
{
IRepository rep = new Repository(); //real repository
var result = rep.GetData();
Assert.IsTrue(result != null)
}

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


person Community    schedule 08.06.2009    source источник


Ответы (5)


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

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

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

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

person Joseph    schedule 08.06.2009

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

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

person Charlie Martin    schedule 08.06.2009

YMMV очень хорошо с определениями здесь. ИМХО термин «модульное тестирование» пострадал от лингвистического дрейфа. (См. Мое сообщение в блоге об этом Чтобы получить больше информации).

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

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

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

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

Надеюсь это поможет.

person cwash    schedule 08.06.2009
comment
По последним подсчетам в моем текущем проекте мы используем примерно 550 ~ методов модульного тестирования! Так что да, по мере того, как проект прогрессирует, он становится монстром, который нужно поддерживать. Я думаю, что сейчас мы находимся на грани невозврата. Отсюда мой вопрос об интеграционном тестировании и о том, как минимизировать повторение тестового кода. Буду читать ваш блог утром :) - person ; 08.06.2009
comment
Попался. Я могу посочувствовать. :) Я бы поддержал свою точку зрения, что интеграционные тесты не помогут вам поддерживать что-либо, возможно, они усложняют обслуживание. Если вы вводите тест более высокого уровня, убедитесь, что он представляет для вас очевидную ценность! Удачи! - person cwash; 08.06.2009
comment
Чтобы уточнить, у вас может быть меньше повторений реального кода для тестирования данного сценария, но существует много дублирования, связанного с созданием изолированных интеграционных тестов. (то есть настроить всю эту инфраструктуру для test1, запустить test1, разобрать целую часть инфраструктуры. повторить ...) - person cwash; 08.06.2009

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

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

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

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

Обратите внимание, что оба теста можно (и нужно) автоматизировать.

person Aaron Digulla    schedule 08.06.2009

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

Я обычно использую Spring для этой цели, но любой контейнер DI / IoC предоставит вам эту возможность. Это наиболее настраиваемый подход, и он хорошо работает, если вы уже выполняете внедрение зависимостей. Это также хорошо сочетается с идеей разделения двух люксов.

person cwash    schedule 08.06.2009