Ich hatte in letzter Zeit viele Gelegenheiten, in denen ich komplexe gespeicherte Prozeduren und Funktionen verwalten musste. Diese waren bereits kaputt, normalerweise auf ziemlich subtile Weise - es gab nur sehr wenige Fälle, in denen Sie den SP mit gültigen Parametern aufriefen, und es funktionierte einfach nicht.
Meine Lösung bestand darin, ein Rahmenwerk zu entwickeln, das die gespeicherten Prozeduren innerhalb einer Transaktion ausführt, nachdem die Datenbank unter den von mir benötigten Anfangsbedingungen initialisiert und dann auch innerhalb derselben Transaktion auf das erwartete Ergebnis getestet wurde. Die Transaktion wurde am Ende des Tests zurückgesetzt.
Das hat sehr gut funktioniert. Einige würden dies jedoch als "Integrationstest" bezeichnen, da es sich um die Integration in die Datenbank handelt. Ich nenne es Unit-Test, da ich einzelne Komponenten und einzelne Testfälle für diese Komponenten getestet habe und den Anfangszustand der Datenbank vollständig kontrolliert habe.
Aber wo soll die Linie gezogen werden? Handelt es sich um Integrationstests oder Unit-Tests? Gibt es einen praktischen Grund, warum diese Art von Test eine schlechte Idee ist? Wenn dies "nur" Integrationstests sind, hat jemand Vorschläge, wie tatsächliche "Unit-Tests" für diese gespeicherten Prozeduren durchgeführt werden können?
Update, 3 1/2 Jahre später. Bei meinem aktuellen Projekt habe ich mit Erfolg begonnen, SSDT-Komponententests zu verwenden, obwohl diese besser sein könnten. Siehe Überprüfen des Datenbankcodes mithilfe von SQL Server-Komponententests . Diese stellen das Datenbankprojekt normalerweise auf Ihrer Instanz von SQL Server LocalDB bereit, sodass alle Fragen zur Datenbankumgebung, die sich auf den Test auswirken, beseitigt werden. Ich fülle die Datenbank während des Vortests mit den erforderlichen Daten, wodurch Fragen zum Datenbankinhalt entfernt werden. Tatsächlich verwende ich dazu MERGE-Anweisungen, um sicherzustellen, dass alle Daten, die ich für den aktuellen Test nicht benötige, vor dem Test aus der Datenbank entfernt, eingefügt oder aktualisiert werden. Sie haben Probleme:
- Sie sind nicht schnell
- Es ist nicht möglich, Testbedingungen wiederzuverwenden
- Es ist nicht möglich, Vortests wiederzuverwenden (es sei denn, Sie machen sie allen Tests in einem Projekt gemeinsam).
- Die Benutzeroberfläche könnte verbessert werden
Einer der Gründe für die oben genannten Probleme ist, dass ich mich noch nicht darüber beschwert habe. Ich empfehle allen Interessierten, diese Funktion auszuprobieren und sich dann darüber zu beschweren. So werden Verbesserungen vorgenommen.
quelle
Antworten:
Beim Unit-Test geht es nicht darum, eine magische Unit-Test-Fee dazu zu bringen, Ihre Meinung zu bestätigen. Es geht darum, die kleinsten und einfachsten Bausteine Ihres Systems zu testen, damit Sie keine umfangreicheren Funktionen testen und stolpern, weil etwas nicht so funktioniert hat, wie Sie es sich vorgestellt haben. So können Sie diese brechen weiter nach unten? Ich glaube nicht, dass Sie das können. In diesem Fall:
(a) Es klingt für mich wie ein Unit-Test, und (b) Es spielt keine Rolle, ob es sich um einen Unit-Test handelt oder nicht, da es testet, was Sie testen müssen.
Wenn Sie der Meinung sind, dass die Prozeduren zu komplex sind, möchten Sie sie möglicherweise selbst in kleinere Teile aufteilen (in Datenbankprozeduren oder in Code), aber um dies zu tun, möchten Sie diese Tests natürlich zuerst durchführen!
quelle
Beim Testen von Einheiten geht es per Definition darum, eine "Codeeinheit" in ihrer laufenden Umgebung oder Plattform zu testen. Die Plattform, die Sie verwenden, ist eine Datenbank, Sie müssen sie also verwenden, sie ist nicht integrativ.
Eine bessere Frage ist, warum es dich interessiert. Ist es wichtig, dass Ihr Test in einem Unit-Test, einem Abnahmetest, einem Rauchtest oder einem Funktionstest durchgeführt wird, solange er automatisiert ist und einen Mehrwert bietet?
Bei meiner Arbeit nutzen wir derzeit das Unit-Testing-Framework, um Acceptance Test Driven Development (ATDD) durchzuführen. Einige Tests sind integrativ, andere nicht. Fast keiner von ihnen ist ein Unit-Test, aber es ist uns egal, solange:
Aktualisieren
Es ist alles eine Frage von Kosten und Nutzen. Je mehr bewegliche Teile Sie haben, desto höher ist das Risiko eines nicht deterministischen Tests. Klassische Unit-Tests haben die geringste Anzahl beweglicher Teile und daher die geringste Wahrscheinlichkeit, nicht deterministisch zu sein. Der Nachteil ist, dass Sie die Integrationspunkte (Code, Datenbank, fs, Netzwerk usw.) nicht testen. All dies ist nützlich, um in einem Test behandelt zu werden, solange das Risiko eines falschen Scheiterns oder Erfolgs gering genug ist.
Tests liefern Wert in dem, was sie tun, nicht was sie sind. Der Schlüssel ist, wie oft Sie falsche Fehler und Erfolge haben werden. Wenn ich jeden Monat 2 Stunden lang falsche Fehler habe, weil dies ein Wartungsfenster für das Netzwerk ist, ist der Wert der Tests offensichtlich. Wenn sie fehlschlagen, ist offensichtlich, dass mit der Netzwerkressource etwas nicht stimmt, nicht mit einem bestimmten Test. Und jetzt haben Sie mehr Testabdeckung, gerade weil Sie diese Integrationspunkte testen.
quelle
Ich denke, es kommt darauf an, woher die Daten kommen. Wenn Sie Ihre Testbedingungen im Testpräfix erstellen, ist es meiner Meinung nach sinnvoll, dies als Komponententest zu bezeichnen. Andernfalls stehen Sie in wählerischen Auseinandersetzungen darüber, was für einen Komponententest als "bereits vorhanden" gilt. So wie Ihre Datenbank-Unit-Tests auf der Existenz von Datenbanktabellen usw. beruhen, beruhen Unit-Tests außerhalb der Datenbank auf Klassendefinitionen und häufig auf Instanzen dieser Klassen. Das ist nicht schlecht, es ist realistisch.
quelle
Ich würde das als Integrationstest betrachten:
Tests, wie Sie sie beschreiben, sind jedoch von unschätzbarem Wert. Wir haben kürzlich damit begonnen, einfach solche Tests hinzuzufügen, um gespeicherte Prozeduren zu testen, die in bestimmten Umgebungen nicht manuell getestet werden können. Ich kenne keinen anderen Weg, um automatisierte Tests für gespeicherte Prozeduren durchzuführen.
Diese Tests sind also eine großartige Idee, aber nennen Sie sie Integrationstests. Verwenden Sie eine Testkategorie oder ein Namenssuffix, um sie von regulären Komponententests zu unterscheiden. Auf diese Weise können Sie Integrationstestfehler anders als Unit-Testfehler in Ihrer Build-Automatisierung kennzeichnen.
quelle
SqlCommand
Klasse funktioniert und dass der TCP-Transport funktioniert. Da habe ich mich noch nicht geirrt.Wo läuft der Test? In der Datenbank oder über einen codebasierten Testkabelbaum (JUnit)?
In der Datenbank handelt es sich dann wahrscheinlich um einen Komponententest (da dieser in sich geschlossen ist), ein JUnit-ähnliches Testkabel, dann wird eine Verbindung zu einer externen Datenbank hergestellt und als solcher ein Integrationstest durchgeführt.
Warum die Zitate? Integrationstests sind keine Bestie, die Sie niemals tun sollten.
Ich finde im Allgemeinen, dass die einzige vernünftige Einheit für eine gespeicherte Prozedur der aufrufende Code¹ und die Prozedur ist. Also teste ich den kompletten Satz in einer Reihe von Tests, die genau wie Unit-Tests aussehen.
Da können Sie die Tests aufteilen. Die Ausführung von Integrationstests dauert länger, erfordert zusätzliche Einrichtung und wahrscheinlich Zugriff auf eine Ressource, die von vielen Tests gemeinsam genutzt wird (z. B. die Datenbank).
1) Der aufrufende Code enthält bei Bedarf zusätzliche Komponententests.
quelle
Mikrotest ist ein nützlicher Begriff, der Ihnen helfen kann, die Debatte über die Terminologie zu umgehen und ob Ihr Test ein Komponententest ist oder nicht.
Eine gebräuchliche Definition von Unit-Test beinhaltet, dass das zu testende System eine kleine Funktionseinheit ist und Sie in der Lage sein müssen, alle Tests im Speicher ohne Hilfe von Dateisystemen, Netzwerken oder Datenbank-Engines auszuführen . Wenn Sie ein tatsächliches Datenbankmodul benötigen, um es auszuführen, handelt es sich nicht um einen Komponententest.
Diese Definition funktioniert zwar sehr gut für alle Anwendungsebenen, ist jedoch für die unterste Datenbankzugriffsebene nicht sehr hilfreich. Wir müssen erkennen, dass es etwas Besonderes ist. Wenn Ihre Tests nur kleine Einheiten der Speicher- / Abruf- / Aktualisierungs- / Löschfunktion testen, sind Ihre Tests eindeutig genauso wertvoll wie "strenge" Komponententests, die für die oberen Schichten Ihres Systems geschrieben wurden.
quelle
SELECT
, dann mache ich mir nicht die Mühe, ihn zu testen.