Достаточно ли юнит-тестов и приемочных испытаний? - PullRequest
9 голосов
/ 18 мая 2009

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

Например, если у меня есть юнит-тесты и приемочные тесты для функции, мне все еще нужны интеграционные тесты или должны ли блок и приемочные тесты охватывать одно и то же основание? Есть ли совпадение между типами тестов?

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

Ответы [ 12 ]

13 голосов
/ 18 мая 2009

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

Нет. Тесты могут подтвердить только то, что вы подумали. Не то, о чем ты не думал.

8 голосов
/ 18 мая 2009

Я бы рекомендовал прочитать главы 20 - 22 во 2-м издании Code Complete . Он очень хорошо охватывает качество программного обеспечения.

Вот краткий обзор некоторых ключевых моментов (вся заслуга Макконнелла, 2004)

Глава 20 - Пейзаж качества программного обеспечения:

  • Ни один метод обнаружения дефектов сам по себе не является полностью эффективным
  • Чем раньше вы обнаружите дефект, тем меньше он будет переплетен с остальной частью вашего кода и тем меньше повреждений он нанесет

Глава 21 - Совместное строительство:

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

Глава 22 * ​​1030 * - Тестирование разработчика:

  • Автоматическое тестирование в целом полезно и необходимо для регрессионного тестирования
  • Лучший способ улучшить процесс тестирования - сделать его регулярным, измерить его и использовать то, что вы узнали, для его улучшения
  • Написание тестовых примеров до того, как код отнимает столько же времени и усилий, сколько и написание тестовых примеров после кода, но это сокращает циклы обнаружения-отладки-исправления дефектов (Test Driven Development)

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

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

8 голосов
/ 18 мая 2009

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

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

Приемочные испытания должны проводиться клиентом для обеспечения соответствия системы требованиям.

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

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

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

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

3 голосов
/ 18 мая 2009

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

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

2 голосов
/ 18 мая 2009

Многоуровневое тестирование может быть очень полезным. Модульные тесты, чтобы убедиться, что части ведут себя; интеграция, чтобы показать, что кластеры взаимодействующих подразделений взаимодействуют, как ожидается, и «приемочные» тесты, чтобы показать, что программа функционирует, как и ожидалось. Каждый может поймать проблемы во время разработки. Перекрытие само по себе не так уж и плохо, хотя слишком много его становится бесполезным.

Тем не менее, печальная истина заключается в том, что вы никогда не сможете гарантировать, что продукт будет вести себя «как ожидалось», потому что ожидание - это непостоянная, человеческая вещь, которая очень плохо переводится на бумагу. Хорошее тестовое покрытие не помешает клиенту сказать «это не совсем то, что я имел в виду ...». Частые петли обратной связи помогают там. Рассматривайте частые демонстрации как «тест на здравомыслие», добавляемый к вашему ручному миксу.

1 голос
/ 30 ноября 2010

Вероятно, нет, если ваше программное обеспечение действительно, действительно просто и имеет только один компонент.

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

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

Вам также следует рассмотреть следующие виды тестов, которые обычно пишутся тестерами:

  • Функциональные тесты, которые охватывают части функциональности. Это может включать тестирование API и тестирование на уровне компонентов. Вам, как правило, здесь также потребуется хорошее покрытие кода.
  • Интеграционные тесты, которые объединяют два или более компонентов, чтобы убедиться, что они работают вместе. Вы не хотите, чтобы один компонент выставлял позицию в массиве, где находится объект (на основе 0), когда другой компонент ожидает счетчика объекта (например, «n-й объект», который основан на 1). Здесь основное внимание уделяется не покрытию кода, а покрытию интерфейсов (общих интерфейсов, а не интерфейсов кода) между компонентами.
  • Тестирование на уровне системы, где вы собираете все вместе и проверяете, что оно работает непрерывно.
  • Тестирование на нефункциональные функции, такие как производительность, надежность, масштабируемость, безопасность и удобство для пользователя (есть и другие; не все будут относиться к каждому проекту).
0 голосов
/ 06 октября 2015

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

Модульные и небольшие интеграционные тесты (состоящие из модульных тестов) предназначены для построения устойчивой системы.

Не пытайтесь написать тест для каждой части системы. Это хрупко (легко ломается) и подавляет.

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

0 голосов
/ 18 мая 2009

Если у меня есть модульные тесты для каждого класса и / или функция-член и принятие тесты для каждой пользовательской истории у меня есть достаточно тестов для обеспечения проекта функционирует как положено?

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

0 голосов
/ 18 мая 2009

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

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

Стоит также отметить, что разные наборы тестов имеют тенденцию тестировать продукт / код с другой «точки зрения». Почти так же, как QA может обнаруживать ошибки, которые dev никогда не проверял, один набор тестов может находить то, что другой набор не смог бы.

0 голосов
/ 18 мая 2009

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

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

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

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

...