Jeder schimpft mit selbstgeschriebenen Test-Frameworks. Und wir sind zufrieden mit unserem



Mein Name ist Elena Rastorgueva, ich bin verantwortlich für das Faktor-Produkt bei HFLabs . Der Faktor ist ein verdammt komplexes algorithmisches Unternehmen, das Daten im industriellen Maßstab verarbeitet.

In diesem Artikel werde ich Ihnen erzählen, wie wir mit dem Testen des "Faktors" begonnen haben, wie wir automatische Tests entwickelt haben und warum wir zu den selbst geschriebenen Frameworks gekommen sind.

Was für ein Produkt ist das - "Faktor"


"Faktor" bereinigt Daten in Datenbanken mit Millionen von Kunden: Entfernt Tippfehler in Namen, Telefon und E-Mail, überprüft Pässe und macht vieles mehr. Am schwierigsten ist es, die Postanschriften zu korrigieren.


Adressen werden auf Hunderte von Arten geschrieben, sodass der Faktor einen starken algorithmischen Apparat unter der Haube hat

"Faktor" funktioniert als Dienst: Eingabedaten - Ausgabedaten.

Dies ist ein zustandsloses System, bei dem jeder Anruf unabhängig von den vorherigen ist. Staatenlos vereinfacht das Leben des Testers erheblich. Es ist viel schwieriger, ein Stateful-System zu testen, wenn eine Abfolge von Aktionen wichtig ist.

Das Produkt muss als ISS zuverlässig sein, da es von Banken, Mobilfunkbetreibern, Versicherungen und Einzelhändlern der Lenta-Ebene verwendet wird. Wir antworten auf Fehler mit unserem Kopf, soweit das Fehlen von Fehlern Teil des SLA im Vertrag mit dem Kunden ist.

Aufgrund der Zuverlässigkeitsanforderungen von Autotests haben wir von Anfang an geschrieben. Eines der Kriterien für die Bereitschaft der Aufgabe ist "AutoTests hinzugefügt".

Begonnen mit manuellen Überprüfungen und Autotests


Wir haben den Faktor 2005 auf den Markt gebracht und ihn zuerst mit unseren Händen getestet. Am Morgen führte der Tester automatische Tests für eine Datei mit Fällen durch und verglich das Ergebnis der Datenverarbeitung mit dem Ergebnis des Vortages: Was hat sich nach dem gestrigen Code-Commit geändert?

Der Vorgang konnte einen halben Tag dauern, diese Ausrichtung war nicht gut. Aus diesem Grund haben wir die Mindestanzahl von Tests für die Schlüsselfunktionalität durchgeführt und Unit-Tests durchgeführt. Diese Tests sind schnell und wurden vom Entwickler selbst ausgeführt, bevor sie festgeschrieben wurden.

Unit-Tests sind so bequem und schnell, dass wir Tausende davon hinzugefügt haben. Und dann sind wir darauf gestoßen: Wenn die Tests wie ein Blatt mit Tausenden von Codeteilen aussehen, ist es nicht einfach, an die richtige Stelle zu scrollen. Ganz zu schweigen vom Hinzufügen oder Aktualisieren.


Unit-Test zur Überprüfung des SNILS-Formats

Außerdem erscheint in den Industriedaten plötzlich etwas Unerwartetes, das keine Unit-Tests abdeckt. Zum Beispiel kam ein neuer Kunde mit neuen Funktionen in Adressen, Unit-Tests decken diese Funktionen nicht ab. Sie müssen sich hinsetzen und sehen, welche Tests für neue Daten hinzugefügt werden sollen. Wir haben das immer noch manuell gemacht.

Erstellen Sie Ihr eigenes Framework


Bei herkömmlichen Komponententests werden Daten und Code verwechselt. Es ist schwierig, die richtigen Teile zu finden.

Daher haben wir Autotests im DDT- Paradigma (Data Driven Testing) versucht. DDT ist, wenn Daten zum Testen getrennt vom Code zum Testen gespeichert werden.

Fälle wurden aus einer Excel-Datei geladen, sie befanden sich in den Spalten "Rohdaten" und "Erwartetes Ergebnis". DDT war ein Durchbruch: Das Aktualisieren von Fällen in der "Exelnik" ist unbeschreiblich einfacher.

Nach und nach entwickelten wir einen Ansatz und entwickelten unser eigenes Test-Framework. Es empfängt Textdateien als Eingabe, in denen sich die Quelldaten und das erwartete Ergebnis befinden.


Wir haben Excel-Dateien als Speicher abgelehnt: Textdateien werden schneller geöffnet, ändern den Inhalt nicht, es ist einfacher, Daten von ihnen zu sammeln

Das Framework wird durch Standardtools unterstützt:

  • TeamCity führt jede Nacht automatisch Tests durch.
  • testNG vergleicht erwartete und tatsächliche Ergebnisse.


Wenn das Ergebnis anders als erwartet ist, wird der Test in TeamCity rot. Wenn alles so ist, wie es sollte, ist der Test grün

Das Framework für sich selbst geändert


Seitdem sind 12 Jahre vergangen. In dieser Zeit ist das Framework mit Funktionen überfüllt, die nicht in Standardlösungen enthalten sind.

Berücksichtigung des Aufgabenstatus in Jira. HFLabs hält an der testgesteuerten Entwicklung fest : Zuerst schreiben wir einen Test oder fügen Testfälle für neues Verhalten hinzu und ändern erst dann die Funktionalität.

Wir haben neue Fälle ausgeschaltet, indem wir die Zeile auskommentiert haben. Andernfalls fielen sie zuerst und störten, weil Fälle zuvor Funktionen oder Fehlerbehebungen hinzugefügt hatten.

Möglicherweise kann die Aufgabe den entsprechenden Testfall jedoch nicht abschließen: Der Fehler wird sich als äußerst selten herausstellen oder der Kunde wird etwas Wichtigeres mitbringen. Einige Aufgaben hingen monatelang mit niedriger Priorität, und es häuften sich getrennte Fälle. Gleichzeitig ist unklar, zu welcher Aufgabe jeder Fall gehört, ob dieser Fall gelöscht werden kann.

Aus diesem Grund haben wir den getrennten Fällen eine Aufgabennummer hinzugefügt und ein wenig Automatisierung vermasselt. Jetzt funktioniert alles so:

  • Der Testfall wird deaktiviert, indem er mit einer offenen Aufgabe in Jira abgeglichen wird.


    Um einen Fall an eine Aufgabe anzuhängen, schreiben Sie davor # und Aufgabennummer
  • Das Framework führt Tests auch in deaktivierten Fällen aus. Ignoriert jedoch Abstürze, während die Aufgabe in Jira geöffnet ist.
  • Sobald die Aufgabe geschlossen ist, beginnt der Test auf die damit verbundenen Fälle zu fallen. Dies ist ein Signal: Sie haben die Aufgabe bestanden, aber vergessen, die Fälle einzuschalten.
  • Wenn der Test für den getrennten Fall plötzlich mit einer offenen Aufgabe zu bestehen begann, wird das Framework auch darüber informieren. Vielleicht ist es an der Zeit, den Fall einzuschalten oder die damit verbundene Aufgabe zu schließen (plus Versionshinweise zu aktualisieren und Kunden zu informieren).


    Das Framework sagt, dass der getrennte Fall durchlaufen wird. Vielleicht hat jemand den Code als Teil einer anderen Aufgabe korrigiert, und jetzt funktioniert alles

Also haben wir TDD gerettet und Vergesslichkeit bei der Verwaltung von Testfällen besiegt.


Wir haben alle Optionen mit dem Status von Testfällen und verwandten Aufgaben dokumentiert, um nicht zu vergessen

Aktualisieren von Testfällen im halbautomatischen Modus. Wenn der Test abstürzt, suchen Sie anscheinend nach einem Fehler im Code. Für uns ist dies jedoch nicht immer der Fall. Es kommt manchmal vor, dass Testfälle aktualisiert werden müssen, da sich die Anforderungen an das Ergebnis geändert haben.

Zum Beispiel, bevor der Kunde in der gelöschten Adresse "g. Moskau “in einem Bereich. Jetzt hat er die Architektur der Datenbank geändert, er will die "Stadt" in einem Bereich, "Moskau" in einem anderen. Es ist Zeit, die Testfälle zu ändern.

Für den gefallenen Test zeigt TeamCity den Unterschied zwischen den erwarteten und tatsächlichen Ergebnissen. Zuvor haben wir diesen Unterschied kopiert und Testfälle mit unseren Händen aktualisiert. Für massive Veränderungen - eine sehr teure Veranstaltung.


Ein lebendiges Beispiel: Wir haben „Faktor“ beigebracht, ein Land anhand der Telefonnummer zu bestimmen. Die Tests in TeamCity fielen. Ein neuer Benchmark kann aus dem tatsächlichen Ergebnis entnommen werden, dies dauert jedoch lange

Wir haben das Framework den Benchmark selbst aktualisieren lassen. Zu diesem Zweck werden nach dem Ausführen der Tests die erwarteten Reinigungsergebnisse im Standard durch die tatsächlichen ersetzt, bei denen sie nicht übereinstimmen. Das Ergebnis wird in Artefakten als Fallaktualisierungsdatei gespeichert.


Die erste Datei ist ein neuer Benchmark, bei dem das Framework die erwarteten Ergebnisse aktualisiert hat. Die verbleibenden Dateien sind die Eingabedaten, der alte Standard und die tatsächlichen Daten für die abgelegten Fälle.

Mit dem neuen Benchmark aktualisiert der Tester die Fälle in drei Schritten.

  1. Laden Sie die generierte Datei herunter.
  2. Überprüft alle Zusammenführungswerkzeuge, welche Änderungen im neuen Benchmark vorgenommen wurden. Lässt nur das Notwendige.
  3. Festschreiben


Der Tester prüft, ob die Aktualisierungen im neuen Standard korrekt sind, und schreibt sie fest

Ja, wenn gedankenlos aktualisiert, wird nichts Gutes daraus. Bei manueller Arbeit besteht jedoch die Gefahr einer gedankenlosen Aktualisierung.

Stabilisierung von Testdaten mit Stichleitungen. "Faktor" gibt verarbeitete Daten in Dutzenden von Feldern zurück. Es gibt eine Reihe von Komponenten in nur einer Adresse: Index, Region, Regionstyp, Stadttyp, Stadt, Straßentyp, Haus, Gebäude, Gebäude, Wohnung. Für sie fängt der „Faktor“ IFTS, OKATO, OKTMO und sogar die kleinen Dinge ein. So werden aus einer Zeile am Eingang Dutzende von Werten erhalten.

Nicht alle Felder aus dem Ergebnis müssen mit Testfällen überprüft werden. Beispielsweise hängt die Erkennung derselben Adresse direkt vom Statusverzeichnis FIAS ab. Und darin ändern sich die Felder regelmäßig, für unsere Aufgaben sind sie völlig irrelevant. Durch die Aktualisierung einiger CLADR-Codes für Häuser wurden Hunderte von Testfällen gelöscht.

Wir haben dem erwarteten Ergebnis Stubs hinzugefügt, als wir feststellten, dass wir unsere Zeit damit verschwenden, unwichtige Stürze zu analysieren.

Wenn das Feld überhaupt nicht überprüft werden muss, schreibt der Tester ein Symbol in das erwartete Ergebnis: $$ DNV $$ . Wann das Feld ausgefüllt werden soll, aber der Wert selbst ist nicht wichtig: $$ NE $$ .


Die FIAS-ID befindet sich immer in der Adresse, daher überprüfen wir sie bei allen Tests. Wenn das Feld leer ist, stimmt etwas nicht. Der Index ist jedoch möglicherweise nicht vorhanden. Daher ignorieren wir den Index, wenn wir die FIAS-ID überprüfen

Sie könnten auch in die andere Richtung gehen und die Tests trennen: Jedes Feld hat sein eigenes. Aber es ist schwierig, weil nicht alles isoliert werden kann. Zum Beispiel sind "Stadt" und "Straße" Teile einer Adresse und ohne einander keinen Sinn.

Ein selbst geschriebenes Framework ist bequemer


Daher halte ich die Schaffung eines eigenen Rahmens überhaupt nicht für ein dummes Unterfangen. Wenn wir kein eigenes Tool erstellt hätten, hätten wir nicht so viele neue Möglichkeiten und Flexibilität erhalten.

Das Deaktivieren des Textfalls nach Aufgabenstatus, das Generieren eines neuen Benchmarks und Stubs für das Ergebnis sind die Dinge, die unsere Tester jetzt in anderen Frameworks fragen. Wenn wir Standardlösungen nehmen würden, wären wir dazu niemals in der Lage.

Wenn Sie komplexe Dinge im Unternehmen erledigen möchten, kommen Sie zu uns. Jetzt suchen wir einen Java-Entwickler , Gehalt ab 135 000 ₽ ohne Einkommenssteuer.

Source: https://habr.com/ru/post/de437380/


All Articles