Интеграционные тесты - на каком уровне вы тестируете и как настраиваете? - PullRequest
1 голос
/ 17 апреля 2009

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

Мой вопрос касается настройки этих тестов и того, на каком уровне кода вы выполняете тесты.

Настройка

Учитывая, что у меня должно быть много интеграционных тестов, я не хочу создавать и удалять тестовую базу данных для каждого теста, это будет невероятно медленно (даже если это SqlLite в памяти). Мои мысли:

  1. Иметь тестовую базу данных, которая находится рядом с моим разработчиком базы данных.
  2. Перед тестированием запустите скрипт сброса, который правильно настроит мою схему и вставит все необходимые данные (не специфичные для тестового примера)
  3. Просто используйте этот тестовый БД, как будто это настоящий БД.

Однако, кажется очень расточительным, что я должен запускать свою конфигурацию Fluent NHib в каждой [Setup]. Это просто сложно? Какие у меня есть варианты?

Мой сеанс в настоящее время упакован в шаблон UoW, при этом создание и уничтожение выполняются для begin_request и end_request (веб-приложение MVC) соответственно. Должен ли я изменить это, чтобы играть с тестами, чтобы решить эту проблему?

Тестирование

Что касается написания тестов, как мне это сделать?

Должен ли я выполнять тестирование с максимально возможного уровня (действия контроллера MVC) или с самого низкого (репозитории).

Если я проверю на самом низком уровне, мне придется вручную жестко закодировать все данные. Это сделает мой тест ломким к изменениям в коде, а также не будет отражать то, что действительно произойдет в коде во время выполнения. Если я тестирую на самом высоком уровне, мне нужно запустить все мои настройки IoCC, чтобы зависимости вводились и все функционировало (опять же, повторяя это в каждом [SetUp]?)

Мех! Я заблудился, кто-то указывает мне правильное направление!

Спасибо

Ответы [ 2 ]

2 голосов
/ 17 апреля 2009

Что касается создания фабрики сеансов, я создаю класс с именем _AssemblyCommon в своем тестовом проекте и оттуда выставляю фабрику сеансов как статическую. Метод, помеченный атрибутом [SetupFixture] (NUnit), настраивает фабрику сеанса.

В целом интеграционные тесты должны охватывать операции CRUD в репозиториях. Для этого у меня есть один метод тестирования для каждого объекта (или совокупного корня), и я выполняю вставку, извлечение, обновление и удаление всего этого метода. Я также проверяю любые каскадные удаления, которые я определил. Хранение этих операций в одном методе не оставляет никаких следов в базе данных. У меня есть некоторые интеграционные тесты, которые оставляют после себя тестовые данные, но это не было проблемой.

Ваши операции более высокого уровня должны быть проверены юнитом и по возможности смоделировать (я использую Moq) репозитории.

1 голос
/ 17 апреля 2009

В моем текущем приложении MVC я обнаружил, что достаточно проверить взаимодействие между репозиториями и базой данных. Больше всего, это сгладить любые морщины в картографии NHibernate. Все (хорошо, я преувеличиваю, когда говорю все) выше этого уровня является изолированным модульным тестированием. У меня было несколько интеграционных тестов от контроллеров на всем пути вниз по стеку до базы данных, и они использовали контейнер IoC (StructureMap) для построения контроллеров и зависимостей, но я обнаружил, что эти тесты действительно ничего не добавляли, и они были довольно накладные расходы на обслуживание, поэтому я пока удалил их из «интеграционных» тестов - я могу найти причину их вставить, но пока что нет.

В любом случае, процесс тестирования, который я использую, работает так:

Процесс сборки для тестовой сборки уровня доступа к данным создает тестовую базу данных с помощью вызова ExposeSchema () конфигурации FluentNHibernate. Затем процесс сборки запускает некоторый код уровня репозитория NHibernate для заполнения справочных таблиц в базе данных.

Каждый выполняемый интеграционный тест затем оборачивается в оператор System.Transactions.TransactionScope с помощью (), а TransactionScope никогда не вызывается Complete (), поэтому каждый тест может выполняться изолированно, а результаты можно настроить и проверить с помощью () область видимости ISession без изменения состояния любых других тестовых данных. например,

  using (new TransactionScope())
  {
    var session = NHibernateTestSessionCreator.GetNHibernateSessionForIntegrationTesting();
    // This is an NHibernate ISession - setup any dependencies for the repository tests here

    var testRepository = new NHibernateGenericRepository<NewsItem>(NHibernateTestSessionCreator.GetNHibernateSessionForIntegrationTesting())
    // repository test code goes here - the repository is using a different ISession

    // Validate the results here directly with the ISession
  }

  // at this point the transaction is rolled back and we haven't changed the test data

Это означает, что мне не нужно изменять используемую реализацию UnitOfWork - транзакция откатывается на более высокий уровень.

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