6 Stimmen

Testen von Smart Wrappern für Bibliotheken von Drittanbietern

Angenommen, Sie müssen eine unnötig komplizierte, schwer nachzuahmende (vielleicht hat sie konkrete Klassen ohne virtuelle Schnittstelle) und unzuverlässige Bibliothek eines Drittanbieters verwenden, die mit einer externen Ressource wie einem Socket oder einer Datenbank verbunden ist. Sie beschließen, "Wrapper"-Schnittstellen/Klassen zu erstellen, um die Verwendung dieser Bibliothek erheblich zu vereinfachen und es den Entwicklern, die den Wrapper verwenden, zu ermöglichen, weiterhin testbaren Code zu schreiben. Die Schnittstelle des Wrappers sieht nicht wie die Originalschnittstelle aus.

Ich habe ein paar Fragen dazu, wie ich diesen Wrapper testen kann.

  1. Sollte der Wrapper ohne die externe Ressource getestet werden, indem eine Methode-für-Methode-Schicht über der schlechten Bibliothek entwickelt wird, die nachgeahmt werden kann?

  2. Wenn Sie Ihre Wrapper-Klassen mit der Bibliothek eines Drittanbieters (unter Verwendung der externen Ressourcen) testen, handelt es sich dann um einen Unit-Test oder einen Integrationstest? Wenn die externe Ressource während des automatisierten Tests in den Speicher eingebettet werden kann, handelt es sich dann immer noch um einen Integrationstest?

  3. Wann hören wir auf zu spotten und zu schimpfen und sagen, dass wir eine Einheit haben. Laut Wikipedia ist eine Unit der kleinste testbare Teil einer Anwendung", aber ich finde es schwierig, dies zu messen. Wenn Geschwindigkeit ein Faktor bei der Entscheidung ist, ob wir eine Unit testen oder nicht, wie entscheiden Sie, wie langsam ist zu langsam für den Test, um als Unit-Test bezeichnet zu werden?

9voto

Ladislav Mrnka Punkte 355028

TDD besagt nicht, dass alles einheitlich getestet werden muss. TDD sagt, dass man zuerst einen Test schreiben sollte, aber es muss kein Unit-Test sein.

  1. Beginnen Sie mit dem Integrationstest - er testet Ihre Logik in Abhängigkeit vom Wrapper, der mit einer echten Komponente kommuniziert. Keine Mocks hier. Es ist ein Integrationstest, weil er mehrere Schichten Ihrer Anwendung testet und die reale Komponente noch Sockets oder Datenbankzugriff verwendet.
  2. Der Integrationstest wird fehlschlagen, weil Sie Ihre Logik nicht haben
  3. Schreiben von Unit-Tests mit Mocked Wrapper zum Testen der Logik
  4. Der Unit-Test wird fehlschlagen, weil Sie Ihre Logik nicht haben
  5. Schreiben Sie die Logik, um den Einheitstest zu erfüllen (4.)
  6. Wiederholen Sie 3.-5., um die gesamte Logik zu erhalten, die erforderlich ist, um den Integrationstest zu erfüllen (1.)
  7. Wiederholen Sie den gesamten Prozess mit dem nächsten Integrationstest

Es besteht keine Notwendigkeit, Unit-Tests für den Wrapper zu schreiben. Die Hauptfunktion des Wrappers besteht darin, die Komponente zu umhüllen. Wenn Sie einen Unit-Test für den Wrapper schreiben, werden Sie testen, dass er eine Methode der Komponente aufruft, aber in diesem Fall stehen Sie wieder am Anfang - wie kann man die Komponente mocken? Wenn Sie einen Integrationstest nur für den Wrapper schreiben, der die Komponente aufruft, testen Sie die Komponente erneut (OK, das ist manchmal praktisch, aber im normalen Szenario tun Sie das nicht).

Ich empfehle die Lektüre Wachsende objektorientierte Software mit Hilfe von Tests von Steve Freeman und Nat Pryce.

7voto

Mark Seemann Punkte 216836

Ich denke, diese Frage dreht sich um diese Aussage:

Die Schnittstelle des Wrappers sieht nicht wie die Originalschnittstelle aus

Dies deutet wahrscheinlich darauf hin, dass bei der Übersetzung zwischen dem Wrapper und der Originalschnittstelle eine beträchtliche Menge an Logik involviert ist. Das klingt sehr nach einem Anti-Korruptions-Ebene und wenn diese Logik komplex ist, sollte sie getestet werden.

Am besten ist es immer noch, eine 1:1-Schnittstelle aus der ursprünglichen API zu extrahieren. Dies ist jedoch nicht die Schnittstelle, die Sie dem Rest der Anwendung zur Verfügung stellen. Die Schnittstelle, die Sie dem Rest der Anwendung zur Verfügung stellen, kann eine Fassade über die extrahierte Schnittstelle. In gewissem Sinne könnte man sagen, dass die extrahierte Schnittstelle ein Implementierungsdetail der Anti-Korruptionsschicht ist und nicht etwas, das für den Rest der Anwendung offengelegt wird.

Auf diese Weise können Sie die Übersetzung zwischen der Fassadenschnittstelle und der extrahierten Schnittstelle testen, ohne die ursprüngliche, schwer zu testende Komponente aus dem Test herauszunehmen.

Was bleibt, ist die Übersetzung zwischen der extrahierten Schnittstelle und der ursprünglichen Komponente. Wenn diese Schnittstelle jedoch als 1:1-Abbildung der ursprünglichen Komponente extrahiert wurde, sollte die Implementierung aus reiner Delegation bestehen. Mit anderen Worten, die Implementierung hätte eine zyklomatische Komplexität von 1 und wäre somit eine Bescheidenes Objekt die nicht einheitlich getestet werden müssen.

Sie möchten vielleicht noch einige Integrations- oder Systemtests für das fertige System durchführen, aber diese können die Rolle von Smoke-Tests übernehmen, da Sie bereits eine ausreichende Abdeckung durch die Unit-Tests haben sollten.

2voto

Morten Punkte 3674

Ad 1) Nein ist die kurze Antwort. Ein Wrapper sollte nichts anderes tun als verpacken. Daher sind Integrationstests das einzige, was Sinn macht.

Ad 2) Ja, das stimmt.

Ad 3) Sie hören auf, wenn Ihr Zielobjekt nur eine Sache tut, und lassen externe Objekte - injiziert und verspottet - alles andere tun (SRP)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X