This document discusses unit testing PL/SQL code using Ruby. It introduces the ruby-plsql-spec gem, which allows writing PL/SQL unit tests in Ruby with a readable RSpec-style syntax. The gem provides powerful testing features and best practices from the Ruby community. A demo shows connecting to a database and calling PL/SQL procedures from Ruby tests. The benefits highlighted are compact readable syntax, support for complex tests, following best practices, and being open-source. More information is provided in blog posts and the GitHub repository for ruby-plsql-spec.
8. Good unit tests
Automatic, run fast
Wide code coverage including edge cases
Repeatable
Independent from execution order
Using real and understandable test data
10. created by Steven Feuerstein, 1999
based on “xUnit”-style frameworks
not maintained anymore :(
11. Example
substring from start until end position
CREATE OR REPLACE FUNCTION betwnstr (
string_in IN VARCHAR2,
start_in IN INTEGER,
end_in IN INTEGER
)
RETURN VARCHAR2
IS
l_start PLS_INTEGER := start_in;
BEGIN
IF l_start = 0
THEN
l_start := 1;
END IF;
RETURN (SUBSTR (string_in, l_start, end_in - l_start + 1));
END;
12. Tests
CREATE OR REPLACE PACKAGE ut_betwnstr AS CREATE OR REPLACE PACKAGE BODY ut_betwnstr AS
PROCEDURE ut_setup; PROCEDURE ut_setup AS
PROCEDURE ut_teardown; BEGIN
NULL;
PROCEDURE ut_normal_usage; END ut_setup;
PROCEDURE ut_first_index_null;
PROCEDURE ut_teardown AS
END ut_betwnstr; BEGIN
NULL;
END ut_teardown;
PROCEDURE ut_normal_usage AS
BEGIN
utassert.eq('Normal usage',
betwnstr('abcdefg', 2, 5),
'bcde');
END ut_normal_usage;
PROCEDURE ut_first_index_null AS
BEGIN
utassert.isnull('First index is null',
betwnstr('abcdefg', NULL, 5));
END ut_first_index_null;
END ut_betwnstr;
13. Results
exec utplsql.test('betwnstr', recompile_in => FALSE);
.
> SSSS U U CCC CCC EEEEEEE SSSS SSSS
> S S U U C C C C E S S S S
> S U U C C C C E S S
> S U U C C E S S
> SSSS U U C C EEEE SSSS SSSS
> S U U C C E S S
> S U U C C C C E S S
> S S U U C C C C E S S S S
> SSSS UUU CCC CCC EEEEEEE SSSS SSSS
.
SUCCESS: "betwnstr"
.
> Individual Test Case Results:
>
SUCCESS - betwnstr.UT_FIRST_INDEX_NULL: ISNULL "First index is null" Expected "" and got ""
>
SUCCESS - betwnstr.UT_NORMAL_USAGE: EQ "Normal usage" Expected "cde" and got "cde"
>
>
> Errors recorded in utPLSQL Error Log:
>
> NONE FOUND
15. Why used just by few?
Too large / too verbose test code?
Hard to read, too much noise?
Hard to test complex cases?
No best practices how to write tests?
Nobody is using, why should I use?
16. ruby-plsql-spec
ideal language
for writing tests
powerful testing tools
RSpec with “readable” syntax
library for calling
ruby-plsql PL/SQL procedures
from Ruby
19. Benefits
Compact, readable syntax
Powerful features also for complex tests
Best practices from Ruby community
Based on needs from real projects
Open-source – “free as in beer” :)