Was sind einige bewährte Methoden zum Auffüllen und Verwenden einer Testdatenbank?


8

Daher entwickle ich einige datenbankgesteuerte RESTful Java-Webdienste mit Hibernate und MySQL. Zu Testzwecken verwende ich die H2-In-Memory-Datenbank. H2 ist schön und schnell, also hat das sehr gut geklappt. Das einzige Problem ist, dass das Auffüllen der DB-Tabellen vor meinen Tests etwas mühsam ist. Grundsätzlich erstelle und behalte ich eine Reihe von Objekten von Hand. Ich frage mich, ob ich vielleicht den falschen Weg gehe.

Bitte sagen Sie mir, was sind die besten Methoden, um das zu tun, was ich versuche? Irgendwelche Tools, die mir helfen könnten? Irgendwelche allgemeinen Strategien oder Tipps?

Antworten:


4

Ich gehe davon aus, dass Sie Ihre API so entworfen haben, dass Sie Ihre DB-Details ändern können. Wenn nicht, können wir Ihnen dabei helfen.

In Bezug auf die Terminologie möchten Sie ein Fake Test Double verwenden . In diesem speziellen Fall würde ich empfehlen, dieselbe speicherinterne Datenbank (H2) zu verwenden, aber DBUnit für die Arbeit mit JUnit verwenden, um Ihre Tabellen zu erstellen, sie vor jedem Test zu füllen, die Daten nach jedem Test abzuschneiden und schließlich herunterzufahren die Tabellen, sobald Ihre TestSuite fertig ist.

Es gibt andere Lösungen wie Grails und Spring Roo, die einige Testdaten für Sie erstellen, aber DBUnit wird jetzt eine Wohltat für Sie sein.


+1 für DBUnit. Macht das Testen von DB-Code für Unit-Tests sooo viel angenehmer.
TMN

Cool - ich werde das auf jeden Fall überprüfen. Im Moment fordere ich Hibernate auf, die Tabellen mithilfe der Eigenschaft hibernate.hbm2ddl.auto = create-drop automatisch zu erstellen. Funktioniert das mit DBUnit oder sollte ich damit aufhören?
Sangfroid

Es wird damit funktionieren, ja - tatsächlich besteht eine der Möglichkeiten, DBUnit nachzuahmen, darin, Daten einfach als POJOs durch Hibernate einzufügen
Martijn Verburg

Genial! Okay, ich werde das überprüfen.
Sangfroid

Ist es auch notwendig, DI dafür zu verwenden? Im Moment habe ich eine persistance.xml in meinem Ordner / main / resources / META-INF, die meinen akuten DB-Server angibt, und eine persistance.xml in meinem Ordner / test / resources / META-INF, die H2 angibt. Das scheint wirklich gut zu funktionieren. Im Allgemeinen bin ich zu 100% verwirrt über den Frühling - ich habe ihn noch nie benutzt und verstehe nicht, wie er mir hier helfen könnte, obwohl jeder sagt, ich sollte ihn benutzen.
Sangfroid

1

Vielleicht würden Sie davon profitieren, wenn Sie in Ihren automatisierten Komponententests ein spöttisches Framework verwenden?

Es stehen verschiedene zur Auswahl:


Ja, ich benutze Mockito bereits für Unit-Tests. Ich möchte aber auch (Integrations-?) Tests durchführen, die sich an die DB richten.
Sangfroid

+1 für den Vorschlag, Mock-Frameworks über Datenbanklösungen zu verspotten. Der Datenbankansatz führt häufig zu unnötiger Komplexität, die meistens dazu führt, dass der Ruhezustand und nicht Ihre DAOs getestet werden. Außerdem würde ich JMockit in diese Liste aufnehmen - es macht alles . Unveränderliche Zeichenfolge? Das glaube ich nicht.
Gary Rowe

1
Nun, ich sollte erwähnen, dass ich neu im Ruhezustand bin. Daher ist es für mich wichtig zu testen, ob ich alle meine Dinge im Ruhezustand richtig gemacht habe. Es scheint auch, dass viele Operationen nicht mit einem spöttischen Framework getestet werden konnten. Sie haben beispielsweise eine Methode, die eine Reihe von Datensätzen zurückgibt. Wie können Sie testen, ob diese Methode tatsächlich eine Reihe von Datensätzen zurückgibt, wenn Sie keine Datenbank haben, für die sie ausgeführt werden kann?
Sangfroid

@sangfroid, Dies ist ein guter Punkt und etwas, von dem ich auch profitieren kann. Hibernate-Logik und HQL-Abfragen sind im herkömmlichen Sinne nicht gut für Unit-Tests geeignet. In der Vergangenheit war ich auf Tests von Integrationseinheiten angewiesen, um die Funktionalität zu überprüfen, aber diese waren fast immer umgebungsspezifisch und spröde. DBUnit wurde in einer früheren Antwort erwähnt und scheint einen zweiten Blick zu verdienen.
maple_shaft

1

Alles, was Sie wirklich tun können, ist, Objekte von Hand beizubehalten oder eine vorgefertigte Datenbank zu haben, die Sie laden. Sie müssen auch sicherstellen, dass die Datenbank nach jedem Test zurückgesetzt wird.

In einem Projekt, an dem ich arbeite, bin ich neu in Hibernate, daher habe ich eine Reihe von Tests für grundlegende Beziehungs- und Kaskadenoperationen. Mit TestNG habe ich eine GenericHbTestKlasse, von der alle Hibernate-Tests ausgehen. Es verfügt über eine @BeforeMethodMethode zum erneuten Exportieren des Datenbankschemas und einige Dienstprogrammmethoden zum Generieren verschiedener DAO-Objekte. Dadurch kann ich für jeden Test eine Umgebung anpassen.

Der einzige Nachteil beim erneuten Exportieren des Schemas bei jedem Test besteht darin, dass das Ausführen der Tests sehr lange dauert. Aber ich muss nur sicher sein, dass alles getrennt und sauber ist. Wenn Sie mehr Erfahrung mit dem Ruhezustand haben und ein stabileres Schema haben, ist ein erneuter Export vor jedem Test wahrscheinlich nicht erforderlich. Zumindest aber vorher alle Tabellen löschen


1

Haben Sie über eine Objekt-Serialisierung nachgedacht? Dies ist die schnellste und einfachste Methode, die ich verwendet habe.

Es besteht darin, den gewünschten Status zu erstellen und auf die Festplatte zu serialisieren. Mit diesen Dateien füllen Sie die In-Memory-Datenbank, die Sie für Ihre Tests verwenden.

Einer der Vorteile ist, dass Sie die Dateien später manuell bearbeiten können.

Wenn Sie in Ihren Komponententests gut organisiert sind, können Sie alternativ Objektgeneratoren erstellen. Wenn die Tests starten, wird die Datenbank instanziiert und das Schema exportiert (mit nHibernate). Objekte werden generiert und in der Datenbank ausgefüllt.

Diese Methode hat einen Vorteil gegenüber der ersten: Ihre Objektgeneratoren entwickeln sich mit Ihrem Code weiter, sodass Sie sich nicht wie im vorherigen Vorschlag um Ihre Dateien kümmern müssen.


+1 für einen interessanten Ansatz, aber es könnte ein bisschen zerbrechlich sein.
Gary Rowe
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.