TDD и модульное тестирование в настоящий момент являются самым восторженным событием. Но действительно ли это полезно по сравнению с другими формами автоматизированного тестирования?
Интуитивно понятно, что автоматическое интеграционное тестирование гораздо полезнее, чем модульное тестирование. По моему опыту, большинство ошибок, кажется, связано с взаимодействием между модулями, а не с реальной (обычно ограниченной) логикой каждого модуля. Также регрессия часто происходила из-за изменения интерфейсов между модулями (и изменения предварительных и постусловий).
Я что-то не так понимаю, или почему модульное тестирование уделяет так много внимания по сравнению с интеграционным тестированием? Просто потому, что предполагается, что интеграционное тестирование - это то, что у вас есть, а модульное тестирование - это следующая вещь, которую нам нужно научиться применять в качестве разработчиков?
Или, может быть, модульное тестирование просто дает наибольший выигрыш по сравнению со сложностью его автоматизации?
Как вы оцениваете автоматизированное модульное тестирование, автоматизированное интеграционное тестирование и автоматическое приемочное тестирование, а также что, по вашему опыту, привело к наивысшей рентабельности инвестиций? и почему?
Если бы вам пришлось выбрать только одну форму тестирования для автоматизации в вашем следующем проекте, что бы это было?
Заранее спасибо.
источник
Ответы:
Одним из важных факторов, который делает модульные тесты чрезвычайно полезными, является быстрая обратная связь .
Подумайте, что происходит, когда ваше приложение полностью покрыто интеграционными / системными / функциональными тестами (это уже идеальная ситуация, далекая от реальности в большинстве магазинов разработки). Они часто выполняются специальной группой тестирования.
Это все может занять дни или даже недели. К этому времени вы уже работали над другими задачами, поэтому у вас в голове нет мельчайших деталей кода, написанного ранее. Более того, у вас, как правило, даже нет прямых доказательств того, где на самом деле находится ошибка, так что поиск и устранение ошибки занимает значительное время.
В то время как в модульном тестировании (TDD)
Все это происходит в считанные минуты .
Это не означает, что интеграционные / системные тесты бесполезны; они просто служат разным целям. С хорошо написанными модульными тестами вы можете выявить большую часть ошибок в коде, прежде чем они перейдут к фазе интеграции, где найти и исправить их уже значительно дороже. Вы правы в том, что интеграционные тесты необходимы для выявления тех типов ошибок, которые сложно или невозможно обнаружить с помощью модульных тестов. Однако, по моему опыту, они встречаются реже; большинство ошибок, которые я видел, вызвано каким-то простым или даже тривиальным упущением где-то внутри метода.
Не говоря уже о том, что модульное тестирование также проверяет ваши интерфейсы на удобство использования / безопасность и т. Д., Что дает вам жизненно важную обратную связь для улучшения вашего дизайна и API. ИМХО может значительно снизить шансы ошибок интеграции модуля / подсистемы: чем проще и чище API, тем меньше вероятность недопонимания или упущения.
Окупаемость инвестиций зависит от многих факторов, и, вероятно, главным из них является то, является ли ваш проект новым или устаревшим. С развитием новых технологий мой совет (и опыт пока) заключается в том, чтобы с самого начала проводить модульное тестирование в стиле TDD. Я уверен, что это самый экономически эффективный метод в этом случае.
Однако в унаследованном проекте создание достаточного охвата модульного тестирования является огромным мероприятием, которое будет очень медленным, чтобы приносить выгоды. Более эффективно попытаться охватить наиболее важные функции системными / функциональными тестами через пользовательский интерфейс, если это возможно. (Приложения с графическим интерфейсом для настольных компьютеров могут быть сложны для автоматического тестирования через графический интерфейс, хотя инструменты поддержки автоматического тестирования постепенно улучшаются ...). Это дает вам грубую, но эффективную сеть безопасности быстро. Затем вы можете начать постепенно создавать модульные тесты вокруг наиболее важных частей приложения.
Это теоретический вопрос, и я считаю его бессмысленным. Все виды тестов используются в наборе инструментов хорошего инженера ПО, и все они имеют сценарии, где они незаменимы.
источник
Все виды тестирования очень важны и гарантируют, что различные аспекты системы соответствуют спецификациям. Так что работать задом наперед: «Если бы мне пришлось выбирать один тип тестирования ...», я бы не стал. Модульное тестирование дает мне обратную связь, чем интеграционное тестирование или интерактивное тестирование человеком.
Вот тип / преимущество тестирования, которое мы проводим:
Необязательное, но рекомендуемое тестирование:
Чтобы понять, почему модульное тестирование имеет преимущество перед интеграционным тестированием, вы должны понимать, что дополнительные тесты на порядок должны быть комплексными. Для каждого возможного результата для блока А должен быть тест. То же самое для блока B. Теперь, если оба из них работают вместе для более полного решения, число тестов является комбинаторным. Короче говоря, чтобы проверить каждую перестановку взаимодействия между блоком A и блоком B, вам нужны тесты A * B. Добавьте в единицу C, и количество тестов для трио будет A * B * C.
Именно здесь концепция интерфейсов и границ объектов становится очень важной. Интерфейсы представляют собой определенный контракт. Реализатор интерфейса соглашается , что он будет вести себя определенным образом. Аналогично, потребитель интерфейса соглашается, что он будет использовать реализацию определенным образом. Написав тест, который собирает каждый класс, реализующий интерфейс, вы можете легко проверить, что каждая реализация соблюдает контракты интерфейса. Это половина уравнения. Другая половина - тестирование на стороне потребителя - именно здесь играют роль ложные объекты. Макет настроен на то, чтобы взаимодействия всегда были в спецификации. На данный момент все, что нужно, это несколько интеграционных тестов, чтобы убедиться, что у нас есть правильные контракты между разработчиком и потребителем.
источник
Это разные инструменты с разными целями:
Модульное тестирование - это инструмент проектирования (TDD) и почти обязательное условие для рефакторинга.
Интеграционные тесты хороши для визуализации прогресса проекта, а также для избежания ошибок регрессии.
Следует помнить, что вы не можете по-настоящему проектировать с помощью интеграционных тестов и не найдете регрессий с помощью модульных тестов.
источник
Я широко использовал Selenium для проверки работоспособности.
В крупной веб-издательской компании, когда создавался новый выпуск, обычно требовалось около 3-х тестеров в течение часа или двух, чтобы посетить все семейства сайтов и убедиться, что все в порядке, согласно тестовому сценарию. С Selenium мы смогли автоматизировать тестирование и распределить его по нескольким машинам и браузерам. В настоящее время, когда запускаются тестовые сценарии, 3 компьютерам требуется около 10 минут, чтобы автоматически сделать то же самое и выпустить симпатичный отчет.
Самое замечательное в селене - то, что вы можете связать его с инфраструктурами модульного тестирования, такими как XUnit, TestNG или MSTest.
По моему опыту, это было чрезвычайно ценно, однако настройка чего-то подобного действительно зависит от вашего проекта и вашей команды, поэтому рентабельность инвестиций определенно будет отличаться.
источник
Лучшая рентабельность инвестиций - это, как правило, самое раннее тестирование, которое может обнаружить этот тип ошибки
Модульное тестирование должно найти большинство ошибок, которые есть только в одном методе или, возможно, в одном компоненте. Он находит ошибки, которые обычно могут быть исправлены за считанные минуты, с общим временем оборота менее одного часа. ОЧЕНЬ дешевые тесты, ОЧЕНЬ дешевые ошибки, чтобы найти и исправить! Если эти ошибки превращают это в интеграционное тестирование, оборот может быть больше похож на день (тестовые прогоны часто происходят ночью), при условии, что ошибка не закрыта другой ошибкой; плюс, вероятно, будет введено больше ошибок, так как другой код был написан против исходного глючного кода; плюс любые изменения будут влиять на большее количество кода. Кроме того, устранение большего количества ошибок означает необходимость выполнения гораздо большего количества тестовых прогонов, прежде чем можно будет завершить интеграционное тестирование. Плохое модульное тестирование часто лежит в основе долгого, обременительного, дорогоготестовые интеграционные циклы. Пропуск модульного тестирования может вдвое сократить время разработки, но тестирование займет по крайней мере в 3-4 раза больше, весь проект удвоится в длине, и у вас все равно будет более низкое качество, чем если бы вы тестировали модуль IME.
Интеграционное тестирование, как правило, является самым ранним реальным тестированием, в котором могут быть обнаружены ошибки интеграции (хотя процессы проверки могут обнаружить некоторые ошибки до того, как будет написано программное обеспечение, или до того, как код будет проверен). Вы хотите найти эти ошибки до того, как начнете показывать программное обеспечение пользователю или выпуску, поскольку исправление ошибок в последний момент (или оперативное исправление!) Очень дорого. Вы не можете найти эти ошибки раньше, когда их будет дешевле исправить, потому что вам нужно несколько рабочих компонентов для интеграции (по определению). Интеграционное тестирование замедляется, когда ошибки, которые не имеют ничего общего с взаимодействующими частями (например, мелкие опечатки), должны быть устранены в первую очередь, прежде чем начнется более интересное тестирование.
Приемочное тестирование пользователя гарантирует, что программное обеспечение делает то, что хочет клиент (хотя, мы надеемся, клиент был вовлечен все время, чтобы снизить риск обнаружения огромного разрыва между ожиданиями и фактическим программным обеспечением в конце проекта - ОЧЕНЬ дорого !). К тому времени, когда вы дойдете до этого этапа тестирования, вы действительно должны поверить, что большинство ошибок в вашем продукте, по крайней мере, по сравнению со спецификациями, уже найдено. Приемочное тестирование пользователя - это больше подтверждение того, что продукт соответствует потребностям клиента, чем проверка наличия ошибок по сравнению со спецификациями.
Если бы я собирался автоматизировать только один тип тестирования, это было бы модульное тестирование. Интеграционные тесты могут проводиться вручную и проводились многими крупными компаниями годами. Требуется больше времени, чтобы вручную выполнять работу, которая может выполняться компьютером снова и снова, и гораздо дороже для большинства проектов, не говоря уже о скучной и подверженной ошибкам, но это можно сделать. Пользовательские приемочные тесты часто выполняются вручную, поскольку пользователи часто не знают, как автоматизировать свои тесты, в то же время тестируя то, что их волнует. Модульные тесты ДОЛЖНЫ быть автоматизированы. Вы должны иметь возможность запускать все модульные тесты в течение нескольких секунд по запросу так же часто, как каждые несколько минут. Люди просто не могут даже приблизиться к ручным тестам. Не говоря уже о том, что модульные тесты находятся в коде и не могут быть выполнены без вызова их через код, т. Е. Их автоматизации.
Следует иметь в виду, что это форум в первую очередь для разработчиков, а не для тестировщиков. Интеграционное тестирование в основном осуществляется тестерами. Модульное тестирование осуществляется разработчиками. Естественно, разработчики больше говорят о модульном тестировании, чем другие виды тестирования. Это не значит, что они не думают, что другое тестирование важно. Это просто означает, что они на самом деле этого не делают (или делают это реже).
источник
Я чувствую, что приемочные испытания - король в этом сценарии.
Если коммит нарушает приемочные тесты, он должен быть отсортирован.
Приемочные тесты сообщают вам, где находится ваше программное обеспечение, а модульные тесты - нет.
Поэтому модульные тесты могут дать очень ложное чувство безопасности.
источник
Вопрос не столько в том, что важнее, сколько в том, что можно автоматизировать и быстро запустить.
Модульные тесты показывают, подходит ли маленький компонент для определенной цели, и, как правило, он маленький и быстро запускается. Будучи маленькими, они обычно достаточно просты для автоматизации.
Интеграционные тесты показывают, работают ли компоненты вместе. Они, как правило, намного больше, и, возможно, их нелегко автоматизировать. Они могут занять больше времени, чтобы бежать. Есть смысл в том, чтобы запускать их автоматически, но это более сложная задача, и они все равно не будут запускаться так часто.
Приемочные испытания показывают, является ли проект приемлемым или нет. Обычно это невозможно полностью автоматизировать (хотя автоматические тесты могут сыграть свою роль), поскольку обычно невозможно точно и точно сформулировать требования в формальном вопросе, который менее сложен, чем сам исходный код. Приемочное тестирование обычно включает в себя потенциальных пользователей, которые работают с системой и наблюдают, что результаты являются удовлетворительными во всех отношениях, что обычно является частично субъективным. Поскольку приемочные испытания обычно проводятся один раз (разные клиенты, как правило, захотят провести свои собственные приемочные испытания), автоматизировать их на самом деле не стоит.
источник