Oracle Testen DB-Background-Jobs mit JUNit

turmaline

Bekanntes Mitglied
Hallo Leute,

obwohl es eigentlich beschlossen wurde keine JUnit-Tests für die DB-Background-Jobs zu schreiben, würde mich interessieren, wie Ihr das machen würdet. Das Thema lässt mich nicht in Ruhe, da ich gewohnt bin, Tests für das Backend zu schreiben und mir unkontrollierte (nicht ausreichend getestete) Änderungen des Datenbankzustandes Angst machen... ihr versteht was ich meine?

Es liegt folgende Situation vor:

- es gibt eine Oracle-DB
- es gibt mehrere Jobs die beim Vorliegen bestimmter Bedingungen eine Tabelle ändern: es kann ein UPDATE oder ein DELETE sein (nicht entweder oder, sondern das sind zwei verschiedene Jobs).
- diese Jobs werden automatisch (wenn bestimmte Regeln vorliegen) bzw. manuell vom Administrator angetoßen werden.

Nun implementiert habe ich die jobs schon und ich habe sie manuel getestet aber das ist meiner Meinung nach nicht ausreichend. Was ist Eure Meinung dazu?

Meine Idee solche Jobs mt JUNIt zu testen wäre folgende:

1) Test erstellt eine DB (bzw. nimmt eine Test-DB, kopiert beispielsweise jedes Mal aus dem Ressource-Verzeichnis in den runtime-ordner eine Test-DB).

2) Nun, da es eine Test-DB ist wissen wir ganz genau welchen Zustand sie hat und der ist am Anfang beim Ausführen jedes Tests immer gleich.

3) Wir starten den Job und wissen was rauskommen soll, somit können den Zustand der DB prüfen.

Wäre so eine Vorgehensweise sinnvoll bzw. was für Alternativen gäbe es?

Gruß, madlena
 
M

maki

Gast
Hi,

du beschreibst die 4 Phasen des klassischen autom. Tests, was übrigens unabhängig davon ist ob man Stored Proceduress, Javacode oder sonstetwas testet.

1. Setup - Hier werden alle Vorrausetzungen für den Test geschaffen, zB. eine sog. Testfixture aufgesetzt, d.h. in diesem Falle wohl Datenbank, Tabellen, Stored Procedures und Testdaten
2. Exercise - hier werden die zu testenden Funktionen aufgerufen
3. Verify - Ergebnisse prüfen
4. Teardown - ressourcen freigeben, aufräumen, etc. pp.

Beachte, dass ein richtiges Setup nicht darauf angewiesen ist bzw. davon ausgeht dass der Teardown sauber gelaufen ist, wenn ein test fehlschlägt kann es schnell passieren dass der Teardown nicht sauber ausgeführt wird. Im Falle eines DB tests führen die übriggeblienen Testdaten schnell zu problemen für den nächsten Test (testdata leakage) wenn das Setup falsche Annahmen macht, also davon ausgeht dass der letzte Test richtig aufgeräumt hat.

In deinem falle müsstest du dir überlegen in welcher Sprache du die Tests schreibst, für Java gibt es zB. DBUnit als JUnit-Erweiterung um RDBMS zu testen.
 

turmaline

Bekanntes Mitglied
HI, danke für Deine Antwort,

DBJunit kenne ich nicht, danke für den Tipp ich werde es mir ansehen.
Ja ich habe beschrieben so wie ich das Testen mit JUnit kenne. Mein Problem in dem Fall ist: die Datenbank, ich weiß nicht wie ich das sauber lösen soll. Einen skript laufen lassen, der mir jedes mal Datensätze anlegt? der test sollte schließlich einfach änerbar sein, wenn sich beispielsweise die DB ändert.
 
M

maki

Gast
Einen skript laufen lassen, der mir jedes mal Datensätze anlegt?
Ein SQL Script, oder ein ORM das autom. das Schema erstellt (Hibernate, EclipseLink), oder per Javacode wie mit DBUnit möglich.
Ob man für jeden Test das komplette Schema neu erstellt kommt darauf an, wie schnell/langsam die DB ist.
Vorteil: Man hat immer eine saubere Ausgangsbasis.
Nachteil: Kann recht langsam sein...

Man kann natürlich vor jedem Test auch einfach alle Tabellen flushen, kann aber nebeneffekte haben (Ids/Sequenzen die nicht mehr bei 1 anfangen, etc. pp.)

DbUnit - About DbUnit

Beispiel mit DBUnit ohne externe XML Dateien (unter "Example: Back Door Fixture Setup ") :
Back Door Manipulation at XUnitPatterns.com
 

turmaline

Bekanntes Mitglied
ja Hibernate wäre möglich, allerdings sollte das Schema synchron mit dem Schema der produktiven DB sein.
jedenfalls vielen Dank für die Rückmeldung, ich schaue es mir alles an.:rtfm:
 

turtle

Top Contributor
Ich werfe noch eine Alternative in den Riing ;)

Dieses Verfahren setze ich manchmal ein, wobei ich mir bewusst bin, dass dieses Vorgehen nicht immer sinnvoll oder einsetzbar ist.

Es beruht darauf das der Entwickler einen DB-Test auf einer in-memory Datenbank (z.B mit Derby jdbc:derby:memory:myDB) durchführt. Sollte durch Umstellung der JPA/Hibernate-Umgebung einfach machbar sein.

Dann kann jedesmal bei jedem Testdurchlauf eine DB neu erzeugt werden. So ist sich der Entwickler zumindest sicher, dass der Backend-Code läuft. Man weiss allerdings nicht, ob es das auch auf der Produktiv-DB noch funzt. Dieses ist aber IMHO nicht Bestandteil von jUnit-Tests.
 
M

maki

Gast
@turtle
DB Tests sind keine (isolierten) Unittests, sondern Integrationstests, weil dabei Systemgrenzen überschritten werden.

Dein Vorschlag mit In-Memory Derby ist sehr gut, einmal weil Derby sehr ähnlich zu Oracle ist und trotzdem viel schneller.
Eignet sich sehr gut für autom. Tests, die der Entwickler an seiner Maschine durchführt.
Der CI Server sollte dann aber die richtige Db Sfotware für die Integrationstests verwenden, lässt sich zB. per Maven Profile umsetzen. Hab wir in der Vergangenheit immer so gemacht und sind sehr gut damit gefahren.
 

turtle

Top Contributor
DB Tests sind keine (isolierten) Unittests, sondern Integrationstests, weil dabei Systemgrenzen überschritten werden.

Das ist doch wohl klar.

Der TO hatte geschrieben, dass er sich "unwohl" fühlt bei nicht ausreichend getesteten Dingen. Daher habe ich vorgeschlagen, wie ein weiterer Schritt aussehen könnte. Dabei habe ich aber angemerkt, dass dies nicht immer sinnvoll oder einsetzbar ist. Ich setze häufig diese Art der Tests ein, bevor ein grosser Integrationstest startet. So habe ich mehr Vertrauen in meinen Backend-Code. Dieses scheitert natürlich wenn DB-Spezifika benutzt werden oder der Test einfach viel zu lange dauert um häufig aufgerufen zu werden.

Aber ich sehe schon, wir verstehen uns hier wohl ganz gut, oder?;)
 

fastjack

Top Contributor
Für diese Art der Tests setzen wir bei uns immer HSQL ein. Wir gehen immer den Weg: DB-Klasse mit Mocks testen (Unittest) und extra Test mit HSQL (DBUnit) und Integrationstest mit dem derzeit von uns präferierten DB-System.
 

turmaline

Bekanntes Mitglied
Ich schaue mir DBUnit an. Die entscheidende Frage ist dabei, wie man den Data Set erstellt bzw. exportiert so dass die Tests relativ leicht zu pflegen sind.

Die beste Alternative finde ich das DB-Schema einmalig zu exportieren (geht das mit DBUnit?), anschließend die Datensätze anlegen (vor jedem Test separat gemacht). Bei der Änderung des Schemas muss der Schema-Exportvorgang neu gemacht werden sowie das automatische Anlegen von den Datensätzen müsste angepasst werden. Das ist die Idee.

Bis jetzt habe ich nur gefunden wie ich die Datensätze aus der DB exportiere. Wie könnte ich das Schema exportieren? Ich meine automatisch. Ein neues Schma per Hibernate manuel anzulegen fände ich nicht so gut, da es nicht synchron mit der DB wäre.

Irgendwelche Ideen?
 

turmaline

Bekanntes Mitglied
was ich meine ist: ich brauche ein Datenbankschema, das mit dem Schema der produktiven DB übereinstimmt und durch einen einfachen Vorgang upgedatet werden kann (mir ist klar, dass das Erstellen der Datensätze in dem Fall auch angebasst werden soll - "nichts bleibt gleich"...)
 

Ähnliche Java Themen


Oben