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

Как достичь тестирования изоляции тестирования Oracle PL/SQL?

В Java-проектах тесты JUnit выполняют настройку, проверку, срыв. Даже когда вы издеваетесь над реальным db, используя db in-memory, вы обычно откатываете транзакцию или удаляете db из памяти и воссоздаете ее между каждым тестом. Это дает вам тестовую изоляцию, поскольку один тест не оставляет артефактов в среде, которая может повлиять на следующий тест. Каждый тест начинается в известном состоянии и не может перетекать в другой.

Теперь у меня есть сборка Oracle db, которая создает 1100 таблиц и 400 Кбайт кода - много пакетов pl/sql. Я бы хотел не только протестировать db install (полностью создать с нуля, частично - обновить с предыдущего db и т.д.) И убедиться, что все таблицы и другие объекты находятся в состоянии, которое я ожидаю после установки, но ТАКЖЕ запускать тесты на pl/sql (я не уверен, как бы я сделал это в точности - предложения?).

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

Во-первых, я должен использовать корпоративную версию вместо XE, поскольку XE не поддерживает java SP и зависимость от Oracle Web Flow. Даже если я устраню эти зависимости, сборка обычно занимает 1,5 часа, чтобы загрузить (полная сборка).

Итак, как вы проводите тестовую изоляцию в этой среде? Использовать транзакции для каждого теста и откатывать их обратно? Хорошо, как насчет тех процедур pl/sql, которые совершают в них?

Я думал о резервном копировании и восстановлении до reset db после каждого теста или воссоздал весь db между каждым тестом (слишком резким). Оба они непрактичны, так как для его установки требуется час. Выполнение этого для каждого теста является излишним и безумным.

Есть ли способ нарисовать линию в песке в схеме db (-ов), а затем отбросить ее до этого момента? Сорта, как большая функция отмены. Что-то кроме expdp/impdp или rman. Возможно, весь подход отключен. Предложения? Как это сделали другие?

Для CI или небольшого окна обновления продукта набор тестов для чатов должен выполняться в разумные сроки (30 минут идеально подходят).

Есть ли продукты, которые могли бы помочь в достижении этой способности "отменить"?

4b9b3361

Ответ 1

Кевин МакКормак опубликовал статью о блоге Server Labs о непрерывном тестировании интеграции для PL/SQL с использованием Maven и Hudson. Проверьте это. Ключевым компонентом компонента тестирования является фреймворк Steven Feuerstein utPlsql, который представляет собой реализацию концепций JUnit в PL/SQL.

Необходимость reset наших тестовых приборов - одна из больших проблем с PL/SQL-тестированием. Одна вещь, которая помогает - соблюдать надлежащую практику и избегать фиксации хранимых процедур: транзакционное управление должно ограничиваться только внешними частями стека вызовов. Для тех программ, которые просто должны выдавать коммиты (возможно, неявно, потому что они выполняют DDL), всегда есть тестовое устройство, которое выдает команды DELETE. Обработка реляционной целостности делает их довольно сложными для кодирования.

Альтернативный подход - использовать Data Pump. Вы, кажется, отказываетесь от impdp, но Oracle также предоставляет API PL/SQL для него, DBMS_DATAPUMP. Я предлагаю его здесь, потому что он предоставляет возможность удалять любые существующие данные до запуска импорта. Таким образом, мы можем иметь экспортированный набор данных в качестве нашего тестового прибора; для выполнения SetUp является задачей запуска задания Data Pump. Вам не нужно ничего делать в TearDown, потому что это уборка происходит в начале SetUp.

Ответ 3

1,5 часа - это очень долгое время для 1100 таблиц и 400 Кбайт кода. Я, очевидно, не знаю подробностей вашего окружения, но, основываясь на своем опыте, я уверен, вы можете сократить это до 5-10 минут. Вот две основные проблемы с установкой script, которые я видел с Oracle:

1. Операции разбиты на мелкие куски

Чем больше шагов у вас будет, тем больше будет накладных расходов. Например, вы хотите как можно больше объединить код следующим образом:

Заменить:

create table x(a number, b number, c number);
alter table x modify a not null;
alter table x modify b not null;
alter table x modify c not null;

С

create table x(a number not null, b number not null, c number not null);

Заменить:

insert into x values (1,2,3);
insert into x values (4,5,6);
insert into x values (7,8,9);

С

insert into x
select 1,2,3 from dual union all
select 4,5,6 from dual union all
select 7,8,9 from dual;

Это особенно актуально, если вы запускаете script и свою базу данных в разных местах. Это крошечное сетевое отставание начинает иметь значение, когда вы умножаете его на 10 000. Каждый инструмент Oracle SQL, о котором я знаю, будет отправлять по одной команде за раз.

2. Разработчики должны совместно использовать базу данных

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

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


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

Ответ 4

Хотя Oracle Flashback - это функция Enterprise Edition, технология, на которой она основана, доступна во всех редакциях, а именно Oracle Log Miner:

http://docs.oracle.com/cd/B28359_01/server.111/b28319/logminer.htm#i1016535

Мне было бы интересно узнать, использовал ли кто-нибудь это, чтобы обеспечить тестовую изоляцию для функциональных тестов, то есть запросить v $LOGMNR_CONTENTS, чтобы получить список инструкций UNDO с момента времени, соответствующего началу теста.

База данных должна находиться в режиме архивирования, а в тестовом примере junit - метод, аннотированный с помощью

@Startup 

вызовет DBMS_LOGMNR.START_LOGMNR. Тест будет выполняться, а затем в методе, аннотированном с помощью

@Teardown

будет запрос v $LOGMNR_CONTENTS, чтобы найти список заявлений UNDO. Затем они будут выполняться через JDBC. Фактически запрос и выполнение заявлений UNDO можно было бы извлечь в хранимую процедуру PLSQL. Порядок, который должны выполняться, должен быть рассмотрен.

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