Нужно ли при модульном тестировании использовать базу данных для проверки операций CRUD?

При модульном тестировании обязательно ли использовать базу данных при тестировании операций CRUD? Может ли sql lite помочь с этим? Вам нужно как-то создать БД в памяти?

Я использую мбунит.


person mrblah    schedule 27.09.2009    source источник


Ответы (7)


Нет. Интеграция фактической БД будет интеграционным тестированием. Не модульное тестирование.

Да, вы можете использовать для этого любую БД в памяти, такую ​​как SQLite или MS SQL Compact, если вы не можете абстрагировать (смоделировать) свой DAL/DAO каким-либо другим способом.

Имея это в виду, я должен отметить, что модульное тестирование возможно вплоть до DAL, но не самого DAL. DAL нужно будет протестировать с какой-то реальной БД при интеграционном тестировании.

person Robert Koritnik    schedule 27.09.2009
comment
Учитывая тот факт, что на самом деле это интеграционный тест, есть ли смысл подделывать базу данных для выполнения модульных тестов? - person Robert Harvey; 28.09.2009
comment
Да, это. Это поможет вам провести модульное тестирование ваших репозиториев данных, которые используют DAL (в данном случае издевательские). - person Robert Koritnik; 28.09.2009
comment
-1. Я думаю, что ответ Марка более точен: это зависит от того, потому что, если вы пишете код, который сохраняет данные от имени другого кода (n-уровневая, фреймворковая библиотека и т. д.), то модульный тест - это именно то, что проверяет конкретный модуль кода работает как положено. Например, скажем, вы используете столбцы IDENTITY в своей БД и возвращаете созданный идентификатор в качестве запроса SELECT после INSERT, этот код должен быть протестирован модулем, т. е. утверждение возвращаемого значения является ожидаемым идентификатором. Согласитесь, что создание фиктивных репозиториев — это хорошо, но есть некоторые вещи, от которых вы просто не сможете избавиться. - person si618; 28.09.2009
comment
... вы можете возразить, что достаточно модульного теста для SQL-запроса, а не выполнения запроса, но иногда этого недостаточно. Замена одной СУБД на другую (Sqlite вместо SQL Server) невозможна, если вы хотите проверить, правильно ли работает ваш специальный код SQL Server 2005 с экземпляром SQL Server 2005. - person si618; 28.09.2009

Как и во всех сложных вопросах, ответ: это зависит :)

Как правило, уровень доступа к данным следует скрывать за интерфейсом, чтобы можно было протестировать остальную часть приложения без использования базы данных, но что, если вы хотите протестировать саму реализацию доступа к данным?

В некоторых случаях некоторые люди считают это излишним, поскольку они в основном используют декларативные технологии доступа к данным, такие как ORM.

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

Некоторые люди считают, что это интеграционные тесты, а не модульные тесты, но в моей книге не так уж важно, как вы это называете — самое главное, что вы получаете пользу от своих полностью автоматизированных тестов, и вы определенно можете используйте инфраструктуру модульного тестирования для управления этими тестами.

Недавно я писал о том, как это сделать на SQL Server. Самое главное, о чем следует помнить, это избегать соблазна создать General Fixture с некоторыми «репрезентативными данными» и попытаться повторно использовать их во всех тестах. Вместо этого вы должны заполнять данные как часть каждого теста и очищать их после.

person Mark Seemann    schedule 28.09.2009

При модульном тестировании обязательно ли использовать базу данных при тестировании операций CRUD?

Предположим на мгновение, что вы извлекли интерфейсы вокруг указанных операций CRUD и протестировали все, что использует указанный интерфейс, с помощью макетов или заглушек. Теперь у вас остался кусок кода, который представляет собой метод сохранения, содержащий немного кода для связывания объектов и немного SQL.

Если это так, то я бы объявил это «Единицей» и сказал, что вам нужна база данных, и в идеале такая, которая, по крайней мере, является хорошим представлением вашей базы данных, чтобы вас не поймали с SQL, специфичным для продавца.

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

Изменить: пропущены 2/3 вашего вопроса. Прости.

Может ли sql lite помочь с этим?

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

Нужно ли вам как-то создать базу данных в памяти?

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

person Michael Lloyd Lee mlk    schedule 28.09.2009

Как уже указывали другие, вы пытаетесь достичь не модульного тестирования, а интеграционного тестирования.

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

Теперь, что касается вашего вопроса, я бы проверил DbUnit.NET. Я не знаю версию этого инструмента для .NET, но могу сказать, что версия для Java отлично подходит для тестов, взаимодействующих с базой данных. В двух словах, DbUnit позволяет вам перевести базу данных в известное состояние перед запуском теста и выполнить проверку содержимого таблиц. Действительно удобно. Кстати, я рекомендую прочитать страницу Лучшие практики, даже если вы решите не использовать эту инструмент.

person Pascal Thivent    schedule 28.09.2009

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

Для модульного тестирования таких операций рассмотрите возможность использования некоего объекта mock-database. Например, если у вас есть класс, который инкапсулирует ваше взаимодействие с базой данных, извлеките из него интерфейс, а затем создайте наследующий класс, который использует простые объекты в памяти вместо фактического подключения к базе данных.

person JoshJordan    schedule 27.09.2009
comment
но как тогда проверить вставку или удаление? я просто не понимаю! - person mrblah; 28.09.2009
comment
@homestead: модульное тестирование должно проверять только определенную ЕДИНИЦУ кода, а не полный бизнес-процесс. - person Robert Koritnik; 28.09.2009
comment
@homestead: вы пишете для него интеграционный тест. - person JoshJordan; 28.09.2009
comment
-1 Смотрите мои комментарии в ответе Робертса. Да, в большинстве случаев вы можете издеваться над БД, но иногда вы не можете. - person si618; 28.09.2009

Как упоминалось выше, ключевым здесь является то, чтобы ваша тестовая база данных находилась в известном состоянии до запуска тестов. В одном реальном примере у меня есть пара сценариев SQL, которые запускаются перед тестами, воссоздающими известный набор тестовых данных. Исходя из этого, я могу протестировать операции CRUD и убедиться, что новые строки вставлены/обновлены/удалены.

person Doctor Blue    schedule 28.09.2009

Я написал утилиту под названием DBSnapshot, чтобы помочь интеграционный тест базы данных sqlserver.

Если схема вашей базы данных часто меняется, будет полезно протестировать ваш код на реальном экземпляре базы данных. Люди используют SqlLite для быстрых тестов (поскольку база данных работает в памяти), но это бесполезно, когда вы хотите проверить, работает ли ваш код с реальной сборкой вашей базы данных.

При тестировании вашей базы данных вы хотите следовать шаблону, подобному: резервное копирование базы данных, настройка базы данных для теста, проверка кода, проверка результатов, восстановление базы данных в исходное состояние.

Вышеизложенное гарантирует, что вы сможете запускать каждый тест изолированно. Моя утилита DBSnapshot упростит ваш код, если вы его пишете .сеть. Я думаю, что его проще использовать, чем DbUnit.NET.

person Dane O'Connor    schedule 28.09.2009