Мне интересно узнать, какой подход люди используют при разработке автоматических модульных тестов, которые проверяют базу данных.
Устанавливаете ли вы базу данных QA (известную отправную точку) перед запуском набора тестов.
ИЛИ ЖЕ
Вы создаете заглушку базы данных, которая заменяет ее всякий раз, когда происходит вызов базы данных?
Обновлено: Связанный вопрос, но не дубликат, хотя довольно важный для рассматриваемого вопроса: Как выполнить модульное тестирование устойчивости?





Проделаем несколько хитростей:
edit: У нас есть отдельные базы данных для каждого пользователя. На нашем сервере сборки также есть собственная база данных. Стоимость дополнительных жестких дисков намного меньше, чем стоимость разработчиков, влияющих на тесты друг друга.
В дополнение ко всему, мы стараемся проводить как можно больше имитационных тестов, потому что юнит-тесты на самом деле не предназначены для интеграционных тестов. Поэтому попробуйте отделить свой сервисный слой от слоя DAO. Это также поможет вам легче находить проблемы, потому что вы изолировали все.
В какой-то момент я действительно считаю, что вам нужен доступ к базе данных, потому что это не идеальный / академический мир, в котором мы живем :-)
Зависит от случая, но в устаревших системах, где я не хочу отключать базу данных, я часто использую интерфейс, скажем, IFooDBManager, у которого есть методы, возвращающие объекты ADO.Net, такие как таблицы данных или наборы данных. Конечно, это не обязательно должен быть интерфейс, но это может быть, например, виртуальный метод. Затем в своих тестах я использую небольшой API с плавным интерфейсом, который я построил сам давно, я использую его для создания наборов данных и таблиц и заполнения их тестовыми значениями, чтобы я мог вернуть их из своих подделок.
Свободный интерфейс выглядит примерно так:
return DataTableBuilder.Create()
.DefineColumns("a, b")
.AddRow().SetValue("a", 1).SetValue("b", 2).DoneWithRow()
.AddRow().SetValue("a", 10).SetValue("b", 20).DoneWithRow()
.Table
Как я уже сказал, это лишь один из подходов, которые я использую, и он предназначен в основном для устаревших систем, где я не хочу вводить новые зависимости от фреймов и тому подобного. Однако я не видел, чтобы многие другие люди использовали эту технику, поэтому я подумал, что о ней стоит упомянуть.
Обновлено: Я забыл уточнить, что это для заглушки базы данных, поэтому взаимодействие с базой данных в этом случае не проверяется. Фактическое взаимодействие будет происходить в конкретной реализации IFooDBManager, для тестирования что необходимо что-то еще полностью.
Кроме того, не все методы в таком интерфейсе, конечно, возвращают вещи, есть также методы для записи в базу данных, и я обычно тестирую их с помощью тестирования взаимодействия в RhinoMocks, где я устанавливаю ожидания для этих методов.
Мы движемся к использованию макетов фреймворков - они имитируют ресурсы, такие как базы данных, файлы конфигурации и т. д. Использование этих фреймворков - практический способ эффективного выполнения модульных тестов.
Один из фреймворков, над которым мы работаем, - это Rhino Mocks. Вы можете прочитать об этом по ссылке ниже. В нем также есть хорошее представление о том, зачем вам нужны такие фреймворки.
http://weblogs.asp.net/stephenwalther/archive/2008/03/22/tdd-introduction-to-rhino-mocks.aspx
Согласовано. Это не замена тестирования реальными ресурсами. Это придет. Это необходимо для того, чтобы убедиться, что код, который вы написали для использования этих ресурсов, работает нормально. По сути, это первая линия тестирования, за которой следует тестирование с реальными базами данных и т. д.
«Заглушка базы данных» обычно называется «фальшивым репозиторием» или «фиктивным репозиторием». Это хорошая идея. Вы можете кодировать их вручную (что несложно для простых случаев) или использовать для их создания фреймворк, например Rhino Mocks. Вы не упоминаете, на каком языке вы работаете. Rhino издевается над .Net.
Если вы используете фиктивные репозитории, вы можете запускать тесты для кода, который работает с данными, без фактического использования базы данных для данных. Благодаря этому тесты выполняются очень быстро, и это хорошо.
Конечно, на каком-то этапе вам все равно придется протестировать реальный репозиторий, и это скорее проблема. Эти тесты будут выполняться медленнее, потому что они используют настоящую базу данных. Некоторые будут классифицировать их как «интеграционные тесты», а не как модульные тесты из-за проблем со скоростью и зависимостями.
Я не возражаю против того, как вы их называете, но лучше держать эти тесты отдельно.
Хорошая идея для обеспечения согласованности данных - начать транзакцию базы данных перед тестом и откатить ее после этого. Таким образом, состояние базы данных возвращается к тому, что было до теста.
Мне нравится трюк с транзакциями.
Как мне протестировать программное обеспечение, которое само по себе поддерживает транзакции; то есть код сам по себе совершает несколько транзакций? Есть ли способ провести модульное тестирование, кроме запуска БД в известном состоянии?
Джонатан, здесь в игру вступают вложенные транзакции.
Транзакция не будет работать, если у вас есть тестовый пример, который проверяет сущность, созданную в другом тестовом случае ...
Если вы используете NHibernate, вы можете очень легко тест на базе данных SQLite в памяти, что является очень быстро.
эта ссылка очень интересна для чтения. Спасибо, что поделились этим!
На самом деле вам следует делать и то, и другое. Когда вы говорите «построить заглушку базы данных», это намекает на насмешку в модульных тестах. А когда вы говорите об «Установить базу данных QA (известная отправная точка)», это намекает на интеграционные тесты, в которых вы действительно попадаете в базу данных. Модульные тесты появляются намного раньше в игре, и именно здесь в игру вступает насмешка. Мокинг выполняется намного быстрее, чем обращение к базе данных. Поэтому, когда вы запускаете много модульных тестов, имитация сэкономит много времени. Rhino Mocks - отличный фреймворк, который я использовал лично. Но есть несколько фреймворков для фиксации, найдите тот, который лучше всего подходит для вас.
В какой-то момент вам следует пройти свою полную базу данных через интеграционные тесты, и лучший способ, который я нашел для этого, - это иметь сценарий, который полностью создает и заполняет базу данных известным набором данных. Затем убедитесь, что ничто не коснется вашей вновь созданной базы данных, кроме интеграционных тестов, и приступайте к тестированию.
В своей практике тестирования базы данных я использовал NUnit, и до того, как вся последовательность тестов была выполнена, база данных была установлена и заполнена тестовыми данными. Конечно, этот процесс был не очень быстрым, но это мешает вам выполнять другую работу во время выполнения тестов.
Обычно я использую два подхода.
Код, который зависит от уровня абстракции базы данных, работает с IoC и поэтому легко тестируется с помощью макетов / заглушек. У вас есть интерфейс IDataAccess или IRepository, и вы проверяете взаимодействие своего кода с ним.
Код, который на самом деле работает с базой данных (скажем, класс, реализующий IDataAccess), тестируется сам по себе, обычно выполняя двусторонние обращения к базе данных (вставка-извлечение-обновление-извлечение-удаление). Перед запуском каждого тестового примера база данных воссоздается или очищается, чтобы избежать перекрестных помех между тестами. Это приводит к тестам, для выполнения которых требуется несколько минут вместо нескольких секунд, но, на мой взгляд, важно протестировать фактическую базу данных, которую вы будете использовать в производственной среде. Использование такой замены, как SQLite в памяти, не является хорошим выбором, потому что он слишком отличается от, например, SQL Server.
вот хороший снимок экрана по этой теме называется Ценность небольших тестов
Спасибо за ссылку! отличное видео!
В Spring есть тестовые классы, которые являются транзакционными. Заполните тестовые данные, запустите тесты, откатите их. Как будто тебя там никогда не было.
Если вы пытаетесь проверить код доступа к данным, вам понадобится насмешливый фреймворк. По следующей ссылке вы можете увидеть базы данных модульного тестирования видеоурок
Это здорово, но как только вы закончите возиться, вам все равно нужно будет протестировать реальную базу данных, файлы конфигурации и т. д.