Я согласен со многими из вышеперечисленных, касающихся юнит-тестирования. Тем не менее, я думаю, что важно подчеркнуть, что использование репозиториев Mock и модульных тестов не дает такого же уровня тестов, как тест на интеграцию с БД.
Например, наши базы данных часто имеют каскадные удаления, встроенные прямо в схему. В этом случае удаление первичного объекта в совокупности автоматически удалит все дочерние объекты. Однако это не будет автоматически применяться в фиктивном репозитории, для которого не была создана резервная копия физической базы данных с этими бизнес-правилами (если только вы не встроили все эти правила в Mock). Это важно, потому что, если кто-то придет и изменит дизайн моей схемы, мне нужно, чтобы он сломал мои тесты, чтобы я мог соответствующим образом скорректировать код / схему. Я ценю, что это интеграционное тестирование, а не модульное тестирование, но подумал, что стоит упомянуть.
Мой предпочтительный вариант - создать базу данных Master Design, которая содержит образцы данных (те же данные, которые вы создали бы в своих макетах). В начале каждого теста у меня есть автоматический скрипт, который создает резервную копию MasterDB и восстанавливает ее до «TestDB» (который используют все мои тесты). Таким образом, я поддерживаю хранилище чистых тестовых данных в Master, а затем воссоздаю себя при каждом запуске теста. Мои тесты могут поиграться с данными и протестировать все необходимые сценарии.
Когда я отлаживаю приложение, у меня есть другой сценарий, который выполняет резервное копирование и восстанавливает основную базу данных в базу данных DEV. Я тоже могу поиграть с данными, не беспокоясь о потере данных. Обычно я не запускаю этот конкретный сценарий каждую сессию из-за задержки ожидания восстановления БД. Я могу запустить его один раз в день, а затем поиграть / отладить приложение в течение дня. Если, например, я удаляю все записи из таблицы как часть моей отладки, я запускаю сценарий для воссоздания DevDB, когда я закончу.
Эти шаги звучат так, как будто они затрачивают огромное количество времени на процесс, но на самом деле - нет. Наше приложение в настоящее время имеет около 3500 тестов, причем около 3000 из них в какой-то момент обращаются к БД. Резервное копирование и восстановление базы данных обычно занимает около 10-12 секунд в начале каждого теста. И поскольку весь набор тестов выполняется только после проверки TFS, мы не возражаем, если нам все равно придется подождать немного дольше. В среднем весь наш тестовый набор занимает около 15-20 минут.
Я ценю и принимаю, что интеграционное тестирование намного медленнее, чем модульное тестирование (из-за неотъемлемой необходимости использовать реальную БД), но оно более близко представляет приложение «реального мира». Например, репозитории Mock не возвращают коды ошибок БД, время ожидания не истекает, они не блокируются, им не хватает места на диске и т. Д.
Модульные тесты подходят для простых вычислений, базовых бизнес-правил и т. Д. И, безусловно, являются абсолютно лучшим выбором для большинства операций, не требующих доступа к БД (или другим ресурсам). Но я не думаю, что они так же ценны, как интеграционные тесты - люди много говорят о модульных тестах, но мало сказано об интеграционных тестах.
Я ожидаю, что те, кто увлечен юнит-тестами, отправят пламя для этого. Это нормально - я просто пытаюсь найти некоторый баланс и напомнить людям, что проекты, которые полны пройденных модульных тестов, могут все еще плохо провалиться, даже если вы внедрите их в полевых условиях.