Was versteckt sich hinter der Bezeichnung utPLSQL?

Die Bezeichnung „utPLSQL“ setzt sich aus zwei Bausteinen zusammen. Das „ut“ steht für Unit Test und das „PLSQL“ steht für die Prozedurale Programmiersprache von Oracle, welche im Zusammenhang mit SQL verwendet wird. Aus dem Begriff utPLSQL lässt sich also nun schon erahnen, um was es im Folgenden gehen wird: um das Unit Testing im Umfeld von PLSQL.

Um genauer zu sein: utPLSQL ist ein OpenSource Framework für Unit Tests in PLSQL. Die Syntax ist hier an die Syntax bekannter Unit Test Frameworks, wie z.B. JUnit angelehnt. Zudem werden die Tests in PLSQL geschrieben, was den Vorteil bringt, dass der Entwickler, der eine Funktion in PLSQL geschrieben hat und diese nun testen möchte, keine neue Sprache lernen muss.

Zudem unterstützt utPLSQL das Test Driven Development. Es ist also möglich, Unit Tests mittels utPLSQL schon früh in seine Entwicklung einzubinden, um so seine Fortschritte regemäßigen Tests zu unterziehen.

Heutzutage gibt es immer noch sehr viele Entwickler, die Tests für überflüssig halten. Doch im Folgenden soll gezeigt werden, dass Tests eine sehr wichtige Rolle bei der professionellen agilen Softwareentwicklung spielen und zu dem einigen Ärger ersparen können. Und vielleicht kann dann doch der ein oder andere Entwickler davon überzeugt werden, dass Testen gar nicht so schrecklich ist, wie immer vermutet.

Warum sollte man testen? Man weiß doch, was man programmiert hat!

Es stimmt wohl, dass, wenn man etwas programmiert hat, auch wissen sollte, was man  geschrieben hat. Aber in der Realität ist dies nicht immer der Fall. Eine Methode wird dann doch mal schnell mehrere hundert Zeilen lang und durch die ganzen Sonderfälle kann  man schon mal den Überblick verlieren. Am Ende weiß man dann doch nicht mehr so genau, ob man wirklich alles beachtet hat. Vielleicht wird die Funktion sicherheitshalber ein oder zweimal getestet, man sieht, dass alles funktioniert und schließt die Entwicklung ab. Beim Kunden auf dem System kommt dann das böse Erwachen, wenn die Funktion dann auf einmal doch nicht mehr so funktioniert, wie es eigentlich vorgesehen war. Hätte man doch lieber ein wenig mehr getestet, dann hätte  man sich den ganzen Ärger und Stress  ersparen können.

Dies ist nur ein kleines Beispiel, welches veranschaulichen soll, warum Unit Tests so hilfreich sind und definitiv keine Zeitverschwendung sind. Im Folgenden sollen auch noch einige weitere Aspekte aufgelistet werden, warum man Unit Tests in seinen Programmieralltag integrieren sollte:

  • Aufräumen, statt im Chaos zu suchen: Wenn man einen Unit Test für eine Funktion schreiben muss, die man zuvor entwickelt hat, so muss man sich mit dieser Methode intensiv auseinandersetzen und man stellt vielleicht fest, dass alles viel zu kompliziert geschrieben ist. Der Code wird dann nochmal umgeschrieben, und zwar strukturierter. Dadurch wird es auch für andere und auch für einen selbst einfacher, wenn man hier später nochmal was ändern muss.
  • Vorausschauend seine zukünftigen Fehler vermeiden: nicht selten passiert es, dass man eine bereits fertige Funktion noch mal bearbeiten muss, oder man bearbeitet Komponenten, die für diese Methode relevant sind und plötzlich läuft eine Funktionalität, die eben noch ging, auf Fehler. Mittels Unit Tests kann man dies vermeiden, denn wenn ein Unit Test vor den Änderungen noch ein korrektes Verhalten angezeigt hat, sollte das nach den Änderungen immer noch der Fall sein.
  • Sonderfälle im Blick behalten: gerne werden Sonderfälle ignoriert oder vergessen, aber irgendwann gibt es immer diesen einen Fall, bei dem der Datensatz zum Beispiel auf einmal leer ist oder eine negative Zahl übergeben wird. Mit einem Unit Test kann man sich gegen solche bösen Überraschungen wappnen, indem man direkt für solche Fälle einen Test baut, um das Verhalten bei Sonderfällen zu beobachten und entsprechend anzupassen.
  • Nicht für den Mülleimer entwickeln: Nach dem man einen Test entwickelt hat und er seinen Dienst getan hat, sollte er nicht irgendwo abgelegt werden und in Vergessenheit geraten. Eine praktische Funktion von Unit Tests ist, dass man sie automatisieren kann. So kann regelmäßig getestet werden, ob nach Änderungen noch alles funktioniert, wie es soll.
  • Weniger Stress und mehr Kontrolle: Wenn regelmäßig, schon während der Entwicklung getestet wird, fallen Fehler früh auf und können dementsprechend früh korrigiert werden. Die böse Überraschung am Ende bleibt erspart. Dadurch entsteht am Ende der Entwicklung auch weniger Stress, weil man sich zwischendurch immer wieder vergewissern kann, dass die Funktion so arbeitet, wie es vorgesehen ist.

Und welche Vorteile bringt die Verwendung von utPLSQL?

utPLSQL ist speziell für PLSQL entwickelt worden. Natürlich macht es dann auch nur Sinn, denn Einsatz von utPLSQL zu wählen, wenn auch der zu testende Code in PLSQL geschrieben wurde. Ist dies der Fall, bringt utPLSQL einige Vorteile mit und erleichtert die Verwendung von Unit Tests in diesem Kontext. Hier sind einige Vorteile aufgelistet, welche utPLSQL zu bieten hat:

  • Warum etwas Neues lernen: bei der Verwendung von utPLSQL muss der Entwickler keine neue Sprache lernen. Sein zu testender Code ist in PLSQL geschrieben und Tests in utPLSQL werden ebenfalls in PLSQL geschrieben. Auch für Entwickler, die bereits andere Unit Test Frameworks verwendet haben, dürfte utPLSQL bekannte Elemente enthalten, da die Syntax sich an bekannte Frameworks orientiert.
  • Schnittstellen bringen immer Probleme, deswegen gibt es keine: utPLSQL wird in derselben Datenbank installiert, in der auch der zu testende Code liegt, es gibt also keine Schnittstellen zu anderen Systemen. Zudem gibt es auch nur bekannte Dateiformate, da die Tests in Packages abgelegt werden.
  • Kein stundenlanges einrichten: utPLSQL kann in eine bereits bestehende Datenbank problemlos installiert werden. Die Ausführung eines Installationsskriptes genügt hier. Auf der offiziellen Seite von utPLSQL gibt es eine ausführliche Dokumentation inklusive der benötigten Skripte.
  • Keine Kosten: utPLSQL ist ein Open Source Framework und kostenlos. Man kann also ohne großes Abwägen der Kosten utPLSQL in seine Datenbank installieren und mit dem Testen beginnen.
  • Automatisieren ohne viel Aufwand: utPLSQL lässt sich sehr leicht in Jenkins integrieren. Hier kann man dann für seine Tests automatisierte Jobs erstellen, die dann regelmäßig gestartet werden und einen Statusbericht über die Tests erstellen
  • Einfaches Visualisieren: sowohl in Jenkins als auch in Apex lässt sich utPLSQL schnell integrieren. Beide bieten die Möglichkeit, die Tests auszuwerten und visualisiert darzustellen. So behält man immer einen Überblick über all seine Tests.

Wenn die erwähnten Vorteile nun den einen oder anderen Entwickler überzeugt haben, dass Tests doch eine sehr wichtige Rolle spielen und es doch nicht so schlimm ist, Tests zu schreiben, gibt es hier noch einige Best Practice Tipps für ein erfolgreiches Testen:

  • Kein Würfelspiel: Die Tests sollten deterministisch sein. So sollte eine identische Eingabe immer ein identisches Ergebnis liefern.
  • Weniger ist mehr: Ein Test sollte immer nur genau einen Testfall abdecken. So kann es durchaus sein, dass für eine zu testende Funktion mehrere Tests existieren, die alle unterschiedliche Fälle testen.
  • Unabhängig: Ein Test sollte unabhängig sein von anderen Tests, vom Systemstatus und generell von allem, was in diesem Programm existiert. Es soll ja nur der zu testende Code getestet werden und nicht irgendwelche Seiteneffekte.
  • Wer wenig schreibt, macht weniger Fehler: Die Tests sollten so wenig Logik wie möglich enthalten und so einfach wie möglich gestaltet werden, so kann ausgeschlossen werden, dass ein negatives Testresultat aus einem fehlerhaften Test resultiert.
  • Wissen, was man will: Bevor der Tests geschrieben wird, sollte man eine Erwartungshaltung haben: Bei welcher Eingabe wird welche Ausgabe erwartet?
  • Verständigungsschwierigkeiten: Der Test sollte aussagekräftig sein. Man sollte sich überlegen, was der Test zurückgibt und was dies bedeutet. So ist zum Beispiel das Ergebnis: ‚The result is 1‘ nicht gerade aussagekräftig, ‚Test failed because 1 <> 0‘ hingegen schon.
  • Goldwert oder Zeitverschwendung: Der Aufwand für einen Test sollte sich lohnen. Wird der Test regelmäßig benötigt und testet er eine komplizierte Funktionalität, ist er wahrscheinlich sehr wertvoll. Anders sieht es dabei zum Beispiel aus, wenn ein einfaches Insert getestet wird, welches nur einmal benötigt wird. Da wird sich der Mehraufwand eher nicht lohnen.
  • Die Überraschung vorwegnehmen: Um die bösen Überraschungen am Ende der Entwicklung zu ersparen, sollte die zu testende Methode schon während der Entwicklung getestet werden und nicht erst, wenn alles fertig zu sein scheint, so kann man Fehler frühzeitig korrigieren.
  • Gleiches zu Gleichem: Existieren mehrere Tests, welche die gleiche Funktionalität testen oder logisch zusammengehören, sollten diese auch als zusammengehörig markiert werden. In utPLSQL kann dies umgesetzt werden, indem man die Tests mit Tags versieht oder sie in dasselbe Package/dieselbe Suite einordnet.
  • 1 ist nicht immer 1: Beim Testen sollte unbedingt auf den Datentyp geachtet werden, denn selbst, wenn das Ergebnis aussieht, wie erwartet, muss es nicht richtig sein, es muss auch noch vom richtigen Datentyp sein, damit der Test als erfolgreich gilt.
  • Nicht stören: Ein Test sollte nie andere laufende Prozesse stören. Es muss gewährleistet sein, dass ein Test keine Daten ändert und auch keine Prozesse blockiert, die für den Programmfluss wichtig sind.
  • Ordnung muss sein: Für utPLSQL sollte ein separates Schema erstellt werden, so dass der zu testende Code und die Tests in unterschiedliche Schemata liegen. Das Schema utPLSQL sollte dann auch nur die relevanten Berechtigungen erhalten, die zum Testen benötigt werden.
  • Täglich grüßt das Murmeltier: Tests sollten automatisiert werden, damit der Code regelmäßig getestet wird. Tests, die manuell gestartet werden müssen, werden irgendwann vergessen oder als umständlich angesehen und nicht mehr genutzt. So sollte ein Test nicht enden.
  • Vier Augen sehen mehr als Zwei: Derjenige, der eine Methode entwickelt hat, sollte diese nach Möglichkeit nicht testen. Das sollte ein anderer Entwickler übernehmen, da dieser einen anderen Blickwinkel auf die Funktion hat und so die Wahrscheinlichkeit geringer ist, Fehler zu übersehen
  • Blackbox: Beim Testen soll nicht überprüft werden, wie eine Methode funktioniert, sondern ob sie richtig funktioniert. Es interessieren hier also lediglich der Input und der Output und nicht, warum aus einem bestimmten Input genau ein bestimmter Output folgt.
  • Doppelt hält nicht besser: Auch beim Schreiben von Tests gilt es, doppelten Code zu vermeiden. In utPLSQL gibt es zum Beispiel mit beforeaech oder mit aftereach die Möglichkeit, Prozesse zu bestimmen, die nach oder vor jedem Test laufen sollen.

Quellen:


utPLSQL – Blogserie Teil 2:

utPLSQL – Blogserie Teil 3:

https://www.mt-ag.com/blog/know-how/softwareentwicklung/utplsql-eine-einleitung/

Tags:

Keine Kommentare vorhanden.

    Schreibe einen Kommentar

    Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.