Определенно хороший список. Вот несколько мыслей по этому поводу:
Напишите сначала тест, а затем код.
Согласен, на высоком уровне. Но я был бы более конкретным: «Сначала напишите тест, затем напишите достаточно кода, чтобы пройти тест, и повторите». В противном случае я бы побоялся, что мои модульные тесты будут больше похожи на интеграционные или приемочные тесты.
Классы проектирования с использованием внедрения зависимостей.
Согласовано. Когда объект создает свои собственные зависимости, вы не можете их контролировать. Инверсия управления / внедрения зависимостей дает вам этот контроль, позволяя изолировать тестируемый объект с помощью mocks / stubs / и т. Д. Вот как вы тестируете объекты изолированно.
Отделите код пользовательского интерфейса от его поведения с помощью Model-View-Controller или Model-View-Presenter.
Согласовано. Обратите внимание, что даже презентатор / контроллер можно протестировать с использованием DI / IoC, передав ему заглушку / имитацию представления и модели. Ознакомьтесь с Presenter First TDD, чтобы узнать больше об этом.
Не пишите статические методы или классы.
Не уверен, что согласен с этим. Можно провести модульное тестирование статического метода / класса без использования моков. Так что, возможно, это одно из тех особых правил Rhino Mock, о которых вы упомянули.
Программируйте интерфейсы, а не классы.
Я согласен, но по несколько другой причине. Интерфейсы предоставляют разработчику программного обеспечения большую гибкость - помимо поддержки различных фреймворков фиктивных объектов. Например, невозможно правильно поддерживать DI без интерфейсов.
Изолируйте внешние зависимости.
Согласовано. Скрывайте внешние зависимости за собственным фасадом или адаптером (при необходимости) с помощью интерфейса. Это позволит вам изолировать ваше программное обеспечение от внешней зависимости, будь то веб-служба, очередь, база данных или что-то еще. Это особенно важно, когда ваша команда не контролирует зависимость (или внешнюю).
Отметьте как виртуальные методы, над которыми вы собираетесь издеваться.
Это ограничение Rhino Mocks. В среде, которая предпочитает закодированные вручную заглушки над фреймворком имитирующих объектов, в этом нет необходимости.
И пара новых моментов, которые следует учитывать:
Используйте творческие шаблоны проектирования. Это поможет с DI, но также позволит изолировать этот код и протестировать его независимо от другой логики.
Напишите тесты, используя технику Билла Уэйка Arrange / Act / Assert . Этот метод дает очень четкое представление о том, какая конфигурация необходима, что на самом деле тестируется и что ожидается.
Не бойтесь накатывать собственные макеты / заглушки. Часто вы обнаружите, что использование фреймворков фиктивных объектов делает ваши тесты невероятно трудными для чтения. Создавая собственный, вы получите полный контроль над своими макетами / заглушками и сможете сохранить читабельность ваших тестов. (Вернитесь к предыдущему пункту.)
Избегайте соблазна реорганизовать дублирование ваших модульных тестов в абстрактные базовые классы или методы установки / удаления. Это скрывает код конфигурации / очистки от разработчика, пытающегося проверить модульный тест. В этом случае ясность каждого отдельного теста важнее, чем рефакторинг дублирования.
Реализуйте непрерывную интеграцию. Отметьте свой код на каждой «зеленой полосе». Создайте свое программное обеспечение и запускайте полный набор модульных тестов при каждой регистрации. (Конечно, это не практика программирования как таковая; но это невероятный инструмент для поддержания чистоты и полной интеграции вашего программного обеспечения.)