20
PL/SQL Unit Testing Can Be Fun! with a little help from Ruby

PL/SQL Unit Testing Can Be Fun

  • Upload
    rsim

  • View
    1.924

  • Download
    6

Embed Size (px)

DESCRIPTION

Presentation at Miracle Open World 2012

Citation preview

Page 1: PL/SQL Unit Testing Can Be Fun

PL/SQL Unit TestingCan Be Fun!

with a little helpfrom Ruby

Page 2: PL/SQL Unit Testing Can Be Fun

Raimonds Simanovskis

github.com/rsim

@rsim

.com

Page 3: PL/SQL Unit Testing Can Be Fun

What is good code?

Correct

Fast enough

Maintainable

Test functionality!

Testperformance!

Test afterchanges!

Page 4: PL/SQL Unit Testing Can Be Fun

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

Page 5: PL/SQL Unit Testing Can Be Fun

What are typical problems?

Trying and not testing

Tests are not repeatable

Manual verification of results

Testing is done too late in development

Page 6: PL/SQL Unit Testing Can Be Fun

Types of testsunit tests

integration tests

performance & loadtests

exploratory & usability tests

programmer’sresponsibility

Page 7: PL/SQL Unit Testing Can Be Fun

Test Driven Development

Page 8: PL/SQL Unit Testing Can Be Fun

Good unit testsAutomatic, run fast

Wide code coverage including edge cases

Repeatable

Independent from execution order

Using real and understandable test data

Page 9: PL/SQL Unit Testing Can Be Fun

How to do it when programming in

PL/SQL?

Page 10: PL/SQL Unit Testing Can Be Fun

created by Steven Feuerstein, 1999

based on “xUnit”-style frameworks

not maintained anymore :(

Page 11: PL/SQL Unit Testing Can Be Fun

Examplesubstring from start until end position

CREATE OR REPLACE FUNCTION betwnstr ( string_in IN VARCHAR2, start_in IN INTEGER, end_in IN INTEGER) RETURN VARCHAR2IS 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;

Page 12: PL/SQL Unit Testing Can Be Fun

TestsCREATE 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;

Page 13: PL/SQL Unit Testing Can Be Fun

Resultsexec 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

Page 14: PL/SQL Unit Testing Can Be Fun

Visual testing tools

Quest Code Tester SQL Developer >= 2.1

Page 15: PL/SQL Unit Testing Can Be Fun

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?

Page 16: PL/SQL Unit Testing Can Be Fun

ruby-plsql-specideal languagefor writing tests

powerful testing toolswith “readable” syntax

library for callingPL/SQL procedures

from Ruby

RSpec

ruby-plsql

Page 17: PL/SQL Unit Testing Can Be Fun

Demo

Page 18: PL/SQL Unit Testing Can Be Fun

ruby-plsql gemplsql.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

Page 19: PL/SQL Unit Testing Can Be Fun

BenefitsCompact, 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” :)