|
» myCSharp.de Diskussionsforum |
|
|
|
Autor
 |
|
|
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
|
|
21.09.2020 12:17
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
|
Zitat von T-Virus: |
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 :D )
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...
|
|
21.09.2020 13:16
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
|
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
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Lars Schmitt am 21.09.2020 13:23.
|
|
21.09.2020 13:19
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
|
Zitat von T-Virus: |
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.
|
|
21.09.2020 13:22
|
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
T-Virus
myCSharp.de-Mitglied
Dabei seit: 17.04.2008
Beiträge: 1.703
Entwicklungsumgebung: Visual Studio, Codeblocks, Edi Herkunft: Nordhausen, Nörten-Hardenberg
|
|
@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
|
|
21.09.2020 13:25
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
|
Zitat von Lars Schmitt: |
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.
|
|
21.09.2020 13:35
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
Abt
myCSharp.de-Team
Dabei seit: 20.07.2008
Beiträge: 14.512
Herkunft: BW
|
|
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.
Zitat von ThomasE.: |
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.
|
|
21.09.2020 13:40
|
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
|
Zitat von Abt: |
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".
|
|
21.09.2020 14:06
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
Abt
myCSharp.de-Team
Dabei seit: 20.07.2008
Beiträge: 14.512
Herkunft: BW
|
|
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.
|
|
21.09.2020 15:03
|
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
|
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ü
|
|
21.09.2020 16:11
|
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
|
|