2010-02-11 11 views
7

Normalerweise sind Unit- (und andere) Tests bei der Dependency-Injection für das Erstellen/Mocking von Abhängigkeiten des zu testenden Systems verantwortlich.Abhängigkeiten in Tests einbetten

Manchmal hat der Test selbst jedoch Abhängigkeiten oder muss Abhängigkeiten in das SUT einfügen, die er selbst nicht erstellen kann. Wenn beispielsweise Klassen getestet werden, die mit einer Datenbank interagieren, muss der Test Verbindungszeichenfolgen und Katalognamen usw. kennen, die nicht fest codiert werden können, da sie nicht unbedingt für alle, die den Test ausführen, gleich sind.

Also, wie würden Sie empfehlen, dass ein Test diese Einstellungen herausfinden? Stellen einige Test-Frameworks im XUnit-Stil eine Möglichkeit dar, einem Test-Fixture Abhängigkeiten zu geben? Sollte die Testklasse statische Eigenschaften haben, füllen Sie sie aus, bevor Sie alle Tests ausführen? Sollte der Test DI-Praktiken ignorieren und einfach die Abhängigkeiten von einem globalen Ort bekommen? Andere Vorschläge?

Antwort

1

Wenn Sie die Einheit Test-Framework verwenden Integrationstests zu tun, Sie haben nicht wirklich eine DI oder ein Testproblem Einheit.

Was Sie haben, sind Integrationstests, die das leistungsstarke Unit-Test-Framework nutzen.

Da es sich um Integrationstests handelt, unterscheiden sie sich von Komponententests. Das "Stand-alone-ness" zählt nicht mehr wirklich.

Der beste Weg, Integrationstesteinstellungen zu erhalten, die von Benutzer zu Benutzer variieren, ist, sie auf die gleiche Weise zu erhalten, wie die endgültige Anwendung sie bekommen wird. Wenn Sie in Java arbeiten, verfügen Sie möglicherweise über eine Eigenschaftendatei. In Python haben wir spezielle Django-Einstellungsdateien für den Integrationstest.

3

Es gibt ein Prinzip für vollautomatische Tests: Sie sollten in der Lage sein, den gesamten Quellcode aus dem Quellcodeverwaltungs-Repository herunterzuziehen und die Tests einfach auszuführen.

Vorausgesetzt, dass die Umgebung (Maschine) die korrekte Installationsbasis hat (d. H. Compiler, Testframework, Datenbankmodul, etc.), sind die Tests für die Einrichtung ihres Fixtures verantwortlich, bevor sie die Testfälle ausführen.

Das bedeutet, dass für Datenbanken,

  • laufen seine Tests
  • löschen die Datenbank erneut nach dem letzten Testfall

    1. die betreffende Datenbank erstellen

    Wenn die Tests sollten Aus irgendeinem Grund können Sie das nicht tun. Das Einzige, was Sie wirklich tun können, ist eine Konfigurationsdatei in Ihrem Versionskontrollsystem, die maschinenspezifische Einträge für alle Maschinen in Ihrem Test enthält Umwelt; z.B. für die Maschine Tst1 die Verbindungszeichenfolge ist ein Wert, aber für Tst2 ist es eine andere.

    Dies kann sehr schnell hässlich werden, daher ist es viel einfacher, dass die Tests für Fixture Setup und Teardown verantwortlich sind, da sie einfach fest codierte Werte oder Werte vor Ort verwenden können.

    Das hat wirklich nichts mit DI zu tun ...

  • 1

    DI kämpft mit dependecies Komplexität, während die Komponententests die meiste Zeit einfach sehr sein muss. Ein typischer Komponententest würde einen isolierten Aspekt einer isolierten Klasse untersuchen. Anstatt aller Abhängigkeiten erstellen Sie Mocks und injizieren sie (normalerweise) über den Konstruktor CUT (Class Under Test). Sie benötigen in der Regel keine DI-Frameworks.

    Aber. Einige Tests auf höherer Ebene erfordern offensichtlich noch nicht gemachte Abhängigkeiten. Sie möchten beispielsweise Tests an einer großen Datenmenge durchführen und keine spezielle gefälschte Datenquelle erstellen, damit Sie sie in einer echten Datenbank aufbewahren (vielleicht führen Sie auch einige UI-Tests mit diesen Daten durch). In diesem Fall würde ich immer noch versuchen, die Dinge so einfach wie möglich zu halten, indem ich Tests in Klassen-Setup/Test-Setup-Methoden initialisiere.

    Sie sehen, Sie müssen hier vorsichtig sein.Jedes Mal, wenn Sie einen großer machen, komplizierter Test Sie:

    1. Erstellen Sie zusätzlichen komplizierten Code, dass die Unterstützung Anstrengungen erfordern wird.
    2. Erstellen Sie einen Test, der keinen eindeutigen Grund zum Fehlschlagen hat. Es könnte aufgrund einer schlechten Konnektivität an diesem Tag fehlschlagen. Sie können sich nicht auf sein Ergebnis verlassen.
    3. Erstellen Sie einen Test, der nicht einfach und schnell ausgeführt werden kann, z. B. beim Check-in. Weniger Leute werden es laufen lassen, mehr Bugs werden durchkommen.

    etc ...