Unit-Tests in einem DBMS – wie wir es in Sportmaster machen, Teil eins

Hey Habr!

Mein Name ist Maxim Ponomarenko und ich bin Entwickler bei Sportmaster. Ich verfüge über 10 Jahre Erfahrung im IT-Bereich. Er begann seine Karriere mit manuellen Tests und wechselte dann zur Datenbankentwicklung. In den letzten 4 Jahren habe ich das im Testen und Entwickeln erworbene Wissen gesammelt und Tests auf DBMS-Ebene automatisiert.

Ich bin seit etwas mehr als einem Jahr im Sportmaster-Team und entwickle automatisierte Tests für eines der Großprojekte. Im April sprachen die Jungs vom Sportmaster Lab und ich auf einer Konferenz in Krasnodar. Mein Bericht hieß „Unit-Tests in einem 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 detaillierter auf unser Unit-Testsystem und die Ergebnisse seiner Anwendung eingehen.

Unit-Tests in einem DBMS – wie wir es in Sportmaster machen, Teil eins

Zunächst eine etwas langweilige Theorie. Was ist automatisiertes Testen? Dabei handelt es sich um Tests, die mithilfe von Software durchgeführt werden und in der modernen IT zunehmend in der Softwareentwicklung zum Einsatz kommen. Dies liegt daran, dass Unternehmen wachsen, ihre Informationssysteme wachsen und dementsprechend auch die Menge an zu testenden Funktionalitäten wächst. Die Durchführung manueller Tests wird immer teurer.

Ich habe für ein großes Unternehmen gearbeitet, dessen Veröffentlichungen alle zwei Monate herauskommen. Gleichzeitig wurde ein ganzer Monat damit verbracht, die Funktionalität von einem Dutzend Tester manuell überprüfen zu lassen. Dank der Implementierung der Automatisierung durch ein kleines Entwicklerteam konnten wir die Testzeit in anderthalb Jahren auf zwei Wochen verkürzen. Wir haben nicht nur die Testgeschwindigkeit erhöht, sondern auch die Qualität verbessert. Automatisierte Tests werden regelmäßig gestartet und führen immer den gesamten darin enthaltenen Prüfablauf durch, d. h. wir schließen den menschlichen Faktor aus.

Moderne IT zeichnet sich dadurch aus, dass ein Entwickler möglicherweise nicht nur Produktcode schreiben muss, sondern auch Unit-Tests schreiben muss, die diesen Code überprüfen.

Was aber, wenn Ihr System hauptsächlich auf Serverlogik basiert? Es gibt keine universelle Lösung oder Best Practices auf dem Markt. In der Regel lösen Unternehmen dieses Problem, indem sie ein eigenes, selbst geschriebenes Testsystem erstellen. Dies ist unser eigenes, selbst geschriebenes automatisiertes Testsystem, das im Rahmen unseres Projekts erstellt wurde, und ich werde in meinem Bericht darüber sprechen.

Unit-Tests in einem DBMS – wie wir es in Sportmaster machen, Teil eins

Loyalität testen

Lassen Sie uns zunächst über das Projekt sprechen, bei dem wir ein automatisiertes Testsystem implementiert haben. Unser Projekt ist das Sportmaster-Treuesystem (wir haben übrigens bereits darüber geschrieben). dieser Beitrag).

Wenn Ihr Unternehmen groß genug ist, verfügt Ihr Treuesystem über drei Standardeigenschaften:

  • Ihr System wird stark belastet sein
  • Ihr System wird komplexe Rechenprozesse enthalten
  • Ihr System wird aktiv verbessert.

Gehen wir der Reihe nach vor... Insgesamt haben wir, wenn wir alle Sportmaster-Marken berücksichtigen, mehr als 1000 Geschäfte in Russland, der Ukraine, China, Kasachstan und Weißrussland. Täglich werden in diesen Geschäften etwa 300 Einkäufe getätigt. Das heißt, jede Sekunde gelangen 000-3 Schecks in unser System. Natürlich ist unser Treuesystem stark ausgelastet. Und da es aktiv genutzt wird, müssen wir höchste Qualitätsstandards gewährleisten, denn jeder Fehler in der Software bedeutet große finanzielle, Reputations- und andere Verluste.

Gleichzeitig führt Sportmaster mehr als hundert verschiedene Werbeaktionen durch. Es gibt eine Vielzahl von Werbeaktionen: Es gibt Werbeaktionen für Produkte, es gibt solche, die dem Wochentag gewidmet sind, es gibt solche, die an ein bestimmtes Geschäft gebunden sind, es gibt Werbeaktionen für den Betrag des Kassenbons, es gibt Werbeaktionen für die Anzahl der Waren. Im Allgemeinen nicht schlecht. Kunden verfügen über Boni und Aktionscodes, die bei Einkäufen verwendet werden. All dies führt dazu, dass die Berechnung einer beliebigen Reihenfolge eine nicht triviale Aufgabe ist.

Der Algorithmus, der die Auftragsabwicklung implementiert, ist wirklich schrecklich und kompliziert. Und jede Änderung dieses Algorithmus ist ziemlich riskant. Es schien, dass die scheinbar unbedeutendsten Änderungen zu völlig unvorhersehbaren Auswirkungen führen konnten. Aber gerade solche komplexen Rechenprozesse, insbesondere solche, die kritische Funktionen implementieren, sind die besten Kandidaten für eine Automatisierung. Es ist sehr zeitaufwändig, Dutzende ähnlicher Fälle manuell zu prüfen. Und da der Einstiegspunkt in den Prozess unverändert bleibt, können Sie nach einer einmaligen Beschreibung schnell automatische Tests erstellen und sicher sein, dass die Funktionalität funktioniert.

Da unser System aktiv genutzt wird, will das Unternehmen etwas Neues von Ihnen, geht mit der Zeit und ist kundenorientiert. In unserem Treuesystem erscheinen Veröffentlichungen alle zwei Monate. Das bedeutet, dass wir alle zwei Monate eine vollständige Regression des gesamten Systems durchführen müssen. Gleichzeitig geht die Entwicklung natürlich, wie in jeder modernen IT, nicht sofort vom Entwickler in die Produktion über. Es entsteht im Schaltkreis des Entwicklers, durchläuft dann sukzessive den Prüfstand, die Freigabe, die Abnahme und landet erst dann in der Produktion. Zumindest müssen wir auf den Test- und Freigabekreisen eine vollständige Regression des gesamten Systems durchführen.

Die beschriebenen Eigenschaften sind Standard für fast jedes Treuesystem. Lassen Sie uns über die Funktionen unseres Projekts sprechen.

Technologisch ist die Logik unseres Loyalty-Systems zu 90 % serverbasiert und auf Oracle implementiert. In Delphi gibt es einen Client, der die Funktion eines automatisierten Arbeitsplatzadministrators übernimmt. Es gibt exponierte Webdienste für externe Anwendungen (z. B. eine Website). Daher ist es sehr logisch, dass wir, wenn wir ein automatisiertes Testsystem bereitstellen, dies auf Oracle tun.

Das Treuesystem in Sportmaster existiert seit mehr als 7 Jahren und wurde von einzelnen Entwicklern erstellt... Die durchschnittliche Anzahl der Entwickler an unserem Projekt in diesen 7 Jahren betrug 3-4 Personen. Aber im letzten Jahr ist unser Team erheblich gewachsen und jetzt arbeiten 10 Leute an dem Projekt. Das heißt, es kommen Leute zum Projekt, die mit typischen Aufgaben, Prozessen und Architektur nicht vertraut sind. Und es besteht ein erhöhtes Risiko, dass wir Fehler übersehen.

Charakteristisch für das Projekt ist das Fehlen dedizierter Tester als Stabsstellen. Natürlich gibt es Tests, aber die Tests werden von Analysten zusätzlich zu ihren anderen Hauptaufgaben durchgeführt: Kommunikation mit Geschäftskunden, Benutzern, Entwicklung von Systemanforderungen usw. usw. Trotz der Tatsache, dass die Tests von sehr hoher Qualität durchgeführt werden (dies ist besonders erwähnenswert, da einige der Analysten möglicherweise auf diesen Bericht aufmerksam werden), wurde die Wirksamkeit der Spezialisierung und Konzentration auf eine Sache nicht aufgehoben .

Unter Berücksichtigung aller oben genannten Punkte erscheint die Idee, das Testen eines Projekts zu automatisieren, um die Qualität des gelieferten Produkts zu verbessern und die Entwicklungszeit zu verkürzen, sehr logisch. Und in verschiedenen Phasen der Existenz des Treuesystems haben einzelne Entwickler Anstrengungen unternommen, ihren Code mit Unit-Tests abzudecken. Insgesamt war es ein ziemlich unzusammenhängender Prozess, bei dem jeder seine eigene Architektur und Methoden verwendete. Die Endergebnisse waren bei Unit-Tests üblich: Tests wurden entwickelt, eine Zeit lang verwendet und in einem versionierten Dateispeicher gespeichert, aber irgendwann liefen sie nicht mehr und gerieten in Vergessenheit. Dies lag zunächst daran, dass die Tests eher an einen bestimmten Darsteller und nicht an das Projekt gebunden waren.

utPLSQL kommt zur Rettung

Unit-Tests in einem DBMS – wie wir es in Sportmaster machen, Teil eins

Wissen Sie etwas über Stephen Feuerstein?

Dies ist ein kluger Kerl, der einen langen Teil seiner Karriere der Arbeit mit Oracle und PL/SQL gewidmet hat und eine ganze Reihe von Arbeiten zu diesem Thema geschrieben hat. Eines seiner berühmten Bücher heißt: „Oracle PL/SQL. Für Profis.“ Es war Stephen, der die utPLSQL-Lösung oder, wie es heißt, das Unit-Testing-Framework für Oracle PL/SQL entwickelte. Die utPLSQL-Lösung wurde 2016 erstellt, es wird jedoch weiterhin aktiv daran gearbeitet und es werden neue Versionen veröffentlicht. Die zum Zeitpunkt der Berichterstattung aktuellste Version stammt vom 24. März 2019.
Was ist es. Dies ist ein separates Open-Source-Projekt. Es wiegt ein paar Megabyte, einschließlich Beispielen und Dokumentation. Physisch handelt es sich um ein separates Schema in der ORACLE-Datenbank mit einer Reihe von Paketen und Tabellen zum Organisieren von Unit-Tests. Die Installation dauert einige Sekunden. Eine Besonderheit von utPLSQL ist seine Benutzerfreundlichkeit.
Weltweit ist utPLSQL ein Mechanismus zum Ausführen von Unit-Tests, wobei unter einem Unit-Test gewöhnliche Oracle-Batch-Prozeduren verstanden werden, deren Organisation bestimmten Regeln folgt. Zusätzlich zum Start speichert utPLSQL ein Protokoll aller Ihrer Testläufe und verfügt außerdem über ein internes Berichtssystem.

Schauen wir uns ein Beispiel dafür an, wie der Unit-Test-Code aussieht, der mit dieser Technik implementiert wurde.

Unit-Tests in einem DBMS – wie wir es in Sportmaster machen, Teil eins

Der Bildschirm zeigt also den Code für eine typische Paketspezifikation mit Unit-Tests. Was sind die zwingenden Anforderungen? Dem Paket muss „utp_“ vorangestellt werden. Alle Prozeduren mit Tests müssen genau das gleiche Präfix haben. Das Paket muss zwei Standardprozeduren enthalten: „utp_setup“ und „utp_teardown“. Das erste Verfahren wird durch einen Neustart jedes Unit-Tests aufgerufen, das zweite nach dem Start.

„utp_setup“ bereitet unser System in der Regel auf die Durchführung eines Unit-Tests vor, beispielsweise durch die Erstellung von Testdaten. „utp_teardown“ – im Gegenteil, alles kehrt zu den ursprünglichen Einstellungen zurück und setzt die Startergebnisse zurück.

Hier ist ein Beispiel für den einfachsten Unit-Test, der die Normalisierung der eingegebenen Kundentelefonnummer in die Standardform unseres Treuesystems überprüft. Es gibt keine verbindlichen Standards zum Schreiben von Prozeduren mit Unit-Tests. 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 erhaltenen Ergebnisses durch Standard-utPLSQL-Methoden erfolgt.

Ein Unit-Test kann eine beliebige Anzahl von Prüfungen umfassen. Wie aus dem Beispiel hervorgeht, führen wir vier aufeinanderfolgende Aufrufe der getesteten Methode durch, um die Telefonnummer zu normalisieren und das Ergebnis nach jedem Aufruf auszuwerten. Bei der Entwicklung eines Komponententests müssen Sie berücksichtigen, dass es Prüfungen gibt, die sich in keiner Weise auf das System auswirken, und dass Sie nach einigen Prüfungen zum ursprünglichen Zustand des Systems zurückkehren müssen.
Im vorgestellten Unit-Test formatieren wir beispielsweise einfach die eingegebene Telefonnummer, was keinerlei Auswirkungen auf das Treuesystem hat.

Und wenn wir Unit-Tests mit der Methode zum Erstellen eines neuen Clients schreiben, wird nach jedem Test ein neuer Client im System erstellt, was sich auf den späteren Start des Tests auswirken kann.

Unit-Tests in einem DBMS – wie wir es in Sportmaster machen, Teil eins

So werden Unit-Tests durchgeführt. Es gibt zwei mögliche Startoptionen: das Ausführen aller Komponententests aus einem bestimmten Paket oder das Ausführen eines bestimmten Komponententests in einem bestimmten Paket.

Unit-Tests in einem DBMS – wie wir es in Sportmaster machen, Teil eins

So sieht ein Beispiel eines internen Berichtssystems aus. Basierend auf den Ergebnissen des Unit-Tests erstellt utPLSQL einen kleinen Bericht. Darin sehen wir das Ergebnis für jede einzelne Prüfung und das Gesamtergebnis des Unit-Tests.

6 Regeln für Autotests

Bevor wir mit der Entwicklung eines neuen Systems zum automatisierten Testen des Treuesystems begannen, legten wir gemeinsam mit dem Management die Grundsätze fest, denen unsere zukünftigen automatisierten Tests entsprechen sollten.

Unit-Tests in einem DBMS – wie wir es in Sportmaster machen, Teil eins

  1. Autotests müssen effektiv und nützlich sein. Wir haben wunderbare Entwickler, die unbedingt erwähnt werden müssen, denn einige von ihnen werden diesen Bericht wahrscheinlich sehen und sie schreiben wunderbaren Code. Aber selbst ihr wunderbarer Code ist nicht perfekt und enthält, hat und wird weiterhin Fehler enthalten. Um diese Fehler zu finden, sind Autotests erforderlich. Wenn dies nicht der Fall ist, schreiben wir entweder schlechte Autotests oder wir befinden uns in einem toten Bereich, der im Prinzip nicht weiterentwickelt wird. In beiden Fällen machen wir etwas falsch und unser Ansatz ergibt einfach keinen Sinn.
  2. Es sollten Autotests verwendet werden. Es macht keinen Sinn, viel Zeit und Mühe in das Schreiben eines Softwareprodukts zu investieren, es dann in einem Repository abzulegen und es dann zu vergessen. Tests sollten durchgeführt werden, und zwar so regelmäßig wie möglich.
  3. Autotests sollten stabil funktionieren. Unabhängig von Tageszeit, Startstand und anderen Systemeinstellungen sollten Testläufe zum gleichen Ergebnis führen. Dies wird in der Regel dadurch gewährleistet, dass Autotests mit speziellen Testdaten mit festen Systemeinstellungen arbeiten.
  4. Autotests sollten mit einer für Ihr Projekt akzeptablen Geschwindigkeit funktionieren. Diese Zeit wird für jedes System individuell festgelegt. Manche Menschen können es sich leisten, den ganzen Tag zu arbeiten, während andere es für wichtig halten, dies in Sekundenschnelle zu erledigen. Welche Geschwindigkeitsstandards wir in unserem Projekt erreicht haben, erzähle ich euch etwas später.
  5. Die Autotest-Entwicklung sollte flexibel sein. Es ist nicht ratsam, den Test einer Funktionalität zu verweigern, nur weil wir dies noch nicht getan haben oder aus einem anderen Grund. utPLSQL erlegt der Entwicklung keine Einschränkungen auf und Oracle ermöglicht Ihnen grundsätzlich die Implementierung verschiedener Dinge. Für die meisten Probleme gibt es eine Lösung, es ist nur eine Frage der Zeit und Mühe.
  6. Einsatzfähigkeit. Wir haben mehrere Stände, an denen wir Tests durchführen müssen. An jedem Stand kann jederzeit ein Datendump aktualisiert werden. Es ist notwendig, ein Projekt mit automatischen Tests so durchzuführen, dass Sie die vollständige oder teilweise Installation problemlos durchführen können.

Und im zweiten Beitrag in ein paar Tagen werde ich Ihnen erzählen, was wir getan haben und welche Ergebnisse wir erzielt haben.

Source: habr.com

Kommentar hinzufügen