BDD - Entwicklung durch Verhalten. BDD for Microservices ist eine Zusammenarbeit von Kunden, Entwicklern und Testern. BDD ist eine Entwicklung, die sowohl technische Interessen als auch Geschäftsanforderungen berücksichtigt. Dieser Ansatz wird normalerweise zur Beschreibung von Anwendungsschnittstellen verwendet. Da Microservices die Details der Implementierung des Systems sind, eignet sich BDD auch zur Entwicklung von Microservices. Wie es geht - in der Übersetzung von Ken Pugh.
Über den Autor: Ken Pugh lehrt Unternehmen, Flexibilität zu entwickeln, und erstellt mithilfe von Acceptance Test-Driven Development, BDD und DevOps-Beschleunigung hochwertige Systeme. Ken hat mehrere Bücher über Softwareentwicklung geschrieben und war Prefactoring-Gewinner des Jolt Award 2006, einer der Schöpfer des SAFe Agile Software Engineering-Kurses.
Das Verhalten in BDD wird häufig durch das Given / When / Then- Konstrukt ausgedrückt . Wir erhalten einen bestimmten Status, wenn eine Aktion oder ein Ereignis eintritt, dann ändert sich der Status und / oder es werden Informationen zurückgegeben.
Beispielsweise beschreibt zustandslose Logik wie Geschäftsregeln und Berechnungen einfach die Umwandlung von Eingabe in Ausgabe.
Interface Oriented Design verwendet das Prinzip
„Design für Schnittstellen, nicht für Implementierungen“. Verbraucher des Dienstes verwenden die von ihm bereitgestellte Schnittstelle, nicht die Interna. Dies bedeutet, dass eine solche Schnittstelle klar durchdacht sein sollte, einschließlich des Fehlerverhaltens. Zur Definition von Begriffen in der Beschreibung der Schnittstelle oder ihres Verhaltens kann DDD - Domain Driven Design verwendet werden.
Microservices können synchron sein, wenn der Verbraucher
einen anderen Dienst direkt aufruft und das Ergebnis erwartet, oder asynchron, wenn der
Dienst eine Nachricht beantwortet, die der Client in die Warteschlange gestellt hat .
Betrachten Sie ein Beispiel für einen synchronen Dienst.
Synchroner Dienst
Stellen Sie sich einen Service vor, der einen Rabatt auf einen Kundenauftrag berechnet. Der gesamte Prozess besteht aus einer Reihe verwandter Vorgänge.

Das Verhalten dieses Dienstes kann wie folgt beschrieben werden:
Get discount for a customer Given these inputs Customer category Order Amount Then service outputs Discount Amount
Der Dienst kann den Rabatt mithilfe von Algorithmen im Code berechnen, die auf der lokalen Datendatenbank basieren, oder indem er andere Dienste kontaktiert.
Es kann JSON oder XML als Nachrichtenformat verwenden. Die Beschreibung des Dienstes ohne Angabe von Implementierungsdetails hilft jedoch dabei, die Semantik von Operationen von der Syntax zu trennen.
Wie ist das Verhalten?
Mit BDD können Sie mit dem Entwerfen von Beispieldaten beginnen, um eine Vorstellung vom gewünschten Verhalten zu erhalten. Service-, Client- und Testerentwickler können dieses Beispiel erstellen. Die ersten beiden Spalten sind die Eingabe für den Dienst, und die Spalte rechts ist die Ausgabe.
Das Beispiel zeigt Domänenbegriffe, die möglicherweise weiter verfeinert werden müssen. Beschreiben Sie beispielsweise gültige Werte.

Es versteht sich, dass der Dienst das richtige Ergebnis zurückgibt, wenn die Eingabedaten in den Bereich akzeptabler Werte fallen.
Die Verhaltensbeschreibung, insbesondere für Microservices, enthält häufig Antworten bei Fehlern und Ausfällen. Eine Beschreibung möglicher Fehler hilft dem Verbraucher zu verstehen, was in solchen Fällen zu tun ist. Kunden des Dienstes können spezielle Bibliotheken verwenden, z. B. Hystrix von Netflix, um einige dieser Fehler zu beheben.
Einige mögliche Fehler unseres Service:
Fehler können als numerische oder Zeichenkonstanten im Kommunikationsprotokoll ausgedrückt werden.
Die Verwendung aussagekräftiger Namen in BDD hilft dabei, die Semantik eines Fehlers und nicht dessen Syntax hervorzuheben.
Wenn der als Kategorie übergebene Wert nicht in der Liste der zulässigen Werte enthalten ist, gibt der Dienst eine Fehleranzeige zurück: "Ungültiger Wert der Abfrageparameter." Dies kann beispielsweise durch Rückgabe des HTTP-Codes 400 und der entsprechenden Textbeschreibung dargestellt werden.
Alternativ können Sie den Rabattwert bestimmen, der zurückgegeben wird, z. B. 0, wenn einer der Parameter falsch ist. In diesem Fall sollte der Dienst für die Aufzeichnung dieses Problems verantwortlich sein, damit seine Folgen analysiert werden können.
Service-BDD-Tests können einen Kontext für ihre Komponententests bilden. Im Entwurfsprozess liegt die
Verantwortung für das Bestehen von BDD-Tests bei Klassen und Methoden . Unit-Tests bestimmen diese Verantwortlichkeiten.
Stubs
Beim Testen eines Dienstes sind häufig Stubs abhängiger Dienste erforderlich, die er aufruft. Sie werden insbesondere für langsame, teure oder zufällige Dienste benötigt. Wenn sich das Verhalten des Rabattdienstes nie geändert hat, können Sie beim Testen des Clients die Kampfinstanz verwenden.
Änderungen sind oft unvermeidlich, daher werden normalerweise Stubs benötigt.

Ein Stub kann immer dieselben Werte zurückgeben, zum Beispiel:
Kundentests können sich auf diese Werte stützen. In diesem Beispiel kann ein konstantes Verhalten ausreichend sein. Für andere Tests ist eine benutzerdefinierte Stub-Antwort vorzuziehen.
Alternativ kann der Rabatt-Service-Stub unabhängig von der Eingabe einfach den gleichen Betrag zurückgeben.
Wie kann dieser Stub in ein breiteres Szenario passen? Berücksichtigen Sie das Verhalten des Systems für eine Bestellung, die sowohl einen Rabatt als auch eine Steuer enthält. Die Steuer wird vom Microservice berechnet, ähnlich wie der Rabatt.

Es gibt einen Käufer.
Einstellbarer Rabatt.
Die Steuer wird festgelegt.
Wenn ein Kunde eine Bestellung aufgibt:
Dann bestellen Sie Optionen.
Dienstleistungen mit Staat
Wenn der Rabattdienst die Datenbank verwendet, um Informationen zur Berechnung des Rabattes zu erhalten, ist sein Inhalt der Status des Dienstes. Statusänderungen als Reaktion auf Datenaktualisierungen sollten dokumentiert werden. Angenommen, der Dienst hatte diesen Status.
In diesem Fall sollte der Dienst das Ändern dieser Daten ermöglichen. Das Update kann so organisiert werden, dass einzelne Elemente aktualisiert werden oder die gesamte Tabelle sofort aktualisiert wird. Hier ist ein Beispiel für einen Verhaltenstest für ein einzelnes Update.
Gegebene aktuelle Daten.
Wenn ein Artikel aktualisiert wird.
Dann aktualisierte Daten.
Sie können auch überprüfen, ob die aktualisierten Daten zur Berechnung des Rabattes verwendet werden.
Der Rabattdienst verfügt in diesem Beispiel möglicherweise über einen lokalen Speicher zum Speichern von Daten, kann jedoch auch von einem separaten Speicherdienst für diese Daten abhängen. Wenn ja, gelten die Tests aus dem vorherigen Abschnitt für einen separaten Dienst. Aber jede Sucht bringt Probleme mit sich. Wie sollte sich ein Dienst verhalten, wenn seine Abhängigkeiten nicht verfügbar sind? Sollte dies bei einem Rabattdienst auf einen Fehler hinweisen oder sollte einfach der Standardwert 0 zurückgegeben werden? Manchmal können Sie globale Fehlerbehandlungsrichtlinien verwenden, aber
oft hängt die Entscheidung vom Kontext des Dienstes ab .
Testformulierung und Automatisierung
Sobald das Verhalten des Mikrodienstes konsistent ist, kann er als automatisierter Test formuliert werden. Es gibt verschiedene Microservice-Testsysteme wie PACT oder Karate. Darüber hinaus können Sie BDD-Frameworks wie Cucumber oder FIT verwenden.
Beispielsweise verwendet Cucumber Bibliotheken zum Abfragen von Diensten. Anschließend können zusätzliche Informationen zur Umgebung als Teil des Skripts angezeigt werden.
Beispielsweise kann eine Gurkenobjektdatei enthalten.
Die Schrittoptionen hängen von Ihren Testkonventionen ab.
Die Werte in den ersten beiden Spalten können auf eine beliebige Aufrufkonvention übertragen werden, um beispielsweise Parameter abzufragen. Das Ergebnis in body muss mit der dritten Spalte übereinstimmen. Wenn die Namen und Werte der Abfrage die Namen und Werte der Spalten sind, werden die Unterschiede zwischen dem Test und der Implementierung verringert.
Zur Wiederverwendung können Schritte für einen beliebigen Dienst geschrieben werden, der Berechnungen durchführt oder das Ergebnis einer Geschäftsregel ermittelt. Im obigen Beispiel hilft die Verwendung des Symbols "?" Wie im obigen "Rabattbetrag" dem Analysator, zwischen Eingabe und Ausgabe zu unterscheiden.
Tests sollten beispielsweise auch Fehler enthalten.
Fazit
Microservices hängen von anderen Diensten und Systemen ab, was eine klare Spezifikation der Schnittstellen und deren genaue Prüfung erfordert. Dies kann erreicht werden, indem das durch Tests definierte Verhalten und die Schnittstellen beschrieben werden. Bei Verwendung von BDD wird die Funktionalität von Diensten durch ausführbare Tests beschrieben, die sich eher
auf die Semantik von Operationen als auf die Syntax konzentrieren . Die Automatisierung solcher Tests erfordert normalerweise das Einrichten von Stubs anderer Dienste, deren Verhalten durch ihre einzelnen BDD-Tests beschrieben wird.
Schnittstellenorientiertes Design - IOD, enthält zusätzliche Verpflichtungen des Dienstes: Einschränkung der Ressourcennutzung, Bandbreite und Fehlerberichterstattung. Zusammen helfen BDD und IOD dabei, das Verhalten des Dienstes zu beschreiben, damit Kunden ihn leicht verstehen und sich darauf verlassen können.
- BDD für Microservices konzentriert sich auf die Zusammenarbeit der Triade - Serviceentwickler, Kundenentwickler und Tester.
- Erstellen Sie mit dem IOD klar definierte Konventionen für Microservice-Schnittstellen.
- Microservices erfordern normalerweise Teststecker, um das Testen zu beschleunigen.
- Tests müssen unabhängig sein.
- Testen Sie negative Szenarien in Tests.
Vom 27. bis 28. Mai wird Artyom Malyshev während des RIT ++ - Festivals auf der QualityConf- Konferenz darüber sprechen, wie wichtig es ist, das Domänenmodell im Code klar auszudrücken, und anhand von Beispielen zeigen, wie dies zu tun ist.
Sprechen Sie über die Entwicklung von Qualitätsprodukten und teilen Sie Ihre Ideen!