Отличный пример насмешки в реальном времени Берт F
Модульное тестирование
Представьте себе модульное тестирование для этой системы:
cook <- waiter <- customer
Как правило, легко представить тестирование низкоуровневого компонента, такого как cook
:
cook <- test driver
Тест-водитель просто заказывает разные блюда и проверяет, что повар возвращает правильное блюдо для каждого заказа.
Сложнее проверить средний компонент, например официанта, который использует поведение других компонентов. Наивный тестировщик может проверить компонент официанта так же, как мы тестировали компонент повара:
cook <- waiter <- test driver
Тест-водитель заказывает разные блюда и гарантирует, что официант вернет правильное блюдо. К сожалению, это означает, что этот тест компонента официанта может зависеть от правильного поведения компонента приготовления. Эта зависимость еще хуже, если у компонента cook есть какие-либо недружественные к тесту характеристики, такие как недетерминированное поведение (меню включает сюрприз шеф-повара как блюдо), множество зависимостей (cook не готовит без всего своего персонала) или много ресурсы (некоторые блюда требуют дорогих ингредиентов или готовятся в течение часа).
Так как это тест официанта, в идеале мы хотим проверить только официанта, а не повара. В частности, мы хотим убедиться, что официант правильно передает заказ клиента повару и правильно доставляет еду повара.
Под модульным тестированием подразумевается независимое тестирование модулей, поэтому лучшим подходом было бы изолировать тестируемый компонент (официант), используя то, что Фаулер называет тестовыми двойниками (манекены, заглушки, подделки, макеты) .
-----------------------
| |
v |
test cook <- waiter <- test driver
Здесь тест-повар "в сговоре" с тест-драйвером. В идеале тестируемая система спроектирована таким образом, чтобы тестируемый повар мог легко заменить ( впрыскивается ) на работу с официантом без изменения производственного кода (например, без изменения кода официанта).
Макет объектов
Теперь тест готовить (test double) можно реализовать разными способами:
- фальшивый повар - тот, кто притворяется поваром, используя замороженные обеды и микроволновую печь,
- шеф-повар - продавец хот-догов, который всегда дает вам хот-доги, независимо от того, что вы заказываете, или
- фальшивый повар - полицейский под прикрытием, следуя сценарию, изображающему себя поваром в спецоперации.
См. статью Фаулера для более подробной информации о подделках, окурках, мошенничестве, о пустышках , но сейчас давайте сосредоточимся на ложном поваре.
-----------------------
| |
v |
mock cook <- waiter <- test driver
Большая часть модульного тестирования компонента официанта фокусируется на том, как официант взаимодействует с компонентом повара. Подход, основанный на имитации, фокусируется на том, чтобы полностью определить, что такое правильное взаимодействие, и определить, когда оно пошло не так.
фиктивный объект заранее знает, что должно происходить во время теста (например, какие вызовы его методов будут вызваны и т. Д.), А фиктивный объект знает, как он должен реагировать (например, какое возвращаемое значение предоставить) , Насмешка покажет, отличается ли то, что действительно происходит, от того, что должно произойти. Пользовательский фиктивный объект может быть закодирован для ожидаемого поведения каждого тестового примера, но фреймворк стремится к тому, чтобы такая спецификация поведения была четко и легко указана непосредственно в тестовом примере.
Разговор вокруг фиктивного теста может выглядеть следующим образом:
тест-водитель до фальшивый повар : ожидайте заказ хот-дога и дайте ему этот фиктивный хот-дог в ответ
тест-водитель (выдавая себя за клиента) до официант : Хотелось бы хот-дог, пожалуйста
официант до ложный повар : 1 хот-дог, пожалуйста
Ложный повар до официант : оформить заказ: 1 хот-дог готов (дает фиктивного хот-дога официанту)
официант до тест-водитель : вот ваш хот-дог (дает фиктивного хот-дога тест-драйверу)
тестовый водитель : ИСПЫТАНИЕ УСПЕШНО!
Но поскольку наш официант новичок, это может произойти:
тест-водитель до фальшивый повар : ожидайте приказ хот-дога и дайте ему этот фиктивный хот-дог в ответ
тест-водитель (выдавая себя за клиента) до официант : Хотелось бы хот-дог, пожалуйста
Официант до Ложный повар : 1 гамбургер, пожалуйста
Ложный повар останавливает тест: Мне сказали ожидать заказа хот-дога!
тестовый драйвер отмечает проблему: ТЕСТ НЕ ПРОВЕРЕН! - официант изменил порядок
или
тест-водитель до фальшивый повар : ожидайте приказ хот-дога и дайте ему в ответ этот фиктивный хот-дог
тест-водитель (выдавая себя за клиента) до официант : Хотелось бы хот-дог, пожалуйста
Официант до Ложный повар : 1 хот-дог, пожалуйста
Ложный повар до Официант : Заказ: 1 хот-дог готов (дает фиктивного хот-дога официанту)
официант до тестовый водитель : вот ваш картофель фри (дает картофель фри из какого-то другого заказа для тестирования водителя)
тест-водитель отмечает неожиданную картошку фри: ТЕСТ НЕ ПРОВЕРЕН! официант вернул неправильное блюдо
Может быть трудно ясно увидеть разницу между фиктивными объектами и заглушками без контрастирующего примера на основе заглушек, но этот ответ уже слишком длинный: -)
Также обратите внимание, что это довольно упрощенный пример, и что фреймворк-фреймворки позволяют использовать довольно сложные спецификации ожидаемого поведения компонентов для поддержки всесторонних тестов. Для получения дополнительной информации имеется множество материалов о фиктивных объектах и фреймворках.