In einem früheren Artikel habe ich meine Automatisierungserfahrung mit dem Robot Framework geteilt. Jetzt werden wir über einen etwas anderen Ansatz zum Testen der API für ein Projekt auf Kotlin sprechen.
Ich nutzte die Freiheit, den Technologie-Stack zu wählen und vertraute auf den Wunsch, „im Kampf“ etwas Neues auszuprobieren, und wandte mich an Rest-Assured. Nicht ohne Schwierigkeiten haben meine Kollegen und ich Tests gestartet, und als Ergebnis der Entwicklung des Ansatzes haben wir ihn in die Liste der Schlüsselaufgaben für diese Art von Aufgabe aufgenommen.
(Bild als Parodie verwendet)Alles begann mit der Tatsache, dass die Anforderung bestand, die Test-API für eines der neuen Projekte im
Ad-Tech-Segment zu automatisieren. Wir haben Campaign Manager, DMP und verschiedene Integrationen mit Systemen von Drittanbietern durchgeführt. Und die Tester hatten eine äußerst einfache Aufgabe: die Rauchprüfung für die weitere Integration in CI und die ständige Überwachung des Status dieser API zu automatisieren, da Systeme von Drittanbietern daran gebunden sind und ein korrekter Betrieb von entscheidender Bedeutung ist. Eine Überprüfung der Geschäftslogik war in diesem Fall nicht erforderlich, da der getestete Dienst im Wesentlichen eine Proxy-Schnittstelle ist.
Warum beruhigt?
Unter dem Gesichtspunkt der Testautomatisierung haben wir es geschafft, in einer Vielzahl von Bereichen zu arbeiten - Benutzeroberfläche, Web, Mobile, Desktop, Backend, REST-API, SOAP.
Das vorherige Projekt hat uns ziemlich viel Erfahrung mit dem Robot Framework gebracht, daher wäre es am logischsten, es zu verwenden. Die meisten Testteams kennen ihn, und wenn ein dringender Austausch erforderlich ist, erfolgt dies schnell und praktisch schmerzlos. Es wurde jedoch eine andere Entscheidung getroffen.
Zunächst wurde das Projekt selbst in Kotlin geschrieben und mit Gradle erstellt. Gleichzeitig wurde in der Entwurfsphase beschlossen, kein separates Projekt zuzuweisen. Wie in den Kommentaren zum vorherigen Artikel erwähnt, ist das Zusammenhalten von Java (Kotlin) und dem Robot Framework ein großer Schmerz, daher war es sinnlos, sich auf RF zu beziehen. Als ich auf die Arbeit mit einem Roboter zurückblickte, war ich daran interessiert, einen anderen Ansatz zu versuchen. Darüber hinaus konnten wir bei diesem Projekt unabhängig einen Technologie-Stack auswählen - das Unternehmen hat keine eigenen Bedingungen festgelegt.
Auf der Suche nach Ideen wandte ich mich an unser Entwicklungsteam sowie an Kollegen aus dem
Testbereich , und CTO riet
mir , mir Rest-Assured (
rest-assured.io )
anzusehen . Nachdem ich die Dokumentation und Beispieltests in Open Source gelesen hatte, erschien mir der von Rest-Assured vorgeschlagene Ansatz sehr attraktiv. Es bedeutet, eine Antwort vom Backend in Form von JSON zu erhalten, die wir in gute alte Java-Objekte deserialisieren.
Außerdem können Sie mit dieser Struktur wie mit einem normalen Objekt arbeiten. Als Ergebnis haben wir einen völlig normalen objektorientierten Ansatz zur Validierung der Entsprechung der API-Antwort mit der beschriebenen Objektstruktur. Als Bonus erhalten wir einen schnellen ausfallsicheren Test der Antwortstruktur. Wenn sich das durch Deserialisieren der API-Antwort empfangene Objekt in der Anzahl der Felder oder deren Namen unterscheidet, werden die Tests gelöscht, noch bevor die Daten mit einem Deserialisierungsfehler überprüft werden. Wir werden also verstehen, ob wir das Backend reparieren oder die Tests gemäß den neuen API-Anforderungen aktualisieren müssen. In unserem Fall war dies wichtig, da, wie oben erwähnt, viele Subsysteme von Drittanbietern an die API gebunden sind.
Aus Gründen der Genauigkeit stelle ich fest, dass ungefähr der gleiche ausfallsichere Test für HF erhalten werden konnte, jedoch auf etwas andere Weise. In der heutigen Geschichte geht es jedoch nicht darum. Persönlich war es für mich bequemer und verständlicher, von der Seite von Rest-Assured mit einer Entität mit bestimmten Feldern und Methoden einzutreten.
Federtest
Bevor ich anfing, den Stack für ein reales Projekt zu verwenden, entschied ich mich, ihn für einen kleinen CRUD-Dienst auszuprobieren. Um seine eigenen Fehler nicht sofort zu üben, entschied er sich, in diesem Stapel nach Best Practices zu suchen, und fand schnell
einen Artikel von Philip Hauer , in dem er seine Automatisierungserfahrung bei Rest-Assured widerspiegelte. Nach dem Studium des Artikels war es nicht schwierig, eine funktionierende Version der Tests meines Dienstes zu schreiben. Sie erwiesen sich als einfach, leicht zu lesen und zu verstehen.
In die Schlacht!
Das Projekt begann und als die ersten Antwortstrukturen beschrieben wurden, begannen die Erstellung der Testdokumentation und das Schreiben von Autotests. Um das Gesamtbild zu verstehen, gebe ich einen vollständigen Stapel von Autotests:
- Java
- JUnit4 - Ausführung und Parametrisierung von Testskripten (Standard Annotation @Parametrize),
- Rest-Assured - Erstellen und Ausführen von Abfragen,
- AssertJ - Validierung der empfangenen Werte,
- Allure - Berichtsgebäude,
- Gradle - Montage
- Jackson - Deserialisierung.
Als die ersten Tests geschrieben wurden, wurde das Problem der richtigen Parametrisierung offensichtlich. Einfache Datenwerte und das erwartete Ergebnis zu vermitteln, schien äußerst ineffizient und hässlich. Ich hatte vor den Ferien keine Zeit, dieses Problem zu lösen, aber meine Kollegen, die während meiner Abwesenheit beteiligt waren, haben es geklärt. Für eine schöne und einfach zu lesende Parametrisierung haben sie beschlossen, eine Basisklasse mit den Funktionen zum Hinzufügen, Empfangen und Löschen von Objektparametern zu erstellen, von denen alle Klassen geerbt wurden, deren Objekte zum Aufrufen der entsprechenden API-Methoden verwendet wurden.

Dies ermöglichte es buchstäblich im laufenden Betrieb, die erforderlichen Daten zu erstellen und diese in den Testparametern zu übertragen.

Mit Rest-Assured können Sie die Antwort auf die erforderliche Klasse deserialisieren. Die resultierende Antwort wird unter Verwendung von Jackson in eine zuvor bekannte Struktur zerlegt. Klassen für die Deserialisierung sehen so einfach wie möglich aus - alle erwarteten Felder mit ihren Typen werden beschrieben.

Darüber hinaus wird die einfache Arbeit mit Objekten und die Behauptung bestimmter Felder und ihrer Werte fortgesetzt.
Das Schwierigste und Nicht-Offensichtliche, auf das ich bei diesem Ansatz gestoßen bin, ist die Unfähigkeit, Null als einen der Parameter an Rest-Assured zu übergeben (das Ergebnis ist ein Abfall der NullPointerException). Anscheinend ist dies ein bekanntes Problem, aber der Entwickler wird die Situation nicht korrigieren und empfiehlt, das Feld entweder leer oder gar nicht zu senden. Wir hatten dieses Problem bereits zu dem Zeitpunkt, als die Grundlage des Projekts fertig war und nur noch Testklassen hinzugefügt werden mussten. Deshalb haben wir unseren Code nur geringfügig korrigiert.
Im Allgemeinen hat mir der Ansatz gefallen. Es ist merkwürdig, dass es nach einiger Zeit auf das Projekt eines anderen Kunden angewendet wurde (allerdings nicht aus unserem Angebot). Und wir haben den zusammengestellten Stack für Automatisierungstest-APIs (JUnit + AssertJ + Rest-Assured) in die Kategorie der wichtigsten für Java / Kotlin-Projekte eingeordnet. In Python ist das Ziehen nicht intuitiv, da es besser ist, dass sich die Entwicklungs- und Testkompetenzen überschneiden.
Es ist auch erwähnenswert, dass einer der Vorteile dieser Lösung ihre Skalierbarkeit und Anpassungsfähigkeit an komplexe Logik ist. Dies bedeutet, dass es am besten für ernsthafte Projekte geeignet ist, bei denen es wirklich sinnvoll ist, große Objekte, sauberen Code und Blockarchitektur zu beschreiben, wenn separate Teile für die Vorbereitung, Übertragung und den Empfang von Daten in lesbarer Form sowie die anschließende Überprüfung der Daten auf Konformität verantwortlich sind einige Bedingungen. In kleinen Projekten ist das alles sinnlos zu ziehen.
Zusammenfassung
In ungefähr einem Monat konnten wir ungefähr 250 Tests automatisieren und den erforderlichen Abdeckungsgrad bereitstellen. Natürlich wurde nach dem Ende des Automatisierungsprozesses eine interne Präsentation für alle abgehalten, damit die Mitarbeiter eine Vorstellung von der geleisteten Arbeit hatten und aus den Erfahrungen mit diesem Projekt lernen konnten.
Artikelautor: Dmitry Masters
PS Wir veröffentlichen unsere Artikel auf mehreren Websites der Runet. Abonnieren Sie unsere Seiten auf
VK ,
FB oder
Telegramm-Kanal , um mehr über unsere Veröffentlichungen und andere Maxilect-Nachrichten zu erfahren.