Должен ли я практиковать «mockist» или «классический» TDD? - PullRequest
37 голосов
/ 09 октября 2008

Я прочитал (и перечитал) Мартина Фаулера Насмешки - это не заглушки . В нем он определяет два разных подхода к TDD: «Классический» и «Mockist» . Он пытается ответить на вопрос « Так я должен быть классиком или mockist? », но он признает, что он никогда не пробовал TDD mockist на «что-то большее, чем игрушки». Поэтому я решил задать вопрос здесь. Хорошие ответы могут повторять аргументы Фаулера (но, надеюсь, более четко) или добавлять аргументы, о которых он не думал или о которых другие придумали с тех пор, как Фаулер в последний раз обновил эссе в январе 2007 года.

Ответы [ 5 ]

37 голосов
/ 09 октября 2008

Не думаю, что вам нужно выбирать одно над другим. Оба имеют свои преимущества и недостатки, и оба являются инструментами для вашей панели инструментов. «Mockist» tdd делает вас немного более гибким в том, что вы можете тестировать, в то время как классический TDD делает ваши тесты немного менее хрупкими, потому что они имеют тенденцию больше смотреть на ввод / вывод вместо того, чтобы смотреть на фактическую реализацию. При выполнении модульного тестирования mockist у меня, похоже, больше тестов прерывается при изменении реализации.

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

Это все довольно абстрактно, так что я надеюсь, что в этом есть смысл.

23 голосов
/ 21 октября 2008

Вопрос о mockist или classic tdd очень сильно связан с тем, какую часть вашего приложения вы тестируете. Если у вас есть «стандартная» многоуровневая архитектура (например, DDD ), уровень домена обычно подходит для классического tdd, где вы проводите модульное тестирование, настраивая тестируемый объект, вызывая несколько методов и проверяя результат. и / или государство.

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

Мой совет: всегда будь классическим и издевайся, когда нужно.

14 голосов
/ 21 мая 2009

Вы можете посмотреть нашу книгу по адресу http://www.growing -object-oriented-software.com / . Включает расширенный обработанный пример. Когда мы это писали, мы обнаружили, что различие между состоянием и взаимодействием в значительной степени вводит в заблуждение, и это больше касается подхода к проектированию ОО.

5 голосов
/ 24 марта 2014

Сэнди Мец показал очень прагматичный подход:

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

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

enter image description here

Проверьте ссылки

http://jnoconor.github.io/blog/2013/10/07/the-magic-tricks-of-testing-by-sandi-metz/

https://speakerdeck.com/skmetz/magic-tricks-of-testing-ancientcityruby

Youtube

2 голосов
/ 20 октября 2008

Я все еще относительно новичок в TDD, но способ, которым меня учили / знакомили с различиями, заключался в том, чтобы думать об этом с точки зрения тестирования интеграции между классами, чтобы вы не зависели от реальных данных. Например, если у меня есть класс, который является в значительной степени автономным - не зависящим от других классов, которые я создал для проекта, и он не выходит в живую среду data / dev для ввода (например, БД или API для система), тогда я бы использовал классические модульные тесты только в чем-то вроде NUnit или JUnit - но когда я начинаю тестировать взаимодействие между встроенными классами - тогда очень удобно имитировать другие пользовательские классы и / или внешние взаимодействия - так что вы может выделить и протестировать код ваших текущих классов, не пытаясь выявить потенциальную ошибку в других классах, которые вы вызываете.

...