Подтвердить что ты не робот

Является ли модулем тестирование вашего SQL-запроса TDD слишком далеко?

В модуле тестирования вашего SQL есть статья о www.sqlservercentral.com.

Guy TDD во мне сказал хорошо, мы можем протестировать материал базы данных.

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

Итак, если вы чувствуете потребность в unit test вашем SQL, вы просто очень тщательны, чрезмерно прагматичны или это признак дизайнерского запаха?

4b9b3361

Ответ 1

Я согласен с системным архитектором, в наши дни слишком много бизнес-логики вносит свой вклад в базы данных.

Ответ 2

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

Есть несколько случаев, когда я предлагаю тестировать базу данных:

  • Таблицы и представления: проверьте таблицы и представления, которые вы ожидаете. Убедитесь, что эти таблицы и представления содержат столбцы, которые вы ожидаете. Вы также можете проверить, что таблицы, представления или столбцы, которые вы сбросили в этой вехе, фактически отсутствуют.

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

  • Триггеры: такие же, как и для ограничений, а также триггеры могут использоваться для каскадных эффектов или для преобразования значений и т.д. Проверьте эти логические пути.

  • Хранимые процедуры: я поддерживаю осторожность в том, чтобы слишком много логики вводить в базу данных, когда логику легче разрабатывать, отлаживать и поддерживать на прикладном уровне. Но бывают случаи, когда есть веские причины использовать хранимые procs. Часто вы видите, как узкое место производительности решалось путем ввода сложной логики в базу данных. Таким образом, хранимые процедуры не уходят полностью, и тестирование их - хорошая идея.

  • Данные начальной загрузки: таблицы поиска - это пример данных, которые должны присутствовать даже в "пустой" базе данных. Могут быть и другие примеры. Проверьте, что база данных содержит требуемые данные.

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

  • ORM-классы. Подобно триггерам, классы ORM в вашем приложении могут содержать логику для проверки, преобразования или мониторинга операций с базой данных. Они должны быть протестированы.

Эти тесты не могут быть точно названы "модульным тестированием". Единичное тестирование - это особый тип тестирования, в котором каждый тест не зависит от других тестов, и вы пытаетесь изолировать отдельные единицы кода. Я бы сказал, тестируя базу данных, описанные выше способы являются примером тестирования функциональности.

Ответ 3

В вашем SQL содержится логика. Например, булевское условие проверяется в предложении WHERE. Можете ли вы придумать какие-либо способы, с помощью которых SQL может быть неправильным? Если это так, было бы целесообразно протестировать SQL, чтобы убедиться, что эти ошибки отсутствуют?

(Например, какой-то глупый программист, как и я, может случайно ввести "WHILE" вместо "WHERE" в моем комментарии выше!... как и я. Но позже я исправил его. Итак, где мои тесты стекирования??? -)

Ответ 4

Различия между модульными тестами/specs и интеграционными тестами/specs.

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

Ваши тесты должны быть четко определены между модульными тестами для тестирования постоянных неосведомленных блоков POCO/POJO, таких как объекты, службы и интеграционные тесты. Которые предназначены для тестирования, когда ваше приложение попадает в металл.

Тестирование интеграции должно проверять постоянство, такое как репозитории и реализация единичной работы для вашего механизма сохранения (RBDMS), Active Directory, Exchange, файловой системы и электронной почты и т.д.

Если ваш случай использования требует тщательного тестирования точки интеграции, в которой используется триггер, тогда проверьте поведение, а не триггер явно. В будущем вы можете не использовать триггер и вместо этого использовать ORM или AoP-перехватчик.

Ответ 5

Эта проблема обсуждается. Если вы спросите администратора базы данных, они подумают, что это лучшая вещь в мире, чтобы все ваши приложения использовали предопределенные хранимые процедуры. Эти дни, хотя и заканчиваются, с Hibernate и LINQ набирают популярность, вы действительно можете использовать базу данных в качестве хранилища информации, и ваш уровень доступа к данным обрабатывает все запросы. Я думаю, что LINQ может сделать все для вас в MS SQL, кроме полнотекстового поиска. Что касается разницы в производительности между SPROC и LINQ, это небрежно. Мое голосование не является кодом в базе данных, всем кодом на уровне доступа к данным yoru и имеет для этого тестирование.

Ответ 6

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

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

Ответ 7

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

Ответ 8

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

Ответ 9

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

ИЗМЕНИТЬ

Например, я буду использовать значение по умолчанию для вставки и триггер обновления, чтобы установить поля "последнее обновленное время" в insert/update. В LINQ я поставлю столбец как значение, генерируемое автогенерированием, и сделаю его доступным только для чтения. Для меня это проще, чем добавление обработчика события PropertyChanged, чтобы убедиться, что всякий раз, когда изменяется поле на сущности, изменяется последнее обновленное время. Я проверяю его? Конечно, но вручную и после факта, хотя я сильно предпочитаю TDD для большинства вещей.

Ответ 10

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

Ответ 11

Пока предложение WHERE не пустое, оно должно быть протестировано.

Здесь мы используем API-интерфейс NHibernate для запроса базы данных. Тем не менее, мы ставим простые модульные тесты для защиты уровня доступа к данным. Рассмотрим это:

public IList<Book> GetBorrowedBooks(User user);

Это может показаться глупым в первую очередь. Но для такой простой ситуации мы имеем дело с как минимум тремя объектами модели: книгой, пользователем, заимствованием и, возможно, возвратом. Любая попытка изменить любой из 3 (или более) классов может нарушить код.

Какова стоимость? Наверное, для написания тестов в этом примере требуется менее 20 минут. С помощью категории в NUnit тесты модуля доступа к данным могут быть настроены для работы ночью, а другие тесты - для каждой фиксации. Медленные тесты модулей доступа к данным не навредят, и они являются спасателями жизни.

Ответ 12

DbFit - хороший инструмент для модульного тестирования базы данных. Я считаю целесообразным использовать TDD с SQL, потому что, в конце концов, это декларативный язык с условным ветвлением, агрегатными функциями и т.д. Без тестов на месте, как вы можете быть уверены, что получаете ожидаемый результат?