Если проект покрывает 100% модульных тестов, все еще нужны интеграционные тесты? - PullRequest
8 голосов
/ 17 февраля 2009

Если проект покрывает 100% модульных тестов, все еще нужны интеграционные тесты?

Я никогда не работал над проектом со 100% охватом модульных тестов, но мне интересно, получил ли ваш проект это (или 90%), был ли у вас опыт, что вам все еще нужны интеграционные тесты? (тебе нужно меньше?)

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

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

Спасибо за внимание.

Ответы [ 13 ]

16 голосов
/ 17 февраля 2009

Определения

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

Юнит-тест тестирует отдельный блок в изоляции. Для меня это класс. Модульный тест создаст объект, вызовет метод и проверит результат. Он отвечает на вопрос «выполняет ли мой код то, что я намеревался сделать?»

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

Системный тест тестирует всю систему программного обеспечения. Он отвечает на вопрос «это программное обеспечение работает как задумано?»

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

Обратите внимание, что ни один из этих тестов не отвечает на вопросы типа "это программное обеспечение полезно?" или "это программное обеспечение легко в использовании?"

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

Сравнения

Модульные тесты быстрее и легче писать, быстрее запускать и легче диагностировать. Они не зависят от «внешних» элементов, таких как файловая система или база данных, поэтому они намного проще / быстрее / надежнее. Большинство юнит-тестов продолжают работать при рефакторинге (и хорошие юнит-тесты являются единственным способом безопасного рефакторинга). Они абсолютно требуют, чтобы ваш код был отделен , что сложно, если вы сначала не напишете тест. Эта комбинация факторов делает последовательность Red / Green / Refactor TDD так хорошо работает.

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

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

Рекомендация

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

15 голосов
/ 17 февраля 2009

Да.

Даже если все «юниты» делают то, что должны, они не гарантируют, что вся система работает так, как задумано.

4 голосов
/ 17 февраля 2009

Да, кроме того, есть несколько различных типов покрытия кода

из вики:

  • Охват функций - Была ли выполнена каждая функция в программе?
  • Охват операторов - Была ли выполнена каждая строка исходного кода?
  • Покрытие решения (также известное как Покрытие филиала) - Каждая структура управления (например, оператор if) оценивается как true и false?
  • Охват условий - Каждое логическое подвыражение оценивалось как истинное и ложное (это не обязательно подразумевает покрытие принятием решения)?
  • Модифицированный охват условий / решений (MC / DC) - Были ли выполнены все условия в решении по всем возможным результатам хотя бы один раз? Было ли показано, что каждое условие влияет на результат решения независимо?
  • Путь покрытия - Были ли выполнены все возможные маршруты через заданную часть кода?
  • Охват входа / выхода - Были ли выполнены все возможные вызовы и возвраты функции?

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

2 голосов
/ 29 марта 2017

Я действительно не видел ответа, который охватывал бы эти соображения. Теперь я говорю с точки зрения целостных систем, не с точки зрения развития ЕО, но ... Интеграция - это в основном процесс объединения продуктов более низкого уровня в продукт более высокого уровня. Каждый уровень имеет свой собственный набор требований для соблюдения. Хотя возможно, что некоторые требования одинаковы, общий набор требований будет различным для разных уровней. Это означает, что цели тестирования различны на разных уровнях. Кроме того, среда среды продукта более высокого уровня имеет тенденцию отличаться от среды продукта более низкого уровня (например, тестирование модуля SW может проводиться в среде рабочего стола, тогда как полностью загружаемый элемент SW может тестироваться при загрузке в его компонент HW ). Кроме того, разработчики компонентов более низкого уровня могут не иметь такого же понимания «требований и дизайна», как разработчики продуктов более высокого уровня, поэтому интеграционное тестирование также позволяет в определенной степени подтвердить разработку продукта более низкого уровня.

2 голосов
/ 17 февраля 2009

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

2 голосов
/ 17 февраля 2009

Во-первых, 100% покрытия модульным тестом недостаточно даже на уровне модульного тестирования: вы покрываете только 100% инструкций своего кода. Как насчет путей в вашем коде? А как насчет доменов ввода или вывода?

Во-вторых, вы не знаете, совместим ли выходной сигнал от отправляющего устройства с входным сигналом от его приемного устройства. Это цель интеграционного тестирования.

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

1 голос
/ 17 февраля 2009

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

1 голос
/ 17 февраля 2009

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

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

1 голос
/ 17 февраля 2009

Модульные тесты отличаются от интеграционных тестов.

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

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

0 голосов
/ 14 июня 2011

Не похоже, что это было упомянуто здесь, но вы никогда не сможете получить 100% покрытие модульных тестов (если у вас есть база данных). В момент написания модульного теста для подключения к базе данных и операций CRUD вы только что создали интеграционный тест. Причина в том, что ваш тест теперь имеет зависимость вне отдельных единиц работы. Проекты, над которыми я работал, и разработчики, с которыми я общался, всегда указывали, что оставшиеся 10% - это уровень DAO или сервис. Лучший способ проверить это с помощью интеграционных тестов и фиктивной (в памяти) базы данных. Я видел попытки смоделировать соединения для модульного тестирования DAO, но на самом деле я не вижу в этом смысла - ваш DAO - это просто способ сериализации необработанных данных из одного формата в другой, и ваш менеджер или делегат примут решение как манипулировать им.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...