Beim Schreiben von Komponententests werden häufig Fixtures verwendet: wenig testbare Daten, daher können wir sagen: 1. Alle Kunden sollten Willy Wonka enthalten. 2. Löschen Sie Client 3, und erhalten Sie jetzt Clients, die Willy Wonka nicht mehr enthalten sollten.
Das ist gut für Unit-Tests. Verwenden Sie Setup / Teardown, um die Fixtures neu zu laden oder die Transaktion zurückzusetzen. Das Testen, Erstellen, Aktualisieren und Löschen erfolgt also innerhalb einer Transaktion . Die neuen temporären Daten dauern nur für die Dauer dieses Tests und werden dann zurückgesetzt.
Aber was ist, wenn wir den REST-Server vom REST-Client getrennt haben?
Wir möchten sicherstellen, dass unser REST-Client nicht nur richtig liest, sondern auch richtig erstellt, aktualisiert und löscht.
Ich konnte keine Beispiele oder Vorschläge finden, wie dies gegen einen Remote-Test-REST-Server durchgeführt werden kann.
Angenommen, ich habe einen Test-REST-Server, der nur Fixtures bedient. Die ganze Staatenlosigkeit von HTTP bedeutet, dass es schwierig ist, eine Nachricht vom Typ "BEGIN TRANSACTION" und "ROLLBACK TRANSACTION" oder "RELOAD FIXTURES" zu senden, oder?
Ich kann nicht der Erste sein, der dies tun möchte, daher habe ich das Gefühl, dass ich eine andere Art brauche, darüber nachzudenken.
Irgendwelche Vorschläge?
quelle
Antworten:
Softwaresysteme haben idealerweise genau definierte Systemgrenzen und Schnittstellen zwischen ihnen. REST-Services sind hierfür gute Beispiele.
Zu diesem Zweck würde ich empfehlen , gegen das , was Sie zu tun versuchen.
Speziell:
Was ich stattdessen vorschlagen würde, ist:
Erstellen Sie Tests für Ihren REST-Client, um sicherzustellen, dass er sich bei bestimmten Ein- und Ausgaben korrekt verhält. Berücksichtigen Sie gute (erwartete) und schlechte (unerwartete) Werte.
Erstellen Sie Tests für Ihren REST-Service (wenn Sie ihn steuern), um sich gemäß der beabsichtigten Funktion zu verhalten
Halten Sie Tests in der Nähe ihrer Problemdomäne, damit sie das Design und die Entwicklung dessen unterstützen können, was in diesem Kontext wichtig ist
quelle
Zwei Winkel, die hier zu beachten sind:
quelle
Ich denke, das Fälschen der REST-Serverantworten ist der beste Weg, um den Client zu testen.
Für Ruby gibt es das Juwel FakeWeb, mit dem Sie falsche Antworten ausgeben können - https://github.com/chrisk/fakeweb .
In JavaScript können Sie auch so etwas wie Sinon.JS verwenden, wodurch Sie einen gefälschten Server erhalten - http://sinonjs.org/docs/#fakeServer .
quelle
Wie andere bereits gesagt haben, müssen Sie beim Testen eines Clients nicht so weit gehen, auf dem Server zu erstellen, zu löschen usw. In den meisten Fällen müssen Sie sich überhaupt nicht über einen Server lustig machen. Sie müssen wirklich nur sicherstellen, dass Sie die richtigen Anforderungen stellen und die Antworten korrekt verarbeiten. Unabhängig davon, ob sie in Ruby, Python, PHP oder irgendetwas anderem geschrieben sind, wird Ihr Client wahrscheinlich irgendwann eine Methode aus einer HTTP-Bibliothek verwenden, um sie zu erstellen eine Anfrage und es reicht aus, diese Methode zu verspotten, zu überprüfen, wie sie aufgerufen wird, und ein Testergebnis zurückzugeben.
Nehmen Sie einen hypothetischen Python-Client, der
urllib2
zum Erstellen von Anforderungen verwendet wird. Sie haben wahrscheinlich eine Methode im Client, nennen wir sieget()
, die einen Aufruf enthälturllib2.Request()
. Sie müssen sich nur wirklich über den Anruf Ihrer eigenen Klasse lustig machenget()
.In diesem sehr vereinfachten Beispiel wird die Mock-Bibliothek von Python verwendet, um eine hypothetische
your.Client
Klasse mit einerget_object()
Methode zu testen , die die richtige URL generiert, um etwas von einer API abzurufen. Um die Anfrage zu stellen, ruft der Client seineget()
Methode mit dieser URL auf. Hier wird diese Methode verspottet (your.Client.get
wird "gepatcht", so dass sie unter der Kontrolle von stehtyour_mock
), und der Test prüft, ob der richtige Endpunkt angefordert wurde.Die verspottete Methode gibt die konfigurierte JSON-Antwort (
your_mock.return_value
) zurück, die der Client verarbeiten muss, und Sie würden weitere Aussagen treffen, um zu testen, ob die erwarteten Daten auf die erwartete Weise verarbeitet wurden.quelle
Was Sie beschreiben, ist ein Integrationstestszenario. Diese sind normalerweise etwas umständlich einzurichten und abzureißen. Es macht sie langsam zu laufen und ziemlich oft spröde.
Der Ansatz mit Fixtures ist genauso umständlich und ungeschickt, aber es ist die Standardmethode, mit der einige Frameworks vorgehen, z. B. Rails, und er wird bereits unterstützt. Sie benötigen den abstrakten Testfall oder ähnliches, um die Datenbank mit Fixtures vorzubereiten. (Vorsicht vor ungewöhnlichen Benennungen von Testkategorien in Rails, die Unit-Tests mit DB-Fixtures sind streng genommen auch Integrationstests.)
Ich würde in Ihrem Szenario akzeptieren, dass Sie eine testspezifische Kontrolle über den API-Anwendungsstatus oder die Datenbank haben. Sie können entweder zusätzliche Endpunkte für das Einrichten und Herunterfahren haben, die nur in der Testumgebung vorhanden sind. Alternativ können Sie mit der Datenbank (oder was auch immer Sie verwenden) hinter der Rückseite Ihrer Anwendung / API sprechen.
Wenn Sie der Meinung sind, dass dies zu viel (im Sinne eines unangemessenen) Aufwands ist, sollten Sie berücksichtigen, dass der Ansatz mit Fixtures für Datenbanken genau dies bewirkt: Verwenden zusätzlicher, testspezifischer Mittel zum Manipulieren des Datenbank- oder Anwendungsstatus.
Ich glaube nicht, dass diese Diskussion mit der Staatenlosigkeit von HTTP zu tun hat. HTTP ist zustandslos, die Anwendung jedoch in den meisten Fällen definitiv nicht. Es klingt ein bisschen so, als ob Sie nach REST-Strenge suchen. Genauso gut können alle Ressourcen vollständig erstellt, gelesen und gelöscht werden. In diesem Fall können Sie alle Einstellungen und Abbrüche über reguläre API-Mittel vornehmen. In der Praxis wird dies jedoch häufig nicht durchgeführt, da Sie bestimmte Vorgänge aus einem Geschäftsverständnis Ihrer Anwendung nicht einbeziehen möchten, zumindest nicht außerhalb der Testumgebung.
quelle
Affen Patch
Bei meiner Arbeit machen wir ATDD, indem wir ein bestehendes xUnit-Framework verwenden und Netzwerkaufrufe zwischen Client und Server patchen. Im selben Prozessbereich laden wir den Client und patchen den Netzwerkaufruf am Anfang des REST-Server-Stack-Codes. Alle Anrufe werden dann vom Client wie gewohnt ausgegeben, und der Servercode erhält die Anforderungen genau so, wie sie normalerweise angezeigt werden.
Leistungen
Kompromisse
quelle