Die einzige echte Logik liegt in der Abfragesyntax für die externe API. Ich möchte nicht testen, ob die API abgefragt wird. Ich möchte testen, ob die API so abgefragt wird, dass die korrekten Daten zurückgegeben werden. Zum Beispiel ein Pseudocode:
function retrieve_related_data(id)
{
query = "[potentially long, syntactically complex query that
uses param id to get some data]";
results = api_wrapper.query(query);
return results;
}
Ein konkreteres Beispiel mit einer erfundenen API:
function retrieveLifeSupportingObjectsWithinRegion(id)
{
query = "
within region(" + id + ") as r
find objects matching hydration>0 and temp_range has 75
send name, id, relative(position, r)
";
results = astronomicalObjectApiWrapper.query(query);
return results;
}
Die Abfrage hat eine an die API angepasste Syntax und ist komplex. Es gibt mehrere Möglichkeiten, die gleichen oder ähnliche Ergebnisse zu erzielen. Der Zweck der Funktion besteht nicht darin, Daten zu identifizieren, id
sondern eine Teilmenge anderer Daten zu finden, die auf einer unscharfen Beziehung zu den durch identifizierten Daten basiert id
, die auch einige andere Anforderungen erfüllt. Die anderen Anforderungen sind immer gleich id
, können sich jedoch im Laufe der Zeit ändern, wenn das System geändert wird. Wenn die Beispiel-API beispielsweise die Unterstützung für Schwerkraftinformationen hinzufügt, möchten wir die Abfrage möglicherweise ändern, um auch die Schwerkraft zu verwenden, um die Ergebnisse zu verfeinern. Oder wir haben eine effizientere Methode zur Überprüfung des Temperaturbereichs entwickelt, die die Ergebnisse jedoch nicht verändert.
Was ich testen möchte, ist, dass für eine bestimmte Eingabe id
der richtige Datensatz zurückgegeben wird. Ich möchte dies testen, damit, wenn jemand die Abfrage durcheinander id
bringt und nicht mehr die richtigen Daten zurückgibt , dies fehlschlägt. Ich möchte jedoch auch, dass die Abfrage geändert werden kann, um sie zu verfeinern, ohne dass Änderungen erforderlich sind der Test.
Optionen, über die ich nachgedacht habe:
Ich könnte die API stummschalten, aber das wäre entweder zu einfach (überprüfen Sie, ob die
id
in der Abfrage vorhanden ist, und geben Sie dann eine erwartete Menge von Daten zurück, wenn dies der Fall ist, oder eine unerwartete Menge, wenn dies nicht der Fall ist), zu spröde (überprüfen Sie, ob die Abfragezeichenfolge vorhanden ist genau das, was in der Funktion enthalten ist) oder zu komplex (stellen Sie sicher, dass die verwendete Abfrage syntaktisch korrekt ist und die richtigen Daten zurückgegeben werden).Ich könnte die Abfrage an die echte API senden, aber die erwarteten Ergebnisse könnten sich im Laufe der Zeit ändern, da sich die Daten im externen System außerhalb der Kontrolle des Testsystems ändern.
Ich könnte versuchen, eine Testinstallation der echten API einzurichten, um die darin enthaltenen Daten zu kontrollieren, aber das ist ein großer Aufwand.
Ich neige zu # 2 und mache dies eher zu einem Integrationstest, der nicht oft ausgeführt wird und sehe, wie oft Änderungen an den Daten des externen Systems dazu führen, dass der Test abgebrochen wird. Ich denke, das wäre im Moment am einfachsten, aber ich frage mich, ob es Alternativen gibt, über die ich nicht nachdenke, oder bessere Möglichkeiten, um dieses Problem anzugehen. Jeder Rat wäre dankbar.
quelle
Antworten:
Es mag so aussehen, als würden wir unsere Funktion testen, wenn wir die externe API-Antwort validieren, aber das wäre nicht ganz richtig. Irgendwie würden wir die externe API und die Umgebung testen, in der die API ausgeführt wird.
Unsere Tests sollten angesprochen werden, um das erwartete Verhalten des von uns geschriebenen Codes zu gewährleisten, nicht das von Dritten.
Bis zu einem gewissen Grad müssen wir uns auf die ordnungsgemäße Funktion der APIs und Bibliotheken verlassen, auf die wir uns verlassen. Zum Beispiel testen wir normalerweise nicht die Framework-Komponenten, die wir implementieren.
Warum sage ich das?
Was würde hier getestet werden? Wie Sie sagten, sind die Daten und ihre Richtigkeit nicht unter unserer Kontrolle, daher würden wir den Erfolg der Testphase auf einen externen Agenten beschränken, auf den wir keine Kontrolle haben. Diese Tests sind ein Kandidat, um nicht deterministisch zu werden, und definitiv. Wir wollen diese Art von Tests nicht in unserer Baupipeline haben .
Ein anderes Anliegen ist es, den Vertrag zu validieren. Ich würde einen Vertragstest 1 als sehr nützlich erachten, um sicherzustellen, dass die Integration vor jeder Veröffentlichung oder Bereitstellung noch wie erwartet funktioniert.
Was ist, wenn die Abfrage in Ordnung ist, die Daten jedoch aufgrund von Fehlern in der API falsch sind? Nicht nur die Daten sind außerhalb unserer Kontrolle. Die Logik ist auch.
Hier kann die Implementierung von Funktionstests oder End-to-End-Tests hilfreich sein. Sie können diesen Test verwenden, um bestimmte Ausführungspfade zu validieren. Wenn die APIs falsche Daten zurückgeben, führt dies wahrscheinlich zu unerwarteten Verhaltensweisen und Ausgaben. Andererseits würde ich erwarten, dass die API Fehler auslöst, wenn meine Abfragen schlecht formatiert sind.
Ich schlage vor, ein Tool für diesen Zweck zu implementieren. Es könnte so einfach sein wie:
Oder etwas Anspruchsvolleres. Zum Beispiel ein eigenständiger Client.
In jedem Fall ist die Funktion unter der Frage durchaus zwei Arten von Tests wert:
Gerätetest. Wie Sie sagten, müssen Sie die externe API blockieren, aber das ist der ganze Zweck von Komponententests. Testen Sie unseren Code, um die Abhängigkeiten zu isolieren.
Integrationstest. Vergewissern Sie sich, dass der Code nicht nur die richtige Anforderung sendet, sondern auch den richtigen Umgang mit Antwortinhalten, Fehlern, Weiterleitungen usw. hat. Führen Sie in all diesen Fällen Tests durch, testen Sie jedoch keine Daten .
Randnotiz: Ihre Frage ähnelt -wie testen Sie die SQL-Anweisungen der App-?
Verwandte Fragen :
1: Möglicherweise interessieren Sie sich für die Antwort von @ DocBrown zu diesem Thema
quelle
Ich habe Unit Checks gesehen, bei denen überprüft wurde, ob die generierte Abfragezeichenfolge einem erwarteten Wert entspricht.
Jedoch. Dies war meiner Meinung nach nur bedingt zu gebrauchen. Die Abfragesyntax war kompliziert, möglicherweise fehlerhaft. Daher gab es unzählige Überprüfungsmöglichkeiten, und auch wenn die Zeichenfolge "korrekt" generiert wurde, konnten unerwartete Ergebnisse in der Live-Umgebung zurückgegeben werden.
Ich denke, Sie haben Recht, Ihre Option 2 zu wählen. Führen Sie Integrationstests für die Live-Instanz durch.
Solange sie nicht destruktiv sind, sind dies die ersten Tests, die Sie schreiben sollten, da sie die Fehlerursache erkennen, aber nicht identifizieren.
Die Option 3 "Bereitstellen einer Testinstanz mit Dummy-Daten" ist überlegen. Dies wirkt sich jedoch nicht auf das Schreiben von Tests aus, da Sie dieselben Tests auf den Testserver verweisen können, wenn die Bereitstellung eines Tests zeitaufwendig wird.
quelle
Dies hängt von der API ab. Wenn möglich, wählen Sie Option 3 (private Testinstanz).
Das Stoppen der API (Option 1) ist aus den von Ihnen genannten Gründen die schlechteste Option, und diese Route wird wahrscheinlich mehr schaden als nützen (viel verschwendete Zeit).
Die Verwendung der echten API (Option 2) macht die Tests unzuverlässig und unzuverlässig, und nach ein paar falschen Positiven werden die Benutzer sie einfach nicht mehr verwenden. Es können sich nicht nur die Daten ändern, sondern auch der Service kann ausfallen. Meiner Meinung nach bedeutet dies, keine Tests für die Abfragen zu haben und sich auf Integrations- / Systemtests zu stützen, um die Probleme zu finden. Wenn sich die API-Daten jedoch selten ändern und die API selbst fast immer aktiv ist, ist dies möglicherweise eine praktikable Option. Die meisten APIs passen nicht zu dieser Beschreibung.
Letztendlich kommt es darauf an, wie wichtig und komplex diese Abfragen sind: Wenn es mehr als eine Handvoll Abfragen gibt und einige von ihnen so komplex sind, dass Sie sie testen müssen, würde ich den Aufwand investieren, eine private Instanz zum Testen einzurichten . Das zahlt sich aus wie bei anderen Unit-Tests.
quelle