Тестовый разрыв между модулем и интеграцией: интеграция в малом, тестирование интеграции компонентов, тестирование модулей

9

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

Частым сценарий придумывает , где Aи Bкак использовать компонент C. Однако Aи Bимеют несколько иные требования, и делают несколько иные предположения C. Если я разработчик того, Aкак и где я проверяю свои предположения C?

Очевидно, что модульное тестирование Aс использованием поддельных предположений Cподходит для тестирования Aв изоляции, но оно не проверяет сами предположения.

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

Чтобы сформулировать это на более конкретном примере: предположим, что это приложение узла. Aи Bзависит от того, Cчтобы прочитать файл (среди прочего) и сохранить содержимое файла в объекте, переданном в C. Сначала все файлы, которые Cобрабатывают, являются маленькими и могут быть прочитаны синхронно без существенной блокировки. Однако разработчик Bпонимает, что его файлы становятся огромными и ему нужно переключиться Cна асинхронное чтение. Это приводит к спорадической ошибке синхронизации A, которая по-прежнему предполагает Cсинхронное чтение файлов.

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

Я нашел только несколько ссылок на этот тип тестирования. Интеграция в малых , тестирование интеграции компонентов , единицы интеграции тестирования. Это также в некоторой степени относится к направлению тестирования BDD, а не к формальному тестированию модулей TDD.

Как мне заполнить этот пробел? Конкретно - куда мне ставить такие тесты? Как смоделировать входы Aи Cдля «мини» интеграционных тестов? И сколько усилий нужно приложить для разделения проблем тестирования между этими тестами и юнит-тестами? Или есть лучший способ заполнить пробел тестирования?

mjhm
источник
1
Рассматривали ли вы управление версиями модулей AC и использовать какую-либо форму управления зависимостями?
miraculixx
1
@gnat Спасибо за совет. Я сделал вопрос менее расплывчатым.
MJHM
@miraclixx Спасибо за ваше предложение. Не могли бы вы уточнить? Если вы имеете в виду что-то вроде blog.nodejitsu.com/package-dependencies-done-right - я думаю, что это решает другую проблему, чем я спрашиваю. Компоненты, на которые я ссылаюсь, как правило, слишком малы для самостоятельной версии в качестве модуля узла - например, файл компонента Model или Controller. Кроме того, управление версиями дает только подсказки о безопасности и источниках сбоев, а не о явном тестировании на конкретные проблемы.
MJHM

Ответы:

6

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

C должен делать то, что нужно C, и должен быть протестирован, задокументирован и разработан именно для этого. Когда у вас есть ситуация, когда C предназначен для «делать то, что хочет B», у вас возникают оскорбительные отношения, которые становятся очень ясными, когда приходит A и хочет, чтобы C сделал что-то немного другое.

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

Интеграционные тесты не обязательно должны быть «всей программой», хотя они часто так настроены. Они могут быть тестовой установкой, которая запускает A и C вместе, не запуская остальную часть программы (или настолько мало, насколько вы можете избежать). На данный момент я не могу советовать дальше, поскольку это зависит от того, что эти компоненты делают и как они взаимодействуют с остальной частью вашей программы, но обычно это тот случай, когда вы можете написать тестовую установку, которая обеспечивает тестовое покрытие обоих компонентов. Стоит ли делать это, или более эффективно интегрировать тестирование всей программы как одной (даже если вы выполняете подмножество интеграционных тестов) - это вопрос, на который вы можете ответить только вы. Большинство интеграционных тестов состоят из множества разделов, поэтому, надеюсь, вы сможете запустить только те, которые имеют отношение к этим двум компонентам (и если нет,

gbjbaanb
источник
Да, это то, о чем я думаю. Это выходит за рамки и цели модульного тестирования. К сожалению, я не живу в мире программного обеспечения, где зависимые компоненты идеально спроектированы, протестированы и задокументированы. И то небольшое тестирование интеграции, которое мы проводим, обычно является сквозным и выполняется специалистами по обеспечению качества, а не разработчиками исходного кода. Как вы можете догадаться, в миксе есть управленческие и организационные проблемы.
MJHM
Я полагаю, вам нужно будет добавить свои собственные интеграционные тесты, но назовите их модульными тестами, «мы проводим модульное тестирование модуля входа клиента», когда вы запускаете огурец или селен.
gbjbaanb