Создать структуру базы данных в памяти из экземпляра Oracle - PullRequest
32 голосов
/ 24 сентября 2010

У меня есть приложение, в котором многие "юнит" тесты используют реальное соединение с базой данных 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, чтобы сосредоточиться на тесте службы, а не на целых приложениях (т. Е. Service + dao + DB).

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

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

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

Ответы [ 4 ]

19 голосов
/ 24 сентября 2010

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

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

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

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

4 голосов
/ 24 сентября 2010

Последний 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/

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

2 голосов
/ 24 сентября 2010

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

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

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

1 голос
/ 12 декабря 2011

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

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

...