Testgetriebene Entwicklung ist eine effektive Methode, um gut getesteten und umgestaltbaren Code sicherzustellen. Die Grundidee besteht darin, dass Sie mit der Entwicklung beginnen, indem Sie Tests schreiben. Diese Tests dokumentieren die Erwartungen klar und bilden eine Grundlage für eine erfolgreiche Umsetzung. Wenn Sie es richtig machen, können Sie die erwartete Eingabe/Ausgabe einer Funktion klar definieren, bevor Sie Code schreiben. Dies hat einige unmittelbare Vorteile:
Da Sie nun von den Vorteilen überzeugt sind, können Sie mit der testgetriebenen Entwicklung (TDD) beginnen, indem Sie die folgenden Schritte befolgen:
Diese Schritte werden in einem Zyklus ausgeführt, sodass Sie immer weitere Tests hinzufügen, um die aktuelle Implementierung zu hinterfragen.
Der letzte Schritt, der das Schreiben der Mindestmenge an Code angibt, kann mühsam werden, wenn er strikt befolgt wird. Es ist wichtig zu verstehen, warum diese Regel existiert, bevor Sie entscheiden können, wann es angebracht ist, davon abzuweichen.
Sie haben die Aufgabe, die Funktion Add(x, y int) int zu implementieren. Bevor Sie zur Implementierung springen und einfach x + y zurückgeben, schreiben Sie den einfachsten Test: 1 + 1 == 2. Welche einfachste Implementierung würde dann den Test bestehen? Es ist nur Rückkehr 2. Jetzt bestehen Ihre Tests!
An diesem Punkt wird Ihnen klar, dass Sie weitere Tests benötigen, also erhöhen Sie das Tempo und fügen noch ein paar hinzu:
Jetzt schlagen Ihre Tests fehl, sodass Sie die Implementierung korrigieren müssen. Diesmal können Sie nicht einfach 3 oder 105 zurückgeben, Sie müssen also eine Lösung finden, die für alle Tests funktioniert. Dies führt zur Implementierung: return x + y.
Während sich das in dem trivialen Beispiel übermäßig langweilig anfühlt, hat die strikte Einhaltung dieser Methode dazu geführt, dass Sie mehrere Tests geschrieben haben, anstatt nur Ihrer Implementierung zu vertrauen. Natürlich hätte Ihre ursprüngliche Idee, x + y zurückzugeben, funktioniert, aber es geht darum, sich neu anzutrainieren, sich auf Tests zu verlassen und nicht auf Ihr eigenes Verständnis des Codes. In der realen Welt sind Sie nicht der Einzige, der an diesem Code arbeitet, und werden unweigerlich Implementierungsdetails vergessen. Dieser Prozess zwingt Sie dazu, mehr Tests zu schreiben und sich mehr Möglichkeiten auszudenken, um die einfache Implementierung zu durchbrechen.
Mit der Zeit werden Sie Erfahrung sammeln und lernen, die Balance zu finden, die in den verschiedenen Szenarien, denen Sie begegnen, funktioniert. Sie kehren zur Implementierung der Funktionen mit voller Geschwindigkeit zurück und stellen fest, dass Sie weniger Fehler haben und wartbareren Code schreiben können.
Kommen wir zu einem komplizierteren Beispiel mit TDD für eine HTTP-REST-API. Diese Schritt-für-Schritt-Anleitung verwendet mein Go-Framework babyapi, aber die Konzepte können überall angewendet werden.
babyapi verwendet Generika, um eine vollständige CRUD-API rund um Go-Strukturen zu erstellen, wodurch es sehr einfach ist, eine vollständige REST-API und Client-CLI zu erstellen. Darüber hinaus stellt das Babytest-Paket einige Tools zum Erstellen von End-to-End-API-Tabellentests bereit. Die Verwendung von TDD auf API-Ebene ermöglicht das vollständige Testen der HTTP- und Speicherebenen einer neuen API oder Funktion auf einmal.
Haftungsausschluss: Da babyapi den Großteil der Implementierung übernimmt und auch zum Generieren von Test-Boilerplates verwendet wird, beginnen wir technisch gesehen nicht mit TDD. Wir werden jedoch sehen, wie vorteilhaft es ist, wenn wir unserer API Unterstützung für PATCH-Anfragen hinzufügen.
Erstellen Sie ein neues Go-Projekt
Erstellen Sie das erste main.go anhand des einfachen Beispiels von babyapi
Führen Sie die Tests durch und stellen Sie sicher, dass sie bestehen!
This test fails since babyapi doesn't support PATCH by default. We can fix it by implementing Patch for the TODO struct. Since we defined our feature with two tests, our simplest implementation isn't just setting Completed = true and we have to use the value from the request
Now we can change the Completed status of a TODO, but we still cannot use PATCH to modify other fields as show by this new set of tests
Update Patch to set the remaining fields
Our tests still fail since we always update the TODO with the request fields, even if they're empty. Fix this by updating the implementation to check for empty values
The new UpdateWithPatch test passes, but our previous tests fail. Since we changed Completed to be *bool, TODOs created with an empty value will show as null
Implement Render for TODO so we can treat nil as false
Implementing the PATCH feature with test-driven development resulted in a robust set of tests and a well-implemented feature. Since we started by defining the expected input and output of a PATCH request in tests, it was easy to see the issues caused by not checking for empty values in the request. Also, our pre-existing tests were able to protect from breaking changes when changing the type of Completed to *bool.
Test-driven development is an effective approach for creating fully tested and correct code. By starting with tests in mind, we can ensure that every piece of code is designed to be testable instead of letting tests be an afterthought.
If you're hesitant about adopting TDD, here are a few ideas to get started:
Even if TDD isn't a good fit for the way you write code, it's still a powerful tool to have in your belt. I encourage you to at least commit some time to trying it out and see how it affects your development process.
Das obige ist der detaillierte Inhalt vonTestgetriebene API-Entwicklung in Go. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!