Тестирование приложений с использованием базы данных .NET
Каков наилучший способ для unit test сложного промежуточного программного обеспечения, зависящего от базы данных? Например. процесс, который считывает данные из нескольких баз данных, манипулирует им, а затем объединяет и записывает его в другие базы данных?
Должны ли базы данных заполняться статическими данными, которые как-то reset выполняются при каждом запуске unit test? Должен ли весь доступ к SQL Server быть каким-то образом издевательством? Разве это не возможно для unit test такого приложения в реальном мире?
Ответы
Ответ 1
Ответ насмехается
Однако способ сделать это я нашел следующее.
Отделите DAL на 2 слоя. Дно просто выполняет атомарное чтение и запись в базы данных - все эти объекты реализуют набор интерфейсов IReadFromDB и IWriteToDB.
Затем вы можете создать свою бизнес-логику чтения и записи на более высоком уровне DAL, а не ссылаться на объекты, которые будут читать и записывать в ссылку базы данных интерфейсы и использовать свойства, чтобы иметь возможность заменить функциональность. Я склонен включать в конструкторы желаемые функциональные объекты, чтобы вещи работали "из коробки", так сказать.
Это заставит его "поменять" функциональность и, таким образом, на unit test бизнес-логику.
Что касается тестирования чтения и записи БД... Я не нашел способ, который не связан с работой.
Обычно я использую другую строку соединения для копии базы данных, а затем записываю код генерации данных и очистки для модульных тестов, чтобы оставить состояние db таким же, как и раньше.
Да, его много времени... однако он не рискует отчуждать клиента. Это зависит от ваших приоритетов.
Кто-то еще упомянул тестирование производительности. Я бы не считал, что это часть unit test. Обычно я делаю это с помощью тестового жгута в сочетании с кодом отладки просто потому, что производительность небольших деталей часто вводит в заблуждение - когда вы переходите к большому изображению, части, которые на самом деле являются проблемами с корпусом, часто не являются частями, которые локализованные испытания будут отмечать в моем опыте.
Ответ 2
Я думаю, что наилучшей практикой является действительно Mock весь доступ к базе данных - просто верните некоторые предопределенные статические данные при вызове - вам не нужно проверять, как работают базы данных - ваша потребность протестировать поведение вашего устройства. Мало ваш unit test взаимодействует с внешним - лучше это.
С издевательством вы сможете проверить, что вызов в базу данных действителен, не вызывая его, поэтому так, как вам кажется, я думаю.
Ответ 3
Я бы рекомендовал насмехаться над уровнем доступа к данным. Преимущество использования mocks в этом случае:
1) единичные тесты будут работать быстрее. Если они должны выполнить полную работу по подключению к db, извлечению данных и т.д., Тогда стоимость станет дорогой. Дорогие тесты = люди перестают их запускать/начинают терять веру в них!
2) Вы можете протестировать широкий спектр сценариев, не испытывая затруднений при настройке подходящих тестовых/статических данных, которые необходимо обеспечить всегда в БД до начала тестов.
3) удаление внешней системы db из уравнения означает, что вы тестируете только код .NET, который хотите протестировать. Нет внешней зависимости.
У вас может быть уровень доступа к данным, который выполняет чистое взаимодействие с db, а затем издевается над этим. Или, используйте mock SqlCommands и т.д. В вашем коде .NET.
Ответ 4
Я думаю, вы должны разделить свои проблемы на разные виды тестов.
- Напишите модульные тесты для логики управления данными, реализованной в .NET. Либо издевайтесь над базами данных, либо полностью разделите логику массива данных с материалами доступа к данным, и просто подайте свою ручную манипуляцию данными с предварительно обработанными входными данными.
- Создайте тест интеграции, который использует весь поток данных. Этот тест также должен быть автоматизирован. Настройте исходную и целевую базы данных (либо из DB script, либо из резервной копии БД) в хорошо известное состояние, запустите свою логику обработки данных, затем проверьте результаты.
- Вы также можете создавать тесты производительности и стресса, если вы имеете дело с большим количеством данных. Вы можете настроить базу данных так же, как и в тесте интеграции, создать кучу тестовых данных, запустить свой компонент и проверить время выполнения или полностью завершить его (например, проблемы сочетанности, взаимоблокировки, и др.)
Ответ 5
У меня есть два метода для кода модульного тестирования, в котором есть зависимости базы данных:
- Макетные объекты, то есть TypeMock
- Пользовательские сценарии SQL, работающие в подписях TestInitialise() и TestCleanup().
С TypeMock я могу подделать данные базы данных, входящие в мой код, что помогает мне запускать мои тесты, не беспокоясь о очистке базы данных или восстановлении резервных копий и т.д. Я использую насмешку над тестированием кода за пределами логики базы данных, но по-прежнему требуются поддельные данные из базы данных.
С пользовательскими сценариями SQL я могу запускать SQL-команды на подпрограмме TestInitialise(), и, когда заканчивается unit test, я выполняю очистку SQL на вкладке TestCleanup(). Я использую этот метод для тестирования кода, где логика базы данных сложнее. Например, мне может потребоваться вставить некоторые строки в таблицы, которые помогут с тестированием кода. Затем на TestCleanup() у меня будут удаленные команды SQL, которые удаляют все записи, которые были вставлены через тег TestInitialise().
Ответ 6
Вы должны попытаться сложить свой код, чтобы вы могли издеваться над действиями своих функций.
Слой, который действительно должен разговаривать с базой данных, может использовать систему настройки данных и работу с ней в рамках транзакции, которую вы откатываете в конце теста.
Ответ 7
Я бы отбросил уровень доступа к данным и затем издевался над ним. С издевательством вы сможете увеличить охват кода ваших тестов. Это также предотвратит идею " Test Cancer", которая будет происходить путем дорогостоящих вызовов в сеть/файловую систему/базу данных, потому что люди перестанут их запускать.
У вас должно быть несколько тестов, которые вызывают в базе данных, но они должны быть ограничены как можно больше.
Ответ 8
В моей работе мы используем Nunit и Typemock для нашего тестирования модуля. Тот факт, что нам не нужно менять наш код для тестов, - большой плюс. Издеваться над DAL - путь.