Модульное тестирование баз данных .NET приложений - PullRequest
17 голосов
/ 10 июля 2009

Каков наилучший способ для модульного тестирования промежуточного ПО .NET, зависящего от базы данных? Например. процесс, который считывает данные из нескольких баз данных, манипулирует ими, а затем объединяет и записывает их в другие базы данных?

Должны ли базы данных заполняться статическими данными, которые каким-то образом сбрасываются при каждом запуске модульного теста? Должен ли весь доступ к SQL Server быть каким-то образом смоделированным? Разве не представляется возможным провести модульное тестирование такого приложения в реальном мире?

Ответы [ 8 ]

5 голосов
/ 10 июля 2009

насмешливый ответ

Однако я нашел следующий способ сделать это:

Разделите DAL на 2 слоя. Дно просто выполняет атомарное чтение и запись в базы данных - все эти объекты реализуют набор интерфейсов IReadFromDB и IWriteToDB.

Затем вы можете создать свою бизнес-логику для чтения и записи на более высоком уровне DAL, но не ссылаться на объекты, которые будут считывать и записывать в базу данных, ссылаться на интерфейсы и использовать свойства, чтобы иметь возможность заменять функциональность. Я склонен включать нужные конструкторы в конструкторы, чтобы все работало «из коробки», так сказать.

Это позволит легко «поменять» функциональность и провести модульное тестирование бизнес-логики.

Что касается тестирования чтения и записи БД ... Я не нашел способа, который не требовал бы работы. Я обычно использую другую строку подключения к копии базы данных, а затем пишу генерацию данных и код очистки для модульных тестов, чтобы оставить состояние базы данных таким же, как до и после.

Да, это отнимает много времени ... однако это не рискует оттолкнуть клиента. Это зависит от ваших приоритетов.

Кто-то еще упомянул тестирование производительности. Я бы не стал считать это частью модульного теста. Я обычно делаю это с помощью тестового набора в сочетании с отладочным кодом просто потому, что производительность мелких деталей часто вводит в заблуждение - когда вы переходите к общей картине, части, которые на самом деле являются проблемами с корпусом, часто не являются частями, которые локализованное тестирование отметит в моем опыте .

2 голосов
/ 10 июля 2009

Я думаю, что на самом деле лучше всего проверять весь доступ к базе данных - просто возвращать некоторые заранее определенные статические данные при вызове - вам не нужно проверять работу баз данных - вам нужно проверить поведение вашего модуля. Чем меньше ваш юнит-тест взаимодействует с внешним миром, тем лучше.

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

1 голос
/ 10 июля 2009

У меня есть два метода для модульного тестирования кода, который зависит от базы данных:

  • Макет объектов, т.е. TypeMock
  • Пользовательские сценарии SQL, работающие в подпрограммах TestInitialise () и TestCleanup ().

С TypeMock я могу подделывать данные базы данных, поступающие в мой код, что помогает мне выполнять свои тесты, не беспокоясь об очистке базы данных, восстановлении резервных копий и т. Д. Я использую насмешки для тестирования кода вне логики базы данных, но по-прежнему требуются поддельные данные из базы данных.

С помощью пользовательских сценариев SQL я могу запускать команды SQL в подпрограмме TestInitialise (), а после завершения модульного теста у меня запускается очистка SQL в подпрограмме TestCleanup (). Я использую этот метод для тестирования кода, где логика базы данных более сложна. Например, мне может понадобиться вставить несколько строк в таблицы, которые помогут с тестированием кода. Затем в TestCleanup () у меня будут команды SQL для удаления, которые удаляют все записи, которые были вставлены с помощью подпрограммы TestInitialise ().

1 голос
/ 10 июля 2009

Я думаю, вы должны разделить свои проблемы на различные виды испытаний.

  • Написание модульных тестов для логики манипулирования данными, реализованной в .NET. Или смоделируйте базы данных, или полностью отделите логику массирования данных от всего, что нужно для доступа к данным, и просто подпишите вашу процедуру манипулирования данными предварительно запеченными входными данными.
  • Создать интеграционный тест, который выполняет весь поток данных. Этот тест также должен быть автоматизирован. Установите исходную и целевую базы данных (из сценария БД или из резервной копии БД) в хорошо известное состояние, запустите логику манипулирования данными, а затем проверьте результаты.
  • Возможно, вы захотите создать тесты производительности и стресс-тестирования, если вы работаете с большим количеством данных. Вы можете настроить базу данных так же, как в интеграционном тесте, сгенерировать кучу тестовых данных, запустить свой компонент и проверить либо время выполнения, либо его полное выполнение (например, отсутствие проблем с параллелизмом, взаимоблокировки, и др.)
1 голос
/ 10 июля 2009

Я бы порекомендовал издеваться над уровнем доступа к данным. Преимущество использования макетов в этом случае включает: 1) модульные тесты будут выполняться быстрее. Если им придется выполнить всю работу по подключению к БД, извлечению данных и т. Д., Тогда стоимость станет дорогой. Дорогие тесты = люди перестают их запускать / начинают терять веру в них! 2) Вы можете протестировать широкий спектр сценариев без необходимости настраивать подходящие тестовые / статические данные, которые всегда должны быть в БД до начала тестирования. 3) удаление внешней системы БД из уравнения означает, что вы тестируете только тот код .NET, который хотите протестировать. Нет внешней зависимости.

Вы можете иметь слой доступа к данным, который выполняет чистое взаимодействие с БД, а затем высмеивать его. Или используйте фиктивные SqlCommands и т. Д. В своем коде .NET.

0 голосов
/ 15 июля 2009

В своей работе мы используем Nunit и Typemock для нашего модульного тестирования. Тот факт, что нам не нужно менять наш код для тестов, является большим плюсом. Издеваться над DAL - путь.

0 голосов
/ 10 июля 2009

Я бы абстрагировал слой доступа к данным, а затем высмеял его. С помощью насмешек вы сможете увеличить охват кода ваших тестов. Это также предотвратит идею « Test Cancer », которая произойдет, если делать дорогие вызовы в сеть / файловую систему / базу данных, потому что люди перестанут их запускать.

У вас должно быть несколько тестов, которые обращаются к базе данных, но они должны быть максимально ограничены.

0 голосов
/ 10 июля 2009

Вы должны попытаться наложить свой код на уровень, чтобы вы могли высмеивать работу ваших функций.

Слой, который действительно должен взаимодействовать с базой данных, может использовать систему настройки данных и работы с ними в транзакции, которую вы откатили бы в конце теста.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...