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

server->get_mysql_session() возвращает временный объект Session. Все временные уничтожаются в конце утверждения, в котором они были созданы.

Поскольку сеанс уничтожается до того, как вы позвоните fetchOne, он терпит неудачу.

Например, этот код:

#include <iostream>
#include <string>

struct A
{
    A() { std::cout << "A()\n"; }
    ~A() { std::cout << "~A()\n"; }
};

std::ostream& operator << (std::ostream& os, const A& a) { os << "\nA<<"; return os; }

int main()
{
    std::cout << "line1\n";
    std::cout << "line2" << A() << "\n";
    std::cout << "line3\n";
}

производит следующий вывод:

line1
A()
line2
A<<
~A()
line3
8
задан Bob Herrmann 17 February 2009 в 15:37
поделиться

11 ответов

Определения

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

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

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

Тестирование системы тестирует целую программную систему. Это отвечает на вопрос "это программное обеспечение, работает, как предназначено?"

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

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

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

Сравнения

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

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

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

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

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

16
ответ дан 5 December 2019 в 04:41
поделиться

Да.

Даже если все "единицы" делают то, что они, как предполагается, делают, это не гарантия, что полная система работает, как разработано.

15
ответ дан 5 December 2019 в 04:41
поделиться

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

от Wiki:

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

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

4
ответ дан 5 December 2019 в 04:41
поделиться

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

2
ответ дан 5 December 2019 в 04:41
поделиться

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

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

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

2
ответ дан 5 December 2019 в 04:41
поделиться

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

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

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

0
ответ дан 5 December 2019 в 04:41
поделиться

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

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

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

1
ответ дан 5 December 2019 в 04:41
поделиться

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

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

1
ответ дан 5 December 2019 в 04:41
поделиться

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

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

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

0
ответ дан 5 December 2019 в 04:41
поделиться

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

1
ответ дан 5 December 2019 в 04:41
поделиться

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

0
ответ дан 5 December 2019 в 04:41
поделиться
Другие вопросы по тегам:

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