Oracle unit testing validates PL/SQL procedures, functions, and triggers by executing them in isolation and comparing actual results to expected outcomes.
Detect logic defects early, protect against regressions, and document expected behavior. Automated tests shorten release cycles and raise confidence in schema changes.
Use native SQL Developer Unit Test, the open-source utPLSQL
framework, or commercial suites like Quest Code Tester. This guide focuses on utPLSQL
because it is free, scriptable, and CI-friendly.
utPLSQL
quickly?Clone the repository, connect as a privileged user, and run install_headless.sql
.Grant UT_ROLE
to developers running tests.
Create a schema-level package whose procedures start with test_
. Inside, use ut.expect(actual).to_equal(expected)
. Register the package in a suite and execute with ut.run
.
Suppose calc_order_total(p_order_id)
in package orders_api
returns the value stored in Orders.total_amount
. A test verifies both value and datatype.
create or replace package orders_api_ut as
--%suite(Orders API)
--%suitepath(ecommerce).
--%test(Correct total returned)
procedure test_total_matches_column;
end orders_api_ut;
/
create or replace package body orders_api_ut as
procedure test_total_matches_column is
l_expected Orders.total_amount%type;
l_actual Orders.total_amount%type;
begin
select total_amount into l_expected from Orders where id = 1001;
l_actual := orders_api.calc_order_total(1001);
ut.expect(l_actual).to_equal(l_expected);
end;
end orders_api_ut;
/
Run begin ut.run(); end;
in SQL*Plus, SQLcl, or any CI job.Pass ut_varchar2_list('ecommerce')
to run a specific suite path.
Use the ut_xunit_reporter()
parameter:begin ut.run(reporters => ut_xunit_reporter()); end;
Outputs XML consumable by Jenkins or GitLab.
Keep tests independent; reset data with savepoint/rollback
or isolated test schemas. Cover edge cases—NULLs, constraint violations, bulk data. Integrate tests into every deployment pipeline.
Relying on production data makes tests brittle; instead, insert minimal fixture rows.Ignoring performance leads to slow suites; prefer deterministic SQL over loops and avoid COMMIT inside tests.
Fire DML inside the test, then query the table or audit log to assert side-effects. Wrap the DML in savepoint
and rollback
to leave no residue.
Replace calls to outbound web services or DB links with conditional compilation or test stubs in shadow packages.utPLSQL supports build-in spy
helpers for verifying call counts.
Yes. Use ut_suite_setup
to run fixture DML once per suite, and ut_test_setup
for each test case. Clean up in matching teardown procedures.
Add coverage reports, integrate with Git hooks, and educate teammates. Strong test suites turn PL/SQL into a maintainable, reliable layer of your application.
.
Yes. utPLSQL offers CLI and Maven plugins that connect via JDBC, execute ut.run
, and publish JUnit reports for Jenkins, GitLab, or GitHub Actions.
SQL Developer includes a GUI that generates DBMS unit test harnesses. However, script-based utPLSQL is preferred for version control and automation.
Fetch the cursor into a collection, then compare counts, data types, or specific columns with ut.expect
helpers like ut.equal
and ut.to_raise
.