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ů.

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á:

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.

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."

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.

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).

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.

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

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.




