Upgrade to Pro — share decks privately, control downloads, hide ads and more …

PL/SQL Unit Testing Can Be Fun (with a little h...

PL/SQL Unit Testing Can Be Fun (with a little help from Ruby)

Presentation at Miracle Open World 2012

Avatar for Raimonds Simanovskis

Raimonds Simanovskis

April 20, 2012
Tweet

Other Decks in Technology

Transcript

  1. How is it done? try something... dbms_output.put_line(...) it is obvious

    that there are no bugs testers should test, that’s their job
  2. What are typical problems? Trying and not testing Tests are

    not repeatable Manual verification of results Testing is done too late in development
  3. Types of tests unit tests integration tests performance & load

    tests exploratory & usability tests programmer’s responsibility
  4. Good unit tests Automatic, run fast Wide code coverage including

    edge cases Repeatable Independent from execution order Using real and understandable test data
  5. 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;
  6. Tests CREATE OR REPLACE PACKAGE ut_betwnstr AS PROCEDURE ut_setup; PROCEDURE

    ut_teardown; PROCEDURE ut_normal_usage; PROCEDURE ut_first_index_null; END ut_betwnstr; CREATE OR REPLACE PACKAGE BODY ut_betwnstr AS PROCEDURE ut_setup AS BEGIN NULL; END ut_setup; PROCEDURE ut_teardown AS 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;
  7. 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
  8. 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?
  9. ruby-plsql-spec ideal language for writing tests powerful testing tools with

    “readable” syntax library for calling PL/SQL procedures from Ruby RSpec ruby-plsql
  10. ruby-plsql gem plsql.connect! "hr","hr","xe" plsql.test_uppercase('xxx') # => "XXX" plsql.test_uppercase(:p_string =>

    'xxx') # => "XXX" plsql.test_copy("abc", nil, nil) # => { :p_to => "abc", # :p_to_double => "abcabc" } plsql.test_copy(:p_from => "abc", :p_to => nil, :p_to_double => nil) # => { :p_to => "abc", # :p_to_double => "abcabc" } plsql.hr.test_uppercase('xxx') # => "XXX" plsql.test_package.test_uppercase('xxx') # => 'XXX' plsql.hr.test_package.test_uppercase('xxx') # => 'XXX' plsql.logoff
  11. 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” :)