Hallo Habr!
Mein Name ist Maxim Ponomarenko und ich bin Entwickler bei Sportmaster. Ich habe 10 Jahre Erfahrung im IT-Bereich. Er begann seine Karriere im manuellen Testen und wechselte dann zur Datenbankentwicklung. In den letzten 4 Jahren habe ich mich mit der Testautomatisierung auf DBMS-Ebene beschäftigt und dabei Kenntnisse in Test und Entwicklung gesammelt.
Ich bin seit etwas mehr als einem Jahr Teil des Sportmaster-Teams und beschäftige mich mit der Entwicklung automatisierter Tests für eines der Hauptprojekte. Im April sprachen die Jungs von Sportmaster Lab und ich auf einer Konferenz in Krasnodar. Mein Bericht hieß Unit Tests im DBMS, und jetzt möchte ich ihn mit Ihnen teilen. Da es viel Text geben wird, habe ich beschlossen, den Bericht in zwei Beiträge aufzuteilen. Im ersten werden wir über Autotests und Tests im Allgemeinen sprechen, und im zweiten werde ich auf unser Unit-Test-System und die Ergebnisse seiner Anwendung eingehen.

Zunächst eine etwas langweilige Theorie. Was ist automatisches Testen? Dies sind Tests, die von Software durchgeführt werden und in der modernen IT zunehmend in der Softwareentwicklung eingesetzt werden. Dies liegt an der Tatsache, dass Unternehmen wachsen, ihre Informationssysteme wachsen und dementsprechend die Menge an Funktionen, die getestet werden müssen, wächst. Die Durchführung manueller Tests wird immer teurer.
Ich habe für eine große Firma gearbeitet, deren Veröffentlichungen alle zwei Monate erscheinen. Gleichzeitig wurde ein ganzer Monat mit einem Dutzend Testern verbracht, um die Funktionalität mit ihren Händen zu überprüfen. Dank der Einführung der Automatisierung durch ein kleines Entwicklerteam konnten wir die Testzeit in anderthalb Jahren auf zwei Wochen reduzieren. Wir haben nicht nur die Testgeschwindigkeit erhöht, sondern auch die Qualität. Automatisierte Tests werden regelmäßig durchgeführt und schließen immer den gesamten Verlauf der ihnen innewohnenden Tests ab, dh wir schließen den menschlichen Faktor aus.
Die moderne IT zeichnet sich dadurch aus, dass der Entwickler möglicherweise nicht nur Produktcode schreiben muss, sondern auch Komponententests schreiben muss, die diesen Code verifizieren.
Was aber, wenn Ihr System hauptsächlich auf Serverlogik basiert? Es gibt keine One-Stop-Lösung und Best Practices auf dem Markt. In der Regel lösen Unternehmen dieses Problem, indem sie ein eigenes selbstgeschriebenes Testsystem erstellen. Ein solches proprietäres selbstgeschriebenes automatisiertes Testsystem wurde für unser Projekt erstellt, und ich werde in meinem Bericht darüber sprechen.

Loyalität testen
Lassen Sie uns zunächst über ein Projekt sprechen, in dem wir ein automatisiertes Testsystem implementiert haben. Unser Projekt ist das Treue-System von Sportmaster (darüber haben wir übrigens bereits in
diesem Beitrag geschrieben ).
Wenn Ihr Unternehmen groß genug ist, verfügt Ihr Loyalitätssystem über drei Standardeigenschaften:
- Ihr System wird stark belastet.
- Ihr System enthält komplexe Rechenprozesse.
- Ihr System wird aktiv weiterentwickelt.
Lass uns in Ordnung gehen. Sportmaster hat eine große Anzahl von Geschäften, die aktiv verkaufen. Natürlich ist das Loyalitätssystem ein hoch belastetes System. Und da das Projekt aktiv genutzt wird, müssen wir die höchsten Qualitätsstandards bereitstellen, da jeder Fehler in der Software viel Geld, Ansehen und andere Verluste mit sich bringt.
Gleichzeitig arbeiten in Sportmaster mehr als hundert verschiedene Werbeaktionen. Die Aktien sind sehr unterschiedlich: Es gibt Waren, es gibt Zeitangaben für den Wochentag, es gibt Bindungen an ein bestimmtes Geschäft, es gibt Aktien für die Höhe des Schecks, es gibt Aktien für die Anzahl der Waren. Im Allgemeinen nicht schwach. Kunden haben Boni, es gibt Aktionscodes, die beim Einkauf verwendet werden. All dies führt dazu, dass die Berechnung einer Bestellung eine nicht triviale Aufgabe ist.
Der Algorithmus, der die Auftragsabwicklung implementiert, ist wirklich schrecklich und kompliziert. Und Änderungen an diesem Algorithmus sind ziemlich riskant. Es schien, dass es äußerlich geringfügigste Änderungen gab, die zu eher unvorhersehbaren Auswirkungen führen konnten. Aber gerade solche komplexen Rechenprozesse, umso mehr die Implementierung kritischer Funktionen, sind der beste Kandidat für die Automatisierung. Das Überprüfen von Dutzenden von Fällen des gleichen Typs mit Ihren Händen ist sehr zeitaufwändig. Und da der Einstiegspunkt in den Prozess unverändert bleibt, können Sie nach der Beschreibung schnell automatische Tests stempeln und sich der Funktionalität sicher sein.
Da unser System aktiv genutzt wird, möchte das Unternehmen etwas Neues von Ihnen, lebt auf dem neuesten Stand und ist kundenorientiert. In unserem Treue-System werden Releases alle zwei Monate veröffentlicht. Daher müssen wir alle zwei Monate eine vollständige Regression des gesamten Systems durchführen. Gleichzeitig kommt die Entwicklung natürlich wie in jeder modernen IT nicht sofort vom Entwickler zur Produktion. Es entsteht auf der Schaltung des Entwicklers, besteht dann nacheinander den Prüfstand, die Freigabe und die Abnahme und ist erst dann in Produktion. Zumindest in den Test- und Freigabeschaltungen müssen wir eine vollständige Regression des gesamten Systems durchführen.
Die beschriebenen Eigenschaften sind Standard für fast jedes Treue-System. Lassen Sie uns über die Funktionen unseres Projekts sprechen.
Technologisch gesehen sind 90% der Logik unseres Loyalitätssystems serverbasiert und auf Oracle implementiert. Auf Delphi gibt es einen exponierten Client, der die Funktion eines AWP-Administrators ausführt. Es gibt exponierte Webdienste für externe Anwendungen (z. B. eine Website). Daher ist es sehr logisch, dass wir ein automatisiertes Testsystem unter Oracle bereitstellen.
Das Loyalitätssystem in Sportmaster besteht seit mehr als 7 Jahren und wurde von einzelnen Entwicklern erstellt ... Die durchschnittliche Anzahl der Entwickler in unserem Projekt während dieser 7 Jahre betrug 3-4 Personen. Aber im letzten Jahr ist unser Team erheblich gewachsen und jetzt arbeiten 10 Personen an dem Projekt. Das heißt, Menschen, die mit typischen Aufgaben, Prozessen und Architekturen nicht vertraut sind, kommen zum Projekt. Und es besteht ein erhöhtes Risiko, dass wir Fehler überspringen.
Das Projekt zeichnet sich durch das Fehlen engagierter Tester als Personaleinheiten aus. Testen ist natürlich so, aber Analysten sind zusätzlich zu ihren anderen Hauptaufgaben mit dem Testen beschäftigt: Kommunikation mit Geschäftskunden, Benutzern, Erarbeitung von Systemanforderungen usw. etc ... Trotz der Tatsache, dass die Tests sehr effizient durchgeführt werden (dies ist besonders zu erwähnen, da einer der Analysten die Aufmerksamkeit dieses Berichts auf sich ziehen könnte), hat niemand die Wirksamkeit der Spezialisierung und Konzentration auf eine Sache aufgehoben.
Angesichts der oben genannten Umstände erscheint die Idee, die Tests des Projekts zu automatisieren, sehr logisch, um die Qualität des ausgegebenen Produkts zu verbessern und die Entwicklungszeit zu verkürzen. In verschiedenen Phasen der Existenz des Loyalitätssystems bemühten sich einzelne Entwickler, ihren Code mit Komponententests abzudecken. Es war im Allgemeinen ein ziemlich unterschiedlicher Prozess, bei dem jeder seine Architektur und Methoden verwendete. Unit-Tests waren für die Endergebnisse üblich: Tests wurden entwickelt, für einige Zeit verwendet, in einem versionierten Dateispeicher gestapelt, aber irgendwann hörten sie auf zu starten und vergaßen. Dies war hauptsächlich auf die Tatsache zurückzuführen, dass die Tests eher an einen bestimmten Leistungsträger als an ein Projekt gebunden waren.
UtPLSQL kommt zur Rettung

Wissen Sie etwas über Stephen Feuerstein?
Dies ist ein kluger Kerl, der einen langen Teil seiner Karriere der Arbeit mit Oracle und mit PL / SQL gewidmet hat und eine ziemlich große Anzahl von Arbeiten zu diesem Thema geschrieben hat. Ein bekanntes Buch von ihm heißt: „Oracle PL / SQL. Für Profis. “ Es ist Steven, der die Entwicklung der utPLSQL-Lösung oder, wie es steht, des Unit Testing Frameworks für Oracle PL / SQL besitzt. Die utPLSQL-Lösung wurde 2016 erstellt, arbeitet jedoch weiterhin aktiv daran und veröffentlicht neue Versionen. Zum Zeitpunkt des Berichts ist die neueste Version vom 24. März 2019 datiert.
Was ist das? Dies ist ein separates Open Source-Projekt. Es wiegt ein paar Megabyte und berücksichtigt Beispiele und Dokumentationen. Physikalisch handelt es sich um ein separates Schema in der ORACLE-Datenbank mit einer Reihe von Paketen und Tabellen zum Organisieren von Komponententests. Die Installation dauert einige Sekunden. Eine Besonderheit von utPLSQL ist die einfache Bedienung.
Weltweit ist utPLSQL ein Mechanismus zum Ausführen von Komponententests, bei dem sich ein Komponententest auf reguläre Oracle-Batch-Prozeduren bezieht, deren Organisation bestimmten Regeln folgt. Zusätzlich zum Start speichert utPLSQL ein Protokoll aller Ihrer Testläufe, und es gibt auch ein internes Berichtssystem.
Schauen wir uns ein Beispiel an, wie der durch diese Technik implementierte Unit-Test-Code aussieht.

Der Bildschirm zeigt also den Code für die Standardspezifikation eines Pakets mit Komponententests. Was sind die erforderlichen Anforderungen? Das Paket muss das Präfix utp_ haben. Alle Verfahren mit Tests sollten genau das gleiche Präfix haben. Das Paket muss zwei Standardprozeduren enthalten: "utp_setup" und "utp_teardown". Die erste Prozedur wird aufgerufen, indem jeder Komponententest neu gestartet wird, die zweite - nach dem Start.
"Utp_setup" bereitet unser System in der Regel darauf vor, einen Komponententest durchzuführen, beispielsweise werden Testdaten erstellt. "Utp_teardown" - im Gegenteil, alles kehrt zu seinen ursprünglichen Einstellungen zurück und setzt die Startergebnisse zurück.
Hier ist ein Beispiel für den einfachsten Komponententest, bei dem die Normalisierung der eingegebenen Kunden-Telefonnummer auf den Standard-Look für unser Treue-System überprüft wird. Es gibt keine verbindlichen Standards für Schreibverfahren mit Komponententests. In der Regel wird eine Methode des zu testenden Systems aufgerufen und das von dieser Methode zurückgegebene Ergebnis mit dem Referenzergebnis verglichen. Es ist wichtig, dass der Vergleich des Referenzergebnisses und des Ergebnisses über Standard-utPLSQL-Methoden erfolgt.
Ein Unit-Test kann eine beliebige Anzahl von Prüfungen haben. Wie Sie dem Beispiel entnehmen können, führen wir vier aufeinanderfolgende Anrufe der getesteten Methode durch, um die Telefonnummer zu normalisieren, und nach jedem Anruf bewerten wir das Ergebnis. Bei der Entwicklung eines Komponententests muss berücksichtigt werden, dass es Überprüfungen gibt, die das System in keiner Weise beeinflussen, und nach einigen muss ein Rollback auf den Ausgangszustand des Systems durchgeführt werden.
Im vorgestellten Unit-Test formatieren wir beispielsweise einfach die eingegebene Telefonnummer, was sich nicht auf das Treue-System auswirkt.
Wenn wir Komponententests mit der Methode zum Erstellen eines neuen Clients schreiben, wird nach jeder Überprüfung ein neuer Client im System erstellt, was sich auf den nachfolgenden Start des Tests auswirken kann.

So laufen Unit-Tests ab. Es gibt zwei mögliche Startoptionen: Starten aller Komponententests von einem bestimmten Paket oder Starten eines bestimmten Komponententests in einem bestimmten Paket.

Hier ist ein Beispiel für ein internes Berichtssystem. Nach den Ergebnissen des Unit-Tests erstellt utPLSQL einen kleinen Bericht. Darin sehen wir das Ergebnis jedes spezifischen Tests und das Gesamtergebnis des Einheitentests.
6 Regeln für Autotests
Bevor wir gemeinsam mit dem Management ein neues System zum automatisierten Testen eines Loyalitätssystems erstellen, haben wir die Grundsätze festgelegt, denen unsere zukünftigen Autotests entsprechen sollten.

- Autotests sollten effektiv und vorteilhaft sein. Wir haben wundervolle Entwickler, über die ich sagen muss, weil einer von ihnen diesen Bericht wahrscheinlich sehen wird und sie wundervollen Code schreiben. Aber selbst ihr wunderbarer Code ist nicht perfekt und enthält, enthält und enthält Fehler. Autotests sind erforderlich, um diese Fehler zu finden. Wenn dies nicht der Fall ist, schreiben wir entweder schlechte Selbsttests oder sind zu einem toten Bereich gekommen, der im Prinzip nicht abgeschlossen wird. In beiden Fällen machen wir etwas falsch und unser Ansatz ist einfach bedeutungslos.
- Automatische Tests sollten verwendet werden. Es macht keinen Sinn, viel Zeit und Mühe damit zu verbringen, ein Softwareprodukt zu schreiben, sein Repository zu addieren und es zu vergessen. Tests sollten so regelmäßig wie möglich ausgeführt werden.
- Autotests sollten stabil funktionieren. Unabhängig von der Tageszeit, dem Startstand oder anderen Systemeinstellungen sollte das Ausführen der Tests zum gleichen Ergebnis führen. Dies wird in der Regel dadurch sichergestellt, dass Autotests mit speziellen Testdaten mit festen Systemeinstellungen arbeiten.
- Automatische Tests sollten mit einer für Ihr Projekt akzeptablen Geschwindigkeit funktionieren. Diese Zeit wird für jedes System individuell festgelegt. Jemand kann es sich leisten, den ganzen Tag zu arbeiten, und jemand passt kritisch in die Sekunden. Welche Geschwindigkeitsstandards wir in unserem Projekt erreicht haben, werde ich etwas später erzählen.
- Die Entwicklung von Autotests sollte flexibel sein. Es ist unerwünscht, sich zu weigern, Funktionen zu testen, nur weil wir dies noch nicht getan haben oder aus anderen Gründen. utPLSQL unterwirft keine Entwicklungsbeschränkungen, und mit Oracle können Sie im Prinzip eine Vielzahl von Dingen implementieren. Die meisten Aufgaben haben eine Lösung, die einzige Frage ist Zeit und Mühe.
- Bereitstellbarkeit. Wir haben mehrere Stände, an denen Sie Tests durchführen müssen. An jedem Stand kann jederzeit ein Datendump aktualisiert werden. Es ist notwendig, ein Projekt mit Autotests so durchzuführen, dass die vollständige oder teilweise Installation problemlos durchgeführt werden kann.
Und im zweiten Beitrag in ein paar Tagen werde ich Ihnen sagen, was wir getan haben und welche Ergebnisse erzielt wurden.