Der Kotlin-Titel behauptete, eher mit der Android-Entwicklung verbunden zu sein, aber warum nicht experimentieren? Mit seiner Hilfe haben wir einen Weg gefunden, die Automatisierung des Testens der API eines unserer Dienste leicht zu vereinfachen und die Arbeit von Testern zu erleichtern, die mit der Programmierung und den Nuancen der Java-Sprache nicht vertraut sind.
Was machen wir? Wir entwickeln einen Service zum Versenden von Brokerage-Fragebögen, um diese zu berechnen und eine Entscheidung darüber zu erhalten. Und trotz der Tatsache, dass es sich um eine Banklösung handelt, wird die Entwicklung von einem kleinen Scrum-Team durchgeführt, in dem je nach Belastung und Situation des Projekts 1-2 Spezialisten an Tests beteiligt sind.
Im Rahmen des Schnitts werden wir Sie über die Ergebnisse unserer Experimente informieren, die wir gerne in die Produktion übertragen haben.
Kein Gesicht
Unser Service wurde für die Integration in die Schnittstelle von Partnern entwickelt und verfügt nicht über eine eigene Benutzeroberfläche. Daher ist in diesem Fall das direkte Testen der API die einzige verfügbare Option. Obwohl API-Tests auch mit einer Schnittstelle eine Reihe von Vorteilen haben:
- Sie können bereits in der Phase der Entwicklung von Diensten mit dem Testen beginnen.
- Vereinfachung der Fehlerlokalisierung;
- Reduzieren Sie im Allgemeinen die Testzeit.
Unser Service umfasst eine Reihe von APIs zur Übertragung der Daten des Kundenfragebogens zur Berechnung und zur Erlangung einer Lösung für einen Autokredit. Die folgenden Überprüfungen können als die wichtigsten Testaufgaben auf hoher Ebene unterschieden werden:
- Format von Feldern und Parametern;
- Richtigkeit von Statuscodes und Fehlermeldungen;
- erforderliche Felder und Servicelogik.
Kritischer Moment
Das Team bereitete den MVP des Dienstes in sehr kurzer Zeit vor, und die automatisierten Tests wurden ursprünglich vom Produktentwickler geschrieben. Autotests waren schneller und bequemer in das Projekt aufzunehmen, daher waren sie anfangs eng mit dem Code verbunden und basierten auf dem Java-Stack, REST-versichert und dem TestNG-Testframework.
Mit der Entwicklung des Projekts nahm die Beteiligung der Tester am Automatisierungsprozess zu. Derzeit liegt die Aufgabe der Unterstützung und Aktualisierung von Autotests vollständig bei der Testabteilung. In diesem Zusammenhang wurde es notwendig, den Ansatz zur Automatisierung anzupassen - um Tests so weit wie möglich zu vereinfachen und sie vom Hauptcode unabhängig zu machen. Und damit die auftretenden Schwierigkeiten zu lösen:
- Die Kommunikation mit dem Code macht die Tests anfälliger für Konstruktionsänderungen und erfordert viel Arbeit, um die Leistung aufrechtzuerhalten.
- komplexe Beziehungen verlängern die Zeit, um Informationen zu finden und Fehler zu untersuchen;
- Es ist schwierig, neue Mitarbeiter der Testabteilung in die Arbeit mit Java-Code einzubeziehen. Dies erfordert die Schulung von Testern und einen erheblichen Zeitaufwand für die Teilnahme am Projekt.
Aus diesem Grund haben wir beschlossen, den Testansatz zu ändern, und die folgenden Anforderungen für neue Tools formuliert:
- Vollständige Kompatibilität mit Java, mit der Sie Prüfungen schrittweise umschreiben können, während Sie weiterhin mit alten Tests arbeiten.
- einfacher, intuitiver Code;
- freie und stabile Sprache;
- Auswahl von Autotests in einem separaten Projekt.
Was hat Kotlin damit zu tun?
Die Kotlin-Sprache erfüllt unsere Bedürfnisse so gut wie möglich.
Neben der vollständigen Kompatibilität mit Java in Kotlin waren wir an folgenden Funktionen interessiert:
- Die Prägnanz der Sprache macht den Code klar und leicht lesbar.
- syntethischer Zucker;
- intuitiver Code und einfacher Einstieg von Spezialisten in das Projekt;
- die Möglichkeit, Autotests schrittweise und schmerzlos von Java nach Kotlin zu übertragen, teilweise bei Bedarf.
Natürlich gibt es auch Nachteile, insbesondere im Vergleich zu Java. Erstens eine relativ kleine Community: Hilfe und Antworten auf Java-Fragen zu finden ist viel einfacher als mit Kotlin. Zweitens ist Java im Allgemeinen eine universellere Sprache mit mehr Funktionen und einer großen Anzahl von Entwicklungen und Bibliotheken.
Zu Testzwecken benötigen wir jedoch nicht so umfangreiche Funktionen, die nur Java bieten kann. Daher bevorzugten wir die Einfachheit und Kürze von Kotlin.
Von Worten zu Taten
Durch den teilweisen Übergang zu einer neuen Sprache konnten wir einen spürbaren Anstieg der Arbeitskosten für Spezialisten, eine erhebliche Vereinfachung des Codes und eine Reduzierung seines Volumens erzielen. Dies geht aus konkreten Beispielen aus Tests unseres Dienstes zur Verarbeitung von Maklerprofilen deutlich hervor.
In Kotlin können Sie ein Anforderungsobjekt mit einer Codezeile initialisieren. Die ApplicationDTO-Klasse (zum Senden eines Fragebogens an die Lösung) und ErrorDTO (Fehler, die vom Service stammen) sehen beispielsweise folgendermaßen aus: Mit
Kotlin können Sie während der Initialisierung Feldwerte festlegen. Dies spart viel Zeit beim Schreiben von Tests: Beim Erstellen eines Objekts sind die Felder bereits mit gültigen Daten gefüllt, wir ändern nur die Werte, die sich auf die aktuelle Prüfung beziehen.
Mit der Annotation JsonIgnoreProperties können Sie nicht alle Felder in einer Klasse angeben, wenn sie nicht für Tests benötigt werden und nicht überprüft werden müssen. Wenn ein Feld empfangen wird, das nicht in der Beschreibung angegeben ist, schlägt der Test nicht mit einem Fehler fehl.
Das Fragezeichen am Typ einer Variablen zeigt an, dass es irgendwann null sein kann. Bei Verwendung einer Variablen muss dies jedoch berücksichtigt und verarbeitet werden. Im Gegensatz zu Java-Tests kann NullPointerException hier angemessen vermieden werden.
Lassen Sie uns anhand eines einfachen Beispiels für die Fehlerprüfung auf eine falsche Anmeldung veranschaulichen:
class ApplicationTests {
val DEFAULT_LOGIN = "consLogin"
val ERROR_CODE = "3"
val BASE_URI = "https://base_url.com"
@Test
fun incorrectLogin() {
val incorrectLogin = DEFAULT_LOGIN + "INCORRECT";
val res = given()
.spec(spec)
.body(ApplicationDTO)
.`when`()
.post(endpointApplication(incorrectLogin)
.then()
.statusCode(400)
.extract().`as`(ErrorDTO::class.java)
assertThat(res.error_message).containsIgnoringCase(" ")
assertThat(res.error_code).isEqualToIgnoringCase(ERROR_CODE)
}
companion object{
private var spec: RequestSpecification? = null
@JvmStatic
@BeforeClass
fun initSpec() {
spec = RequestSpecBuilder()
.setContentType(ContentType.JSON)
.setBaseUri(BASE_URI)
.addFilter(ResponseLoggingFilter())
.addFilter(RequestLoggingFilter())
.build()
}
}
}
Wir erstellen eine Spezifikation für Abfragen in BeforeClass, die wir in allen Tests dieser Klasse wiederverwenden. Jackson serialisiert und deserialisiert JSON-Objekte, was die Dinge vereinfacht: Sie müssen nicht wie bei Zeichenfolgen mit ihnen arbeiten, da dadurch die Anzahl der Fehler erheblich reduziert wird.
Mit Kotlin reduzieren wir die Menge an Code erheblich, was bedeutet, dass wir sowohl „Schriftstellern“ als auch „Lesern“ das Leben erleichtern. Die ApplicationDTO-Klasse enthält bereits einen Konstruktor und einige andere Methoden (hashCode (), copy () usw.) - wir müssen den Code nicht mit ihnen "überladen", und unerfahrene Autotest-Entwickler werden von ihnen nicht abgelenkt. Sie müssen im Falle von Änderungen nicht aktualisiert werden, was die Zeit für Änderungen an Tests verkürzt.
Es ist auch sehr praktisch, dass Kotlin benannte Argumente unterstützt - der Code ist recht einfach zu lesen und es ist nicht erforderlich, Setter für die json-Objektklassen selbst zu schreiben.
Probieren Sie neue Dinge kostenlos aus
Ich möchte auf die Offenheit und Freiheit von Kotlin und allen von uns verwendeten Bibliotheken hinweisen, was die Arbeit erheblich vereinfacht und die Möglichkeiten zum Experimentieren und Einführen neuer Ansätze erweitert. Stimmen Sie zu, es ist immer einfacher, neue Dinge kostenlos auszuprobieren und im Fehlerfall zu alten Praktiken zurückzukehren.
In Zukunft planen wir, einen neuen Ansatz zu entwickeln und ihn auf andere Projekte zu skalieren, den Rest der API- und Benutzeroberflächentests in Kotlin zu übersetzen.
PS: Trotz der Tatsache, dass Kotlin hauptsächlich mit der Android-Entwicklung in Verbindung gebracht wird, ist der Umfang seiner Verwendung, wie Sie verstehen, nicht darauf beschränkt. Durch die Reduzierung des Zeitaufwands für das Schreiben von Code, seine Einfachheit und Prägnanz können die Arbeitskosten bei der Lösung vieler Probleme gesenkt werden. Wenn wir neue Fälle mit Kotlin haben, werden wir Ihnen auf jeden Fall davon erzählen.hier .