Heim > Backend-Entwicklung > Golang > Testgetriebene API-Entwicklung in Go

Testgetriebene API-Entwicklung in Go

王林
Freigeben: 2024-07-18 01:18:11
Original
542 Leute haben es durchsucht

Test-driven API Development in Go

Einführung

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:

  • Sie überlegen sich sorgfältig die Schnittstelle für die Interaktion mit Ihrem Code und entwerfen sie so, dass sie testbar ist
  • Wenn Sie mit dem Schreiben von Code beginnen, wird Ihr Ablauf nicht durch manuelle Tests oder das Durchlaufen der Ausführungslogik zur Vorhersage des Ergebnisses unterbrochen. Stattdessen führen Sie einfach die Tests durch
  • Das Bestehen einer Prüfung wird zu einem zufriedenstellenden Ziel. Die Unterteilung des Prozesses in eine Reihe klar definierter und erreichbarer Meilensteine ​​macht die Arbeit angenehmer
  • Vermeiden Sie Faulheit und Selbstüberschätzung nach der Implementierung, die Sie daran hindern könnten, Ihren Code zu testen

Da Sie nun von den Vorteilen überzeugt sind, können Sie mit der testgetriebenen Entwicklung (TDD) beginnen, indem Sie die folgenden Schritte befolgen:

  1. Tests schreiben oder ändern
  2. Überprüfen Sie, ob der Test fehlschlägt
  3. Schreiben Sie die Mindestmenge an Code, damit die Tests erfolgreich sind

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.

Einfaches Beispiel

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:

  • 1 + 2 == 3
  • 100 + 5 == 105

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.

Schritt-für-Schritt-TDD für eine HTTP-API

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.

  1. Erstellen Sie ein neues Go-Projekt


  2. Erstellen Sie das erste main.go anhand des einfachen Beispiels von babyapi


  3. Verwenden Sie die CLI, um ein Test-Boilerplate zu generieren

  4. Implementieren Sie jeden Test, indem Sie die Platzhalter mit dem erwarteten JSON ausfüllen
  5. Führen Sie die Tests durch und stellen Sie sicher, dass sie bestehen!

    Da PUT idempotent ist, müssen alle Felder enthalten sein. Um dies zu vermeiden, möchten wir Unterstützung für das Umschalten zwischen „Abgeschlossen“ und „PATCH“-Anfragen hinzufügen. Wir beginnen mit dem Hinzufügen eines einfachen Tests, wie diese Funktion voraussichtlich aussehen wird
  6. 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

  7. 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

  8. Update Patch to set the remaining fields

  9. 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

  10. 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

  11. 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.

Conclusion

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:

  • Try it in simple scenarios where a function's input/output is clear and the implementation is not overly complicated. You can write a robust table test for the variety of input/output that could be encountered. Having a clear visual of the different scenarios can simplify implementation
  • If you're fixing a new bug, you have already identified a gap in your testing. Start by writing a test that would have identified this bug in the first place. Then, make this test pass without breaking any existing tests.
  • Similar to the babyapi example, you can use TDD for high-level API tests. Once you have a definition of the expected request/response, you can resume your usual development flow for more detail-oriented parts of the implementation

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!

Quelle:dev.to
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage