Es scheint ein Henne-Ei-Problem zu sein.
Sie können eine Schreibfunktion in einen Datenspeicher schreiben lassen, wissen jedoch nie, dass Sie sie ohne eine getestete Lesefunktion ordnungsgemäß gespeichert haben.
Sie können eine Lesefunktion aus einem Datenspeicher lesen lassen, aber wie können Sie Inhalte in diesen Datenspeicher einfügen, um sie ohne eine getestete Schreibfunktion zu lesen?
BEARBEITEN:
Ich verbinde mich mit einer SQL-Datenbank und mache Transaktionen mit dieser, um Objekte zur Verwendung zu speichern und zu laden. Es macht keinen Sinn, die von der Datenbank bereitgestellten Zugriffsfunktionen zu testen, aber ich verpacke solche DB-Funktionen, um die Objekte zu serialisieren / deserialisieren. Ich möchte sichergehen, dass ich die richtigen Dinge zur und von der DB richtig schreibe und lese.
Es ist nicht wie Hinzufügen / Löschen, wie @snowman erwähnt. Ich möchte wissen, dass der Inhalt, den ich geschrieben habe, korrekt ist, aber das erfordert eine gut getestete Lesefunktion. Wenn ich lese, möchte ich sichergehen, dass mein Lesen ein Objekt korrekt erstellt hat, das dem entspricht, was geschrieben wurde. Dies erfordert jedoch eine gut getestete Schreibfunktion.
Antworten:
Beginnen Sie mit der Lesefunktion.
Im Testaufbau : Erstellen Sie die Datenbank und fügen Sie Testdaten hinzu. entweder über Migrationsskripte oder aus einem Backup. Da dies nicht Ihr Code ist, ist kein Test in TDD erforderlich
Im Test : Instanziieren Sie Ihr Repository, zeigen Sie auf Ihre Testdatenbank und rufen Sie die Read-Methode auf. Überprüfen Sie, ob die Testdaten zurückgegeben werden.
Nachdem Sie eine vollständig getestete Lesefunktion haben, können Sie zur Schreibfunktion wechseln, die das vorhandene Lesen verwenden kann, um die eigenen Ergebnisse zu überprüfen
quelle
Ich schreibe oft nur, gefolgt von einem Lesen. zB (Pseudocode)
Später hinzugefügt
Zusätzlich dazu, dass diese Lösung "prgamatisch" und "gut genug" ist, könnte man argumentieren, dass die anderen Lösungen das Falsche testen . Zu testen, ob die Zeichenfolgen oder SQL-Anweisungen übereinstimmen, ist keine schreckliche Idee. Ich habe es selbst gemacht, aber es testet einen Nebeneffekt und ist fragil. Was passiert, wenn Sie die Groß- und Kleinschreibung ändern, ein Feld hinzufügen oder eine Versionsnummer in Ihren Daten aktualisieren? Was passiert, wenn Ihr SQL-Treiber die Reihenfolge der Aufrufe aus Effizienzgründen ändert oder Ihr aktualisierter XML-Serializer zusätzlichen Speicherplatz hinzufügt oder eine Schemaversion ändert?
Wenn Sie sich nun strikt an eine offizielle Spezifikation halten müssen, stimme ich zu, dass die Überprüfung der Details angemessen ist.
quelle
Tu es nicht. Testen Sie keine E / A. Das ist Zeitverschwendung.
Unit-Test-Logik. Wenn Sie eine Menge Logik im E / A-Code testen möchten, sollten Sie Ihren Code umgestalten, um die Logik der E / A-Ausführung und der E / A-Ausführung von der eigentlichen E / A-Ausführung zu trennen (was fast unmöglich zu testen ist).
Wenn Sie einen HTTP-Server testen möchten, sollten Sie zwei Arten von Tests durchführen: Integrationstests und Komponententests. Die Komponententests sollten überhaupt nicht mit E / A interagieren. Das ist langsam und führt zu vielen Fehlerbedingungen, die nichts mit der Richtigkeit Ihres Codes zu tun haben. Unit-Tests sollten nicht dem Status Ihres Netzwerks unterliegen!
Ihr Code sollte sich trennen:
Die ersten beiden beinhalten Logik und Entscheidungen und erfordern Unit-Tests. Letzteres beinhaltet nicht viele oder gar keine Entscheidungen und kann mithilfe von Integrationstests wunderbar getestet werden.
Dies ist im Allgemeinen nur gutes Design, aber einer der Gründe dafür ist, dass es einfacher zu testen ist.
Hier sind einige Beispiele:
quelle
Ich weiß nicht, ob dies eine Standardpraxis ist oder nicht, aber es funktioniert gut für mich.
In meinem nicht-Datenbank Lese - Schreib - Methode Implementierungen verwende ich meine eigenen typspezifischen
toString()
undfromString()
Methoden als Implementierungsdetails.Diese können leicht isoliert getestet werden:
Für die tatsächlichen Lese-Schreib-Methoden habe ich einen Integrationstest, der in einem Test physisch liest und schreibt
Übrigens: Stimmt etwas nicht, wenn ein Test zusammen liest / schreibt?
quelle
Bekannte Daten müssen auf bekannte Weise formatiert werden. Der einfachste Weg, dies zu implementieren, besteht darin, eine konstante Zeichenfolge zu verwenden und das Ergebnis zu vergleichen, wie in @ k3b beschrieben.
Sie sind jedoch nicht auf Konstanten beschränkt. Es kann eine Reihe von Eigenschaften der geschriebenen Daten geben, die Sie mit einem anderen Parser extrahieren können, z. B. reguläre Ausdrücke oder sogar Ad-hoc-Tests, die nach Merkmalen der Daten suchen.
Zum Lesen oder Schreiben der Daten kann es nützlich sein, über ein In-Memory-Dateisystem zu verfügen, mit dem Sie Ihre Tests ausführen können, ohne dass andere Teile des Systems eingreifen können. Wenn Sie keinen Zugriff auf ein gutes In-Memory-Dateisystem haben, verwenden Sie einen temporären Verzeichnisbaum.
quelle
Verwenden Sie Abhängigkeitsinjektion und Verspottung.
Sie möchten Ihren SQL-Treiber nicht testen und Sie möchten nicht testen, ob Ihre SQL-Datenbank online und ordnungsgemäß eingerichtet ist. Das wäre Teil eines Integrations- oder Systemtests. Sie möchten testen, ob Ihr Code die SQL-Anweisungen sendet, die er senden soll, und ob er die Antworten so interpretiert, wie er soll.
Wenn Sie also eine Methode / Klasse haben, die etwas mit einer Datenbank tun soll, muss diese Datenbankverbindung nicht von selbst hergestellt werden. Ändern Sie es so, dass das Objekt, das die Datenbankverbindung darstellt, an es übergeben wird.
Übergeben Sie in Ihrem Produktionscode das eigentliche Datenbankobjekt.
Übergeben Sie in Ihren Komponententests ein Scheinobjekt, das sich so verhält, als würde eine tatsächliche Datenbank keinen Datenbankserver kontaktieren. Lassen Sie es einfach überprüfen, ob es die SQL-Anweisungen empfängt, die es empfangen soll, und antwortet dann mit fest codierten Antworten.
Auf diese Weise können Sie Ihre Datenbankabstraktionsschicht testen, ohne eine tatsächliche Datenbank zu benötigen.
quelle
Wenn Sie einen objektrelationalen Mapper verwenden, gibt es normalerweise eine zugeordnete Bibliothek, mit der Sie testen können, ob Ihre Zuordnungen ordnungsgemäß funktionieren, indem Sie ein Aggregat erstellen, es beibehalten und aus einer neuen Sitzung neu laden und anschließend den Status überprüfen das ursprüngliche Objekt.
NHibernate bietet Persistenzspezifikationstests an . Es kann so konfiguriert werden, dass es für schnelle Komponententests gegen einen In-Memory-Speicher arbeitet.
Wenn Sie der einfachsten Version der Muster für Repository und Arbeitseinheit folgen und alle Ihre Zuordnungen testen, können Sie sich darauf verlassen, dass die Dinge ziemlich gut funktionieren.
quelle