# Test Umgebung für Datenbank erstellen, was braucht es?



## REC (28. Okt 2014)

Hallo zusammen  

Ich habe schon viel gegoogelt über das Testen mit JUnit. Kann auch normale Junit Test zu normalen Java Klassen schreiben. Da ich mich mehr oder weniger zum ersten mal damit auseinader setzte wollte ich mal meine Situation erklären und hoffe das jemand eine Idee hat wie ich das am besten bewerkstelligen könnte.

Viele Klassen greifen auf DB's und Tabellen zu die auf anderen Server liegen. Aber ich denke das ist nicht das Problem das funktioniert ja(verbindung aufbauen, Sätze schreiben/lese). Das Problem ist eher der Inhalt der Tabellen. Um einen Satz zu erzeugen müssen oft zuerst auf anderen Tabellen Sätze erzeugt werden um überhaupt einen Testsatz in der DB zu erstellen. Das ist oft mühsam und man braucht mehr Zeit für die Testvorbereitung als für den Testcode selbst. Und diese DB sollen nach dem Test wieder im dem Zustand sein wie vor dem Test.

Ich wollte hier mehr sowas wie ein Brainstorming machen und wissen was euch dazu in den Sinn kommt. Also was für Technologien kann ich wie benutzen und wie wende ich diese speziell im zuammenhang mit DB's an. 
Zum Beispiel:
- Mockito. Aber dort kann ich einträge nur simulieren, aber ich muss ja wirklich überprüfen ob die Einträge auf der DB sind. 
-Oder Blackbox und Whitebox Test was brauche ich eher. Habe bis jetzt immer Blackbox verwendet. 
-Oder wäre es sinnvoller eine cleane DB lokal zu installieren und da drauf zu testen? 

Ninnt mich einfach mal Wunder was erfahrene JUnit Tester, mir alles rundum JUnit und DB testen erzählen können.


----------



## BuckRogers (29. Okt 2014)

Hi,

eine Möglichkeit wäre ein Intergrationstest. Das geht aber etwas über das Testen der Datenbank hinaus.

Andererseits könntest du dir ein eigenes Testframework bauen welches ein DB Schema erstellt, die Tabellen erstellt, Datensätze hinzufügt. Dann laufen all deine Tests und danach wird das Schema einfach gedroppt.
Eigentlich kein großer Aufwand.


Grüße


----------



## EasyEagle (29. Okt 2014)

Hallo REC,
also spontan würde mir da DBUnit einfallen: DbUnit - About DbUnit
Ein weiteres (meiner Meinung nach richtig cooles Tool) für Datenbank-Geschichten ist Liquibase: Liquibase | Database Refactoring | Liquibase

Vg,
EasyEagle


----------



## REC (29. Okt 2014)

Danke! genau auf solche Vorschläge habe ich gehofft. Ich werde diesen mal nachgehen.

Ich habe mich auch gefragt ob es ein Tool gibt, um irgendwie bestehende Datensätze in XML zu exportieren um diese Werte dann wieder für den Test einzulesen.
Also ich habe einen DB EIntrag der genau zu meinem Test passt. Um den Test unabhängig zu machen exportiere ich diese Daten in eine XML. Und immer wenn der Test startet dann lädt er diese XML in die DB. ich hoffe es verständlich geschrieben zu haben.
@Edit Haha habe mit DB Unit begonnen und bereits nach dem ersten Absatz steht das dies genau mit diesem Tool möglich ist

@BuckRogers Was meinst du ein DB Schema erstellen? Einfach eine neue Database anlegen und darin all die Tabellen erstellen? Das Problem ist einfach das es zum Teil Tabellen mit 100 Feldern ist. Das kann ich ja nicht schnell erneut eingeben?


----------



## BuckRogers (29. Okt 2014)

Hi REC,

Die Spaltenanzahl ist nicht das Problem, sondern die Daten. 
Keine neue Datenbank, ein neues Schema mit anderem Namen. Da spielt dein Testframework die Tabellen ein, setzt die neue DataSource für die Testumgebung, ohne Datensätze. Den Dump dafür kannst du ganz easy exportienen und dann verwenden. Die einzelnen Tests beinhalten noch Skripte mit Datensätzen für die Tabellen. Am Ende wird das ganze gedroppt. DBunit sollte dir dabei behilflich sein, wie EasyEagle anmerkte.

Gruß


----------



## REC (29. Okt 2014)

Ok danke dann werde ich mal sowas in der Richtung versuchen. DBUnit habe ich mir angesehen, nicht ganz einfach das Tool überhaupt zu installieren. Man muss ja Maven verwenden. Und damit hatte ich bisher nichts zutun.

Danke für Eure Antworten


----------



## BuckRogers (29. Okt 2014)

Du musst nicht unbedingt Maven verwenden. Dann heißt es aber, dass du deine Abhängigkeiten zu den Bibliotheken selbst definieren und der Applikation zur Verfügung stellen musst. Außerdem willst du ja DBUnit nur zu Testzwecken verwenden. Maven nimmt dir dabei das Management ab. Man kann mit Maven sehr viel konfigurieren und die Abhängigkeiten schnell implementieren. Dich mit Maven auseinanderzusetzen würde dir mit Sicherheit viel nützen. Versuche es einfach mal


----------



## REC (29. Okt 2014)

Entschuldige die Frage aber, auf dieser Seite DbUnit - Downloading dbUnitsteht doch das man maven verwenden muss, oder sonst die "alte" Jar ninnt? Wie bekomme ich den die DBUnit ohen Maven zum laufen?
Oder kann ich mich hier unter "Installation" orientieren wenn ich es ohne Maven laufen lassen will? DBUnit


----------



## BuckRogers (29. Okt 2014)

Ja, ohne Maven musst du dir eine JAR runterladen und einbinden. Ob da jetzt nur alte Versionen zur Verfügung stehen weiß ich nicht. Ansonsten füge doch einfach Maven in dein Projekt ein. 

Eclipse:
Maven zu bestehendem Projekt in Eclipse hinzufügen - StackOverflow


----------



## REC (29. Okt 2014)

Danke  super sieht nach dem ersten Überfliegen gut aus der Artikel . Ok dann habe ich nun 2 Möglchkeiten, eine werde ich wohl zum laufen bringen.


----------



## REC (29. Okt 2014)

Sorry ich muss nochmals nachfragen. Ich habe nun dbUnit zum laufen gebracht. Ich kann auch diese XML dataset erstellen lassen. (Leider habe ich es aber mit der jar gemacht anstatt das ganze Maven aufzugleisen ;-) )
Nun ich stelle mir das so vor das ich eine XML exportiere, diese dann so verändern kann wie ich will und diese dann wieder IMPORTIEREN kann.Also in die DB reinschreiben. Einfach um zusehen ob ich datensätze so vorbereiten kann wie ich will. Aber leider funktioniert das nicht. Ich finde allgemein im Web wenig zum Thema inportiern mit DBUnit, daher habe ich langsam das Gefühl falsch verstanden zu haben wie man mit dbUnit arbeitet. 
Kann mir jemand mal kurz den Ablauf notieren? Ich habe langsam den Überblick verloren. Oder ich sehe vor lauter Bäume den Wald nicht mehr.


----------



## BuckRogers (29. Okt 2014)

-Welches XML? Auszug?
-Wie sieht die Fehlermeldung aus? Auszug?


----------



## REC (30. Okt 2014)

Das war der Ursprüngliche satz

```
<?xml version='1.0' encoding='UTF-8'?>
<dataset>
  <RPM PMMAND="900" PMID="PM" PPUST="100001" PMSB="os3" PNME="Test AG"/>
</dataset>
```

Dann verändere ich den Satz so wie ich es gerne hätte. Der name der XMl ist "partialUPDATE.xml"


```
<?xml version='1.0' encoding='UTF-8'?>
<dataset>
  <RPM PMMAND="900" PMID="PM" PPUST="100001" PMSB="os3" PNME="Test AG EIn veränderter Datensatz" />
</dataset>
```

Und habe dann versucht ihn wieder einzulesen:

```
FlatXmlDataSetBuilder xmlDataSetBuilder = new FlatXmlDataSetBuilder();
        IDataSet dataSet = xmlDataSetBuilder.build(new File("partialUPDATE.xml"));
      

        try {
            DatabaseOperation.CLEAN_INSERT.execute(connection, dataSet);
        } catch (DatabaseUnitException due) {
            throw due;
        } finally {
        }
```

@Edit Ach ja wenn ich im Debugger nachsehe dann sehe ich in der variable "dataSet" nur AbstractDataSet[_orderedTableNameMap=null]


----------



## REC (30. Okt 2014)

Ok ich habe es. 
Komischerweise stimmte der Pfad nicht wo ich nach der Datei suchen musste. Die Datei lag im Class Ordner. Darum verwies ich mit dem Pfad auf den Class Ordner dann ging es


----------



## BuckRogers (30. Okt 2014)

Ja das lesen der Exceptions und das Debuggen kann sehr behilflich sein in der Findung der Ursache. Pfadprobleme wirst du noch öfter haben. Vor allem wenn deine App auf verschiedenen Betriebssystemen laufen soll. Da kommt Freude auf 

Mit diesen XML-DataSets und FlatXmlDataSetBuilder kenne ich mich leider nicht aus.
Ich handhabe das immer folgendermaßen:

sriptAtStart.sql:

```
create schema 'test';
use test;
CREATE TABLE table_name
(
column_name1 data_type(size),
column_name2 data_type(size),
column_name3 data_type(size),
....
);
INSERT INTO table_name
VALUES (value1,value2,value3,...);
```
usw...

dann das ganze im test ausführen:

```
@Before
public void prepareTests(){
     // read in the script file and run script in mysql database
...
}

@Test
public void runAllTheTests(){
     // run a test here or more
}

@After
public void tearDown(){
     // drop DB
     // or delete data or do whatever to prepare for new tests etc...
}
```


----------

