Unit Testing PL/SQL v SQL Developeru / Úvod

Pokud programujete PL/SQL proceduru nebo funkci, můžete vytvořit tzv. unit test - něco co daný blok kódu automaticky otestuje. Existuje několik projektů určených právě k unit testům PL/SQL kódu, např. osvědčený utPLSQL nebo novější PLUTO, nicméně od verze 2.1 je do SQL Developeru zabudován vlastní framework. Vzhledem k tomu že jsme ho po několik měsíců používali na reálném projektu, dovolím si během několika článků shrnout zkušenosti - třeba také uvažujete jestli ho použít na projektu nebo jestli zvolit jiné řešení.

Co to vlastně je unit test? Jedná se o "něco" co automaticky otestuje funkčnost část kódu (funkci, proceduru, proces, ...). Primitivní varianta může mít podobu například anonymního PL/SQL bloku, ale Kent Beck (autor xUnit frameworku ze kterého vychází i populární JUnit) zavedl standardní rozdělení unit testů na startup, vlastní unit test a teardown.

  • startup - příprava prostředí pro unit test (data, instance objektů, ...)
  • vlastní unit test - spuštění testovaného kódu, ověření výsledků
  • teardown - vyčištění prostředí (odstranění dat, souborů, uvolnění zdrojů, ...)

a jak uvidíme dál, této struktury využívá i řešení zabudované do SQL Developeru.

Definici unit testu je třeba někam uložit - SQL Developer používá "repository" což není nic jiného než Oracle schéma s definovanou sadou tabulek. Vývojář tedy pracuje tedy se dvěma typy schémat - jedním či více schématy ve kterých je vyvíjen PL/SQL kód, a schématem ve kterém jsou uloženy definice unit testů (s tím ale pracuje nepřímo přes SQL Developer).

Demonstrace vytvoření jednoduchého unit testu

Založte si dva uživatele - DEVEL_SCHEMA a UTREPOS_SCHEMA se standardními právy (a odpovídající spojení v SQL Developeru). V prvním schématu budeme programovat, ve druhém bude uložena definice unit testů.

spojení na databázi - devel pro schéma DEVEL_SCHEMA a utrepos pro UTREPOS_SCHEMA

Nyní vytvoříme jednoduchou PL/SQL funkci "REPEAT" která bude opakovat zadaný řetězec (počet opakování je dán druhým parametrem), a její unit test. Implementace funkce je velice jednoduchá:

implementace funkce REPEAT opakující daný řetězec

Nyní pro tuto funkci vytvoříme unit test - nejdříve ale musíme nadefinovat repository pro unit testy, tj. sdělit SQL Developeru že pro uložení testů má používat schéma UTREPOS_SCHEMA (resp. odpovídající connection "utrepos"). To se dělá pomocí položky "Tools -> Unit Test -> Select Current Repository ..." v menu.

definice repository pro unit testy v SQL Developeru

Z nabídnutého seznamu spojení vyberte spojení odpovídající schématu UTREPOS_SCHEMA (v mém případě "utrepos"), SQL Developer automaticky zjistí že se jedná o prázdné schéma (bez definice potřebných tabulek) a nabídne vám vytvoření repositáře (tj. potřebných tabulek apod.). Současně vám nabídne nagrantování potřebných práv (pokud je daný uživatel nemá přidělena).

Nyní máte repositář pro unit testy na definovaný a SQL Developer ví že ho má používat, takže pojďme vytvořit unit test pro naši PL/SQL funkci. Test udělá jediné - zavolá funkci se zadanými parametry a zkontroluje že vrací očekávaný výsledek.

Klikněte tedy pravým tlačítkem na jméno funkce a z menu vyberte položku "Create Unit Test."

vytvoření unit testu pro funkci

Zobrazí se vám průvodce vytvořením unit testu - několik jednoduchých obrazovek s různými volbami unit testu - názvem (zvolte např. "REPEAT_TEST"), specifikací startup, teardown a validations (v tomto testu je nepoužijeme takže ponechte "none"), a konečně parametry volání funkce a očekávanou návratovou hodnotou.

parametry volání funkce v unit testu

Já jsem vyplnil řetězec "abc" který se má opakovat 3x, tj. očekávaná hodnota je "abcabcabc." Po kliknutí na "Dokončit" je unit test vytvořen v repositáři. Chcete-li ho zobrazit (a spustit), klikněte na záložku "Unit Test" nad seznamem spojení - zobrazí se vám obsah repositáře, tj. seznam unit testů a test suites (a dalších objektů, které tu ale nebudeme rozebírat).

obsah repositáře unit testů - unit testy, test suites, atd.

Pokud kliknete na unit test, zobrazí se vám jeho vlastnosti (všimněte si že v parametrech volání není vyplněna očekávaná návratová hodnota ale řetězec "(null)", i když jste ji při vytváření unit testu zadali - jedná se o bug, musíte ji vyplnit znovu jinak test bude končit chybou).

Samozřejmě máte také možnost unit test spustit kliknutím za zelenou šipku.

vlastnosti unit testu v SQL Developeru

Výsledky unit testu se vám po spuštění zobrazí v přehledné podobě

výsledky spuštění unit testu

Tolik stručná demonstrace definice jednoduchého unit testu.

Závěr

Je ale třeba mít na paměti že se jedná o velmi jednoduchý unit test, a je otázka jak to bude fungovat ve složitějších případech z praxe. Bohužel moje zkušenosti z použití na reálném projektu ukazují že při praktickém použití se naráží na mnoho chyb nebo ještě hůře na vlastnosti, které vytváření unit testů výrazně komplikují. Namátkou se jedná o

  • navázání na jednotlivé funkce/procedury (co unit test, to volání funkce nebo procedury)
  • navázání na konkrétní schéma / nemožnost přepnout na jiné implementaci v jiném schématu
  • nemožnost debuggingu
  • problémy s přejmenováním testovaných metod
  • ukládání v XML
  • žádná možnost popisu unit testů
  • jiné chování při běhu z GUI a jiné při běhu z příkazové řádky (commit / rollback)
  • nutnost spouštění přes SQL Developer (navázání na connections)

Podrobněji ale až v následujícím článku.

Komentáře

K tomuto článku zatím žádné komentáře neexistují (nebo čekají na schválení).

Nový komentář

Všechny komentáře podléhají schválení - mezi odesláním komentáře a jeho zobrazením na této stránce tedy může být prodleva. Vyplníte-li e-mailovou adresu, budete o schválení či neschválení komentáře informováni.

V titulku ani v textu nejsou povoleny HTML tagy - budou automaticky odstraněny. Odstavec ukončíte prázdným řádkem.

(nepovinné)