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

Создание структуры базы данных в памяти из экземпляра Oracle

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

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

Итак, моя идея - постепенно заменить этот тестовый экземпляр Oracle на базу данных в памяти. Я буду использовать hsqldb или, может быть, лучше h2.

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

Конечно, я могу извлечь структуру базы данных из Oracle, используя некоторые инструменты, такие как SQL Developer или TOAD, а затем модифицировать эти скрипты, чтобы адаптировать их к языку hsqldb или h2. Но я не думаю, что лучший подход.


Фактически, я уже делал это в другом проекте, используя hsqldb, но я написал все скрипты вручную для создания таблиц. К счастью, у меня было всего несколько таблиц для создания. Моя основная проблема на этом этапе состояла в том, чтобы "перевести" сценарии Oracle, используемые для создания таблиц на языке hsqldb.

Например, таблица, созданная в Oracle, используя следующую команду sql:

CREATE TABLE FOOBAR (
    SOME_ID NUMBER,
    SOME_DATE DATE, -- Add primary key constraint
    SOME_STATUS NUMBER,
    SOME_FLAG NUMBER(1) DEFAULT 0 NOT NULL);

необходимо было "перевести" для hsqldb в:

CREATE TABLE FOOBAR (
    SOME_ID NUMERIC,
    SOME_DATE TIMESTAMP PRIMARY KEY,
    SOME_STATUS NUMERIC,
    SOME_FLAG INTEGER DEFAULT 0 NOT NULL);

В моем текущем проекте слишком много таблиц для этого вручную...


Итак, мои вопросы:

  • Каковы советы, которые вы можете мне дать, чтобы достичь этого?
  • Предоставляют ли h2 или hsqldb некоторые инструменты для генерации своих скриптов из соединения Oracle?

Техническая информация

Java 1.6, Spring 2.5, Oracle 10.g, Maven 2


Изменить

Некоторая информация о моих модульных тестах:

В приложении, где я использовал hsqldb, у меня были следующие тесты: - Некоторые "базовые" модульные тесты, которые не имеют ничего общего с БД. - Для тестирования DAO я использовал hsqldb для выполнения манипуляций с базами данных, таких как CRUD. - Тогда на уровне обслуживания я использовал Mockito, чтобы издеваться над моими объектами DAO, чтобы сосредоточиться на тесте обслуживания, а не на всех приложениях (например, службе + дао + DB).

В моем текущем приложении у нас самый худший сценарий: для тестирования уровня DAO необходимо запустить соединение Oracle. Уровень сервиса не использует (пока) любые макетные объекты для имитации DAO. Таким образом, для тестирования служб также требуется соединение Oracle.

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

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

4b9b3361

Ответ 1

Используйте базу данных in-memory/Java для тестирования. Это гарантирует, что тесты ближе к реальному миру, чем если вы попытаетесь "абстрагировать" базу данных в своем тесте. Вероятно, такие тесты также легче писать и поддерживать. С другой стороны, то, что вы, вероятно, хотите "абстрагироваться" в своих тестах, это пользовательский интерфейс, потому что тестирование пользовательского интерфейса обычно сложно автоматизировать.

Синтаксис Oracle, который вы опубликовали, хорошо работает с базой данных H2 (я только что протестировал его), поэтому, кажется, H2 поддерживает синтаксис Oracle лучше, чем HSQLDB. Отказ от ответственности: Я один из авторов H2. Если что-то не работает, отправьте его в списке рассылки H2.

В любом случае вы должны иметь инструкции DDL для базы данных в вашей системе контроля версий. Вы можете использовать эти сценарии для тестирования. Возможно, вам также необходимо поддерживать несколько версий схемы - в этом случае вы могли бы писать сценарии обновления версии (alter table...). С помощью базы данных Java вы также можете протестировать их.

Кстати, вам не обязательно использовать режим в памяти при использовании H2 или HSQLDB. Обе базы данных бывают быстрыми, даже если вы сохраняете данные. И они просты в установке (только файл jar) и нуждаются в гораздо меньшем объеме памяти, чем Oracle.

Ответ 2

Последний HSQLDB 2.0.1 поддерживает синтаксис ORACLE для DUAL, ROWNUM, NEXTVAL и CURRVAL через флаг совместимости синтаксиса, sql.syntax_ora = true. Таким же образом, конкатенация строки с NULL-строкой и ограничений на NULL в ограничениях UNIQUE обрабатываются другими флагами. Большинство функций ORACLE, таких как TO_CHAR, TO_DATE, NVL и т.д., Уже встроены.

В настоящий момент для использования простых типов ORACLE, таких как NUMBER, вы можете использовать определение типа:

СОЗДАТЬ НОМЕР ТИПА КАК ЧИСЛЕННЫЙ

Следующий снимок позволит NUMBER (N) и другие аспекты совместимости типа ORACLE при установке флага.

Загрузить с http://hsqldb.org/support/

[Обновить:] Снимок, выпущенный 4 октября, переводит большинство типов специфичных для Oracle типов ANSI SQL. HSQLDB 2.0 также поддерживает тип ANSI SQL INTERVAL и арифметику даты/времени так же, как и Oracle.

Ответ 3

Каковы ваши модульные тесты? Если они проверяют правильную работу DDL и хранимых процедур, тогда вы должны написать тесты "ближе" к Oracle: либо без кода Java, либо без Spring и других хороших веб-интерфейсов при фокусировке на db.

Если вы хотите протестировать логику приложения, реализованную в Java и Spring, вы можете использовать mock objects/connection database, чтобы ваши тесты не зависели от базы данных.

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

Ответ 4

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

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