Модульные тесты .NET для чтения / сохранения данных в базу данных

Большинство вещей, которые я читал о модульных тестах, касается тестирования ваших классов и их поведения. Но как вы протестируете сохранение данных в базе данных и чтение данных из базы данных. В нашем проекте сохранение и чтение данных осуществляется через службы, которые используются приложением Flex (с использованием WebORB в качестве шлюза). Например, служба читает всех пользователей, у которых есть доступ к определенному модулю. Как вы проверяете, что возвращаемые пользователи на самом деле являются пользователями, имеющими доступ к этому модулю?

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

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

спасибо, Ливен Кардоен

Ответов (7)

Решение

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

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

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

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

Попробуйте использовать mbunit . Это среда тестирования .NET, которая позволяет вам заполнить базу данных в вашей настройке, а затем откатить изменения, которые вы внесли в базу данных во время тестов, восстанавливая базу данных до ее предыдущего состояния. Там быстрая рецензия на него здесь .

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

Существуют инструменты, которые могут сбрасывать огромное количество тестовых данных.

Генератор данных sql от Red Gate

Сообщите нам, какой подход сработал для вас.

Я согласен с @Gambrinus. В общем, модульное тестирование уровня данных практически невозможно; Лучшее, что вы можете сделать, - это предоставить надежный интерфейс уровня данных и имитировать его на бизнес-уровне, а затем сохранить тесты качества данных для интеграционного тестирования.

Я видел попытки издеваться над инструментами ORM ( этот для LINQ меня забавляет), но они не проверяют правильность запроса, а только то, что запрос был написан так, как, по мнению тестировщика, он должен быть написан. Поскольку тестировщик обычно пишет запрос к ORM, это не дает никакой ценности.

  • О: Если вы используете FlexApplication для прямого доступа к базе данных, это непросто протестировать. У вас должен быть тестируемый интерфейс / слой между ними.
  • B: Ввод данных в базу данных является нормальным явлением на этапе «TestSetup-Phase».
  • C: Должна быть возможность протестировать интерфейс, который действительно запускает хранимую процедуру.
    • если это sprocs, которые не используются графическим интерфейсом пользователя, а только sql-to-sql, это также системы, которые тестируют sprocs. обычно у вас есть sp_setup и sp_teardown sproc до и после реальных тестов

это скорее интеграционный тест, чем модульный.

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

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

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