Какое значение имеет модульное тестирование в среде «Выпуск раннего выпуска часто»?

10

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

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

  1. Вся платформа хорошо интегрирована с установленными сборками / выпусками, работающими на стороне клиента без каких-либо горячих точек.

  2. Новые функциональные требования продолжают поступать, и мы постепенно наращиваем их.

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

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

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

Полезны ли модульные тесты в относительно зрелой системе? Должны ли мы, по крайней мере, взвешивать объем тестов в зависимости от зрелости единиц? Замедлит ли юнит-тестирование темпы разработки? Есть ли необходимость оценивать юнит-тестирование по-другому?

Каковы лучшие практики тестирования для зрелой платформы в среде релиз-ранний-релиз-часто?

Дипан Мехта
источник
Я думаю, что идея состоит в том, чтобы выпустить полуработающий код рано и часто, но «полуработающая» часть неявна. Модульные тесты помогают в этом. Но модульных тестов может быть недостаточно. Вам также может понадобиться сторона интеграционных тестов.
ccoakley

Ответы:

15

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

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

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

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

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

Док Браун
источник
«Это часто приводит к тому, что написание модульных тестов усложняется, потому что им часто приходится предоставлять более сложную среду и больше тестовых данных». <- Для простой системы модульный тест должен быть таким же простым, как и для сложной. Вам не нужно больше полудюжины установок для каждого класса. В противном случае это просто означает, что ваш класс стал слишком большим. Кроме того, модульный тест не должен быть привязан к какой-либо среде. (Но вы, вероятно, уже знаете это, просто говорите ...)
Спящий Смит
@SleeperSmith: да, и для того, чтобы можно было писать такие простые модульные тесты, неплохо было бы применить DI и ISP - это именно то, что я написал выше. Извините, если я не был достаточно ясен в этом.
Док Браун
4

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

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

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


источник
3

Как предполагают Док Браун и Торбьерн Равн Андерсен , среда раннего выпуска Release часто может получить еще большую выгоду от хорошего модульного тестирования и разработки, основанной на тестировании, чем среда с длинными циклами выпуска.

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

Марк Бут
источник