Modellierung durch Beispiel: Ein gemeinsames Verständnis

© Jo Carter (Flickr) Alle Rechte vorbehalten

Quergepostet von Mittel; Ursprünglich gepostet 7. April 2017


Ich habe kürzlich an der teilgenommen PHP UK 2017 Konferenz in London. Abgesehen davon, dass PHP 82 % des Webs ausmacht, habe ich auch einen erstaunlichen Vortrag von gesehen Ciaran McNulty (@ciaranmcnulty) genannt Design durch Beispiele vorantreiben (die Folien sind ein guter Bezugspunkt, und Sie können auch a sehen Video des Vortrags).

Hinweis: Obwohl sich dieser Artikel speziell auf PHP bezieht, können die Prinzipien auf jede Art von Entwicklung angewendet werden (setzen Sie einfach die entsprechenden Tools ein).

Haftungsausschluss: Dies ist eine Zusammenfassung des Vortrags mit einigen meiner eigenen persönlichen Interpretationen und Gedanken. Alle Fehler sind meine eigenen.


Modeling by Example kombiniert einige der Konzepte von Behavior Driven Development (BDD) und Domain Driven Design (DDD). —Konstantin Kudrjaschow (@everset).


Verhaltensgesteuerte Entwicklung

„BDD ist die Kunst, in Gesprächen anhand von Beispielen Verhalten zu veranschaulichen“ —Liz Keogh.

Wenn Sie ein neues Projekt planen, haben Sie oft eine Reihe von Regeln oder Geschäftsanforderungen, die Sie einhalten müssen. Allerdings sind Regeln zweideutig und führen oft zu Annahmen, die zu Verzögerungen in einem Projekt führen können, wenn Sie zurückgehen müssen, um sie zu beheben. Beispiele sind jedoch eindeutig und überprüfbar ; sie bilden die Grundlage für User Stories und Szenarien. Wenn Sie Ihr Regelwerk für ein Projekt erhalten, setzen Sie sich mit den relevanten Personen zusammen – einem Geschäftsexperten, einem Testexperten und einem Entwicklungsexperten –, um das Feature gemeinsam zu besprechen und Beispiele zu entwickeln.

Lassen Sie uns ein Beispiel geben. Nun, eigentlich stehlen wir einfach Ciarans Beispiel …

  • Für jeden für einen Flug ausgegebenen £1 erhalten Sie 1 Punkt
  • 100 Punkte können für 10 £ Rabatt auf einen zukünftigen Flug eingelöst werden
  • Flüge werden mit 20 % besteuert

Ich weiß nicht, wie es Ihnen geht, aber wenn ich mir diese Anforderungen ansehe, habe ich mehrere Fragen.

  • Sammeln Sie Punkte für die Steuer oder nur für den Basisflug?
  • Können Sie beim Einlösen Punkte sammeln?
  • Können Sie mehr als 100 Punkte auf einmal einlösen, wenn Sie welche haben?
  • Wenn Sie Punkte einlösen, mit welchem ​​Betrag werden Sie besteuert?
  • Ich frage mich auch, ob Punkte auf Teilbeträge auf- oder abgerundet werden. Verdienen Sie Teilpunkte? (Anscheinend ist der Standard dafür das Abrunden)

Und das ist nur aus der Spitze meines Kopfes. Sie stellen sich also den Fragen und entwickeln im Team testbare Beispiele.

Unter der Annahme, dass ein bestimmter Flug £50 kostet:

  • Wenn Sie bar bezahlen, kostet es 50 £ + 10 £ Steuern und Sie erhalten 50 neue Punkte
  • Wenn Sie vollständig mit Punkten bezahlen, kostet es 500 Punkte + 10 £ Steuern und Sie erhalten 0 neue Punkte
  • Wenn Sie mit 100 Punkten bezahlen, kostet es 100 Punkte + 40 £ + 10 £ Steuern und Sie erhalten 0 neue Punkte

Sie können jetzt Ihre Szenarien als Vorbereitung für die Entwicklung des Features erstellen. Gurke ist ganz gut dafür, da es eine formale Sprache für Beispiele ist, aber Sie müssen sie nicht verwenden. Eine andere zu beachtende Sache ist, dass Szenarien dazu da sind, um a Gemeinsames Verständnis eines Features, um eine anfängliche Definition von Done zu geben und anzugeben, wie ein Feature getestet werden kann; sie sind keine Verträge, und sie können sich entwickeln wenn Sie mehr Wissen und Verständnis erlangen. Aber irgendwo muss man ja anfangen. Das Beste daran, die Szenarien so zu schreiben, ist, dass Implementierungsdetails (wie das Klicken auf Schaltflächen und das Laden von Seiten) vermieden werden, die nicht Teil des Tests sein sollten.

Szenarien sind gut und gut, um zu veranschaulichen, wie die Regeln gelten; Sie müssen jedoch sicherstellen, dass Sie alle auf derselben Seite sind. Bedeutet das Wort, von dem Sie sprechen, für alle anderen dasselbe, ist es überhaupt das richtige Wort?


Domänengesteuertes Design

„DDD bewältigt Komplexität, indem es die Aufmerksamkeit des Teams auf das Wissen über die Domäne lenkt“ —Eric Evans.

Es ist wichtig, etwas Zeit zu investieren, um das Geschäft zu verstehen. Erstellen Sie ein Domänenwörterbuch, a allgegenwärtige Sprachea gemeinsame Art zu sprechen über Geschäftskonzepte. Es reduziert die Übersetzungskosten, sodass ein Entwickler weiß, dass der Geschäftsexperte genau weiß, worauf sich das im Kontext des Geschäfts bezieht, wenn er ein Objekt als Flug bezeichnet. Verwenden Sie diese Sprache bei der Erstellung Ihrer Beispiele.

Die Kombination von Aspekten dieser beiden Paradigmen gibt Ihnen Modellierung am Beispiel.


Modellierung am Beispiel

„Durch die Einbettung von Ubiquitous Language in Ihre Szenarien werden Ihre Szenarien auf natürliche Weise zu Ihrem Domänenmodell“ —Konstantin Kudrjaschow (@everset).

Die Prinzipien der Modellierung durch Beispiel sind:

  • Der beste Weg, das Domänenmodell zu verstehen, ist durch Beispiele diskutieren
  • Schreiben Sie Szenarien, die erfassen allgegenwärtige Sprache
  • Schreiben Sie Szenarien, die veranschaulichen reale Situationen
  • Direkt fahren den Code aus diesen Beispielen

Das Domänenmodell ist nicht der Code oder ein Diagramm. Es ist der Gemeinsames Verständnis das gesamte Team (Entwickler, Tester und das Geschäft) wissen, wie das System funktioniert. Der Code, die Tests und die Dokumentation sind alle Darstellungen des Domänenmodells.

Jetzt haben Sie vielleicht schon davon gehört Testpyramide (Das Gegenteil davon ist eine Eistüte oder Cupcake—schlecht für das Projekt, aber trotzdem lecker). Es ist ideal, sicherzustellen, dass Ihr Projekt nicht mit langsamen Tests, die leicht brechen, kopflastig wird. Jeder hasst es, darauf zu warten, dass die Testsuite ausgeführt wird, nur um einen Test zufällig zu unterbrechen, weil ein Netzwerkausfall vorliegt oder etwas nicht gerendert werden kann.

Das Testen jedes Szenarios über die Benutzeroberfläche (UI) ist langsam, spröde und zwingt Sie dazu, die Domäne und die Benutzeroberfläche gleichzeitig zu entwerfen. Es gibt auch Probleme beim Testen jedes Szenarios mit der tatsächlichen Infrastruktur, zum Beispiel kann das Testen des Geschäftsmodells zu 1000 Tests führen, die ein Objekt anhand seiner ID finden (wobei wir nach einem Test ziemlich sicher sein können, dass es funktioniert), anstatt Testen interessanter Grenzfälle.

Was Sie tun können, ist, das Domänenmodell (das mittlere Bit) zuerst mit Behat mit einer gefälschten (In-Memory-)Infrastruktur zu testen und den Code direkt aus den von Ihnen geschriebenen Szenarien zu steuern.


Beginnen Sie mit der Verbesserung Ihrer Szenarien, indem Sie hinzufügen realistische Details. Fragen Sie die Domain ab, um sicherzustellen, dass Sie die richtigen Begriffe verwenden. Finden Sie heraus, wie das Geschäft eigentlich denkt über Dinge und welche Wörter sie verwenden (siehe Verweis oben auf das Domänenwörterbuch). Du musst gut werden Hören. (Eigentlich ist dies ein guter Rat, was auch immer Sie tun).

Im Airline-Beispiel haben wir mit dem Folgenden begonnen:

Given a flight costs £50

Indem wir realistische Beispiele hinzufügten, erhielten wir:

Given a flight from "London" to "Manchester" costs £50

Die aktive Suche nach Begriffen aus der Domain und das Herausfinden, wie das Geschäft tatsächlich funktioniert, führt zu:

Given a flight "XX-100" flies the "LHR" to "MAN" route
And the current listed fare for the "LHR" to "MAN" route is £50

Nun, das gibt uns etwas, womit wir tatsächlich arbeiten können. Wir müssen keine Annahmen darüber treffen, wie das System funktioniert, und wenn wir mit den Beteiligten über das Projekt sprechen, sind alle auf derselben Seite. Wenn Sie das Gefühl haben, dass Sie nicht alle Antworten haben, dann gehen Sie zurück und fragen Sie nach. Ihr Code wird umso besser und das Produkt auch.

Jetzt haben wir praktikable Szenarien, wir nehmen diese und verwenden sie Betrieb um das Domänenmodell voranzutreiben.

Machen Sie einfach einen Schritt nach dem anderen. Beginnen Sie mit der ersten Zeile. Erstellen Sie ein ausstehendes Beispiel und fügen Sie dann Code nur für dieses Beispiel hinzu.

Modellieren Sie alle Ihre Werte als Wertobjekte

Dies gibt Ihnen eine größere Kontrolle über Ihre Daten und ermöglicht eine strengere Typisierung und Validierung. Sie können verwenden@Transform in Behat, um Ihre Zeichenfolgen in das richtige Format zu konvertieren (eine neue Sache, die ich gerade gelernt habe), was wirklich nützlich ist. Außerdem erhalten Sie einen übersichtlicheren und besser lesbaren Testcode, was ein definitives Plus ist!

Wenn Sie das erste Beispiel ausführen, tritt offensichtlich ein schwerwiegender Fehler auf, da Sie keine Klassen erstellt haben. Dies ist in Ordnung 😃 So macht man das. Sie sollten immer mit einem „nicht bestandenen“ Test beginnen.

Machen Sie einen Schritt weg von der Behat-Suite und beginnen Sie mit der Beschreibung der Objekte, die Sie benötigen PhpSpec (oder was auch immer Ihre bevorzugte Methode für Komponententests ist). Ich empfehle PhpSpec wirklich, weil es Ihr Denken weg vom „Testen“ des Codes hin zum „Beschreiben“ der Funktionalität lenkt; und führt meiner Meinung nach zu viel besserem (und schlankerem) Code. Schreiben Sie nur die Mindestmenge an Code, die Sie benötigen, um jede Spezifikation zu bestehen. Wenn Sie mehr Code hinzufügen müssen, fügen Sie zuerst eine Spezifikation hinzu (z. B. zum Testen gültiger und ungültiger Eingaben).

Nachdem Sie Ihre Objekte beschrieben und erstellt haben, ist die erste Zeile Ihres Behat-Szenarios abgeschlossen.

Modellgrenzen mit Schnittstellen

Schnittstellen sind immer gut, denn das bedeutet, dass Sie niemals den Code von jemand anderem testen (womit ich Dritte meine, nicht andere Entwickler in Ihrem Team!). Außerdem können Sie dann eine In-Memory-Version der Schnittstelle zum Testen erstellen. Es ist eine Trennung von Anliegen, um Abhängigkeiten zu reduzieren, und eines der dahinter stehenden Prinzipien EBI Architektur (Entity-Boundary-Interactor), auch bekannt als Sechseckige Architektur.

Sobald Sie beginnen, Klassen zu beschreiben, die Dinge mit Ihren Wertobjekten tun, müssen Sie überlegen, ob Sie konkrete Objekte (z new Thing()) oder ob es besser ist, ein Doppel zu verwenden? Da ist ein interessante Diskussion mit Ciaran diesbezüglich; Aber was ich davon nehme, ist, dass, wenn Sie Wertobjekte als final dann „können“ sie nicht verdoppelt werden; Außerdem macht es die Tests leichter lesbar – aber auch das Verdoppeln wird meistens verwendet, wenn Sie andere Abhängigkeiten haben und Tests isoliert werden möchten. Du musst die Balance finden, die für dich funktioniert.

Übrigens, wenn Sie Ihre Modelle und Methoden schreiben, denken Sie sorgfältig über die Benennung nach. Sie sollten so nah wie möglich realen Dingen und Aktionen ähneln und nicht Implementierungsdetails.

An diesem Punkt sollten Sie die Grundstruktur Ihres Szenarios eingerichtet haben, aber den Modellen wird jegliche Funktionalität fehlen, bis Sie dazu kommen Then. Then ist, wenn Sie anfangen, das Wesentliche und die Logik hinzuzufügen und das, was Sie bisher geschaffen haben, auf sinnvolle Weise miteinander zu verknüpfen.

Beginnen Sie damit, die zusätzlichen Validierungen oder Optionen hinzuzufügen, die Sie benötigen, um die anderen Szenarien zu bestehen, z. B. das Bezahlen mit Punkten anstelle von Bargeld oder eine Teilzahlung. Verwenden Sie die bereits erworbene Geschäftslogik, um sicherzustellen, dass Sie alle möglichen Szenarien abgedeckt haben. Die Kosten sind zu diesem Zeitpunkt vernachlässigbar, da alles im Arbeitsspeicher erfolgt und unabhängig von Abhängigkeiten ausgeführt wird.


Endlich: End-to-End-Testing.

Da Sie die Domäne bereits modelliert haben und wissen, dass alle Szenarien darin abgedeckt sind, müssen die UI-Tests nicht so umfassend sein. Sie müssen nicht 10 Tests haben, die auf dieselbe Schaltfläche klicken, sondern nur unterschiedliche Zahlen zurückgeben, da dies bereits in der mittleren Ebene abgedeckt ist. Sie können stattdessen die geeigneten Szenarien zum Testen auswählen und sich auf die Interaktionen und die Benutzererfahrung (UX) konzentrieren. Außerdem ist der eigentliche UI-Code einfacher zu schreiben.

An dieser Stelle würde ich auch empfehlen, einige spezifische End-to-End-Tests für alle APIs durchzuführen, die Sie für das Projekt geschrieben haben, um sicherzustellen, dass die Infrastruktur (die wir zuvor ignoriert haben) wie erwartet funktioniert.


Zusammenfassend

Modellierung am Beispiel…

  • Lenkt die Aufmerksamkeit auf Anwendungsfälle
  • Hilft Entwicklern verstehe Kerngeschäftsbereiche
  • Ermutigt Schichtarchitektur
  • Geschwindigkeiten Testsuites erstellen

Sie sollten es verwenden, wenn …

  • Das Projekt ist Ader zu Ihrem Unternehmen
  • Sie werden es wahrscheinlich tun Unternehmensveränderungen unterstützen in der Zukunft
  • Du kannst haben Gespräche mit Interessenten

Verwenden Sie es nicht, wenn…

  • Das Projekt ist nicht Kern zum Geschäft
  • Du baust ein Prototyp oder kurzfristiges Projekt
  • Es kann sein weggeworfen wenn sich das Geschäft ändert
  • Du hast kein Zugang an Geschäftsexperten (aber versuchen Sie, dies zu ändern)

Einige abschließende Gedanken. Softwareentwicklung ist ein sich ständig weiterentwickelndes Ökosystem. Niemand macht es beim ersten Mal richtig, aber Sie lernen im Laufe der Zeit und entwickeln sich kontinuierlich weiter und verbessern sich (auch wenn es sich nicht so anfühlt!). Wählen Sie, was für Sie funktioniert. Entwickeln Sie Ihren eigenen Prozess, verbessern Sie ihn, teilen Sie ihn mit Ihren Kollegen und lernen Sie auch von ihnen.

Similar Posts

Leave a Reply

Your email address will not be published.