Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to achieve test isolation testing Oracle PL/SQL?

Tags:

In Java projects, JUnit tests do a setup, test, teardown. Even when mocking out a real db using an in-memory db, you usually rollback the transaction or drop the db from memory and recreate it between each test. This gives you test isolation since one test does not leave artifacts in an environment that could effect the next test. Each test starts out in a known state and cannot bleed over into another one.

Now I've got an Oracle db build that creates 1100 tables and 400K of code - a lot of pl/sql packages. I'd like to not only test the db install (full - create from scratch, partial - upgrade from a previous db, etc) and make sure all the tables, and other objects are in the state I expect after the install, but ALSO run tests on the pl/sql (I'm not sure how I'd do the former exactly - suggestions?).

I'd like this all to run from Jenkins for CI so that development errors are caught via regression testing.

Firstly, I have to use an enterprise version instead of XE because of XE doesn't support java SPs and a dependency on Oracle Web Flow. Even if I eliminate those dependencies, the build typically takes 1.5 hours just to load (full build).

So how do you acheive test isolation in this environment? Use transactions for each test and roll them back? OK, what about those pl/sql procedures that have commits in them?

I thought about backup and recovery to reset the db after each test, or recreate the entire db between each tests (too drastic). Both are impractical since it takes over an hour to install it. Doing so for each test is overkill and insane.

Is there a way to draw a line in the sand in the db schema(s) and then roll it back to that point in time? Sorta like a big 'undo' feature. Something besides expdp/impdp or rman. Perhaps the whole approach is off. Suggestions? How have others done this?

For CI or a small production upgrade window, the whold test suite has to run with in a reasonable time (30 mins would be ideal).

Are there products that might help acheive this 'undo' ability?

like image 767
Bill Avatar asked Jun 10 '11 21:06

Bill


People also ask

How do I debug a PL SQL package?

Right-click the PL/SQL object that you want to debug and select Database Tools | Recompile. In the Recompile dialog, select With "debug" option. Click OK.


2 Answers

Kevin McCormack published an article on The Server Labs Blog about continuous integration testing for PL/SQL using Maven and Hudson. Check it out. The key ingredient for the testing component is Steven Feuerstein's utPlsql framework, which is an implementation of JUnit's concepts in PL/SQL.

The need to reset our test fixtures is one of the big issues with PL/SQL testing. One thing which helps is to observe good practice and avoid commits in stored procedures: transactional control should be restricted to only the outermost parts of the call stack. For those programs which simply must issue commits (perhaps implicitly because they execute DDL) there is always a test fixture which issues DELETE statements. Handling relational integrity makes those quite tricky to code.

An alternative approach is to use Data Pump. You appear to discard impdp but Oracle also provides PL/SQL API for it, DBMS_DATAPUMP. I suggest it here because it provides the ability to trash any existing data prior to running an import. So we can have an exported data set as our test fixture; to execute a SetUp is a matter of running a Data Pump job. You don't need do do anything in the TearDown, because that tidying up happens at the start of the SetUp.

like image 163
APC Avatar answered Oct 23 '22 03:10

APC


In Oracle you can use Flashback Technology to restore the serve to a point back in time.

http://download.oracle.com/docs/cd/B28359_01/backup.111/b28270/rcmflash.htm

like image 39
Scott Bruns Avatar answered Oct 23 '22 05:10

Scott Bruns