Laden...

Was ist die effektivste Möglichkeit, eine Memory-Datenbank mit Tabellen zum Testen zu erstellen?

Erstellt von ThomasE. vor 3 Jahren Letzter Beitrag vor 3 Jahren 775 Views
T
ThomasE. Themenstarter:in
461 Beiträge seit 2013
vor 3 Jahren
Was ist die effektivste Möglichkeit, eine Memory-Datenbank mit Tabellen zum Testen zu erstellen?

verwendetes Datenbanksystem: SQL

Hallo zusammen,

ich hätte nach längeren wieder mal eine Frage wenn es um Unit-Tests geht.

Was ist wohl die effektivste Möglichkeit, eine (welche) memory-Datenbank (Tabellen) zu erstellen, in der man mit DB-Kommandos wie in echt selektieren kann?

Wobei ich die memory-Datenbank als Mock-Quelle verwenden möchte, die Daten ansich sind nicht das Problem.

Bin sicher das es da schon ganz bestimmte Lösungswege gibt, nur tappe ich momentan im Dunkeln...

Bitte um Info, vielen Dank im Voraus,
Thomas

Ich habe den Titel mal angepasst, so dass Suchende auch etwas damit anfangen können. EDIT: Ich sollte beim Wort "Shift" im Titel das "f" nicht vergessen... 😄

T
2.219 Beiträge seit 2008
vor 3 Jahren

Wenn ich dich richtig verstehe, willst du deine Tabelle für Unit Tests als In Memory Tabelle anlegen lassen?
Halte ich nicht für zielführend, da du dann die eigentlichen DB Operationen auf Dateisystem Ebene ausschließt.
Damit deckst du einen anderen Use Case ab als im produktiv System.

Auch hängt es davon ab, wie du auf die DB zugreifst.
Wenn du z.B. noch über ADO .NET gehst, müsstest du dir nur für einen Unit Test entsprechende Tabellen mit Memory Optimized Einstellung anlegen.
Bei einem OR Mapper wie EF Core könntest du dies mit dem InMemory Provider umsetzen.
Dieser ist auch nur für Tests und nicht auf Geschwindigkeit ausgelegt.
Alternativ müsstest du dir einen eigenen provider bauen.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

T
ThomasE. Themenstarter:in
461 Beiträge seit 2013
vor 3 Jahren

Wenn ich dich richtig verstehe, willst du deine Tabelle für Unit Tests als In Memory Tabelle anlegen lassen?
Halte ich nicht für zielführend, da du dann die eigentlichen DB Operationen auf Dateisystem Ebene ausschließt.
Damit deckst du einen anderen Use Case ab als im produktiv System.

Zum einen verständlich, soll ich das so verstehen, dass sogar für solche Tests auf eine eigene Unit-Test DB zugegriffen wird?
Wäre für mich natürlich eine große Erleichterung... Bisher gibt es sowas nicht bei uns, da wie so oft, vieles nicht mehr dem heutigen Standard entspricht... (aber darauf hingearbeitet wird, leider ist der Technologierfortschritt meist schneller 😄 )

Derzeit noch ADO.NET, sollte sich aber bald ändern.

Der DAL ist eine Eigenproduktion, auch da habe ich schon Ansätze versucht dieses zu ändern...

Ich habe den Titel mal angepasst, so dass Suchende auch etwas damit anfangen können. EDIT: Ich sollte beim Wort "Shift" im Titel das "f" nicht vergessen... 😄

2.223 Beiträge seit 2005
vor 3 Jahren

Hallo ThomasE,

auch wenn auch ich das nicht für eine gute Idee halte, aber welche zugriffstechnologie oder Datenbank benutzt du denn ?

gerade bei den Datenbanken gibt ja schon unterschiedliche SQL Dialekte so, dass sich dein Problem schon nicht so einfach zu beantworten wäre.

Bei einer eigenen DAL, sollte es je nach implementierung auch einfach möglich sein, die erstellten SQL auf irgendeine Memory DB oder sogar xml oder JSON Dokumeten umzuleiten

Viele grüße
lars schmitt

5.657 Beiträge seit 2006
vor 3 Jahren

Halte ich nicht für zielführend, da du dann die eigentlichen DB Operationen auf Dateisystem Ebene ausschließt.

Das ist aber nicht die Aufgabe von Unit-Tests.

Mit Unit-Tests testet man nur die Unit, also eine Klasse bzw. deren öffentliche Methoden. Dazu kann man DB usw. mocken.

Mit System-Tests kann man dann sicherstellen, daß alles zusammen funktioniert wie es funktionieren soll.

Weeks of programming can save you hours of planning

T
2.219 Beiträge seit 2008
vor 3 Jahren

@Lars Schmitt
Da er noch über ADO .NET geht, arbeitet er direkt mit dem Connection/Command Objekten etc.

@ThomasE.
Natürlich musst du für ordentliche Unit Tests eine eigene DB haben und dort alles einmal durchlaufen lassen.
Wenn du z.B. die DAL durchtest, müssen alle Operationen einmal abgedeckt werden.
Jede Methode im Unit Test sollte dann eine Operation in der DAL abdecken.

Vor jedem Test sollten die Tabellen auch einmal geleert werden, damit die Ergebnisse nicht durch Altdaten verfälscht werden.
Ziel bei Unit Tests ist auch immer eine hohe Code Coverage, damit du wirklich alles abdeckst, was abgedeckt werden muss.
Und dabei sollte man auch möglichst immer den gleichen Use Case wie das Produktiv System haben.
Erst dann können auch Fehlerfälle aus dem Produktiv System sinnvoll nachgestellt werden.

Wenn du z.B. einen Fall hast, der wegen großen Datenmengen in der DB auftritt, dann aber wegen einer anderen DB Konstruktion bei dir nicht auftritt, dann hast du deinen eigenen Test durch falsches Umfeld sabotiert.
Hier müssen dann ggf. durch Tests auf Snapshots die Szenarien nachgestellt werden können ohne Sonderschienen beim Unit Testing fahren zu müssen.
Die Umgebung muss also relativ nah am Produktiv System sein, damit die Unit Tests auch erst funktionieren.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

T
ThomasE. Themenstarter:in
461 Beiträge seit 2013
vor 3 Jahren

Bei einer eigenen DAL, sollte es je nach implementierung auch einfach möglich sein, die erstellten SQL auf irgendeine Memory DB oder sogar xml oder JSON Dokumeten umzuleiten

Ja, die Mock-Daten liegen in XML vor, nur werden immer explizit immer dieselben Daten geliefert, was ja wohl in gewissen Tests sinnvoll ist.

Das Problem ist, dass die BL die Selektionen (um es einfach zu nennen) manipulieren kann und danach die Anfrage über den DAL macht.

So haben wir hier teils dynamische Kommandos, die ich gerne wie in echt, geliefert bekommen möchte, ohne fixe Datenrückgaben für jeden einzelnen Fall erstellen zu müssen.

Hoffe das es jetzt verständlicher ist?

Da ist wohl die Überschrift etwas irritierend, obwohl es mehr oder weniger dann doch wieder da hinkommt.
Der Eingangspost weicht stattdessen hier schon stärker ab.

Ich habe den Titel mal angepasst, so dass Suchende auch etwas damit anfangen können. EDIT: Ich sollte beim Wort "Shift" im Titel das "f" nicht vergessen... 😄

16.806 Beiträge seit 2008
vor 3 Jahren

Es gibt eigentlich kein Datenbank-Driver, der im Original als InMemory-Variante zur Verfügung stehen würde und sich identisch verhält.
Ich würde behaupten, dass der InMemory-Driver von EFCore mit am ähnlichsten ist; doch selbst der ist Lichtjahre vom Verhalten von MSSQL / Sqlite entfernt.

So haben wir hier teils dynamische Kommandos, die ich gerne wie in echt, geliefert bekommen möchte, ohne fixe Datenrückgaben für jeden einzelnen Fall erstellen zu müssen.

Wenn ich Dich richtig verstehe, dann testest Du hier aber weit mehr als eine Unit.
Das geht ja eher in Richtung Integrationstest, den man ohnehin anders aufbaut.

T
ThomasE. Themenstarter:in
461 Beiträge seit 2013
vor 3 Jahren

Wenn ich Dich richtig verstehe, dann testest Du hier aber weit mehr als eine Unit.
Das geht ja eher in Richtung Integrationstest, den man ohnehin anders aufbaut.

Hm, ist es wirklich so, dass ich mir nur Arbeit ersparen wollte?
Klar kann ich den memory (Unit-Test) Provider soweit ausbauen, damit er mir aus den übergebenen Informationen der BL aus den XML-Mockdaten korrekt selektieren kann...

In dieser BL sind Kundenspezifische BL-Plugins möglich, diese werden aber dann in den jeweiligen Plugin-Tests abgehandelt.

Ansonsten gibt es soweit keine "Fremdeinwirkungen".

Ich habe den Titel mal angepasst, so dass Suchende auch etwas damit anfangen können. EDIT: Ich sollte beim Wort "Shift" im Titel das "f" nicht vergessen... 😄

16.806 Beiträge seit 2008
vor 3 Jahren

Im Endeffekt ist das Sparen von Arbeit ja immer das Ziel.
Das Problem ist, dass Du eine "fertige InMemory-Datenbank" (also zB EFCore InMemory) eigentlich nur für Unit Testing verwendet werden kann und für Integrationstest aufgrund der Limitations total ungeeignet sind.

Je nachdem wie Du Integrationstests schneidest kann man schon so InMemory nutzen; im Falle von EFCore InMemory funktionieren aber schon einfachste Dinge nicht mehr wirklich (zB Views, Raw SQL, Transaktionen, keinerlei Support von relationalen Abhängigkeiten...), sodass der eigentliche Nutzen dahin ist.

6.911 Beiträge seit 2009
vor 3 Jahren

Hallo ThomasE.,

für SQL Server:
Kannst du SQL Server Express im Docker-Container verwenden?
Dann hast du eine richtige DB, Testdaten kannst du einfügen und so ein Image erstellen das zum Testen verwendet werden kann (ev. auch via CI).

Für andere DBMS halt ein anderes Docker-Image verwenden.

EF InMemory ist für einfach Unit-Tests geeignet -- wie schon erwähnt wurde.
SQLite scheitert wenn Schemas verwendet werden, da diese nicht unterstützt werden.

Wenn bei Tests Inserts/Updates durchgeführt werden, achte darauf dass diese in einer Transaktion durchgeführt werden, die dann nach dem Tests zurückgesetzt wird (rollback), damit zwischen den einzelnen Test-Fällen keine Abhängigkeit entsteht.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"