Mehr Effizienz beim Regressionstesten durch generisches Matching und intelligente Datenanalyse
Aus wissenschaftlichen Umfragen [1] wird deutlich, dass im Bereich der datenintensiven Systeme ein Großteil der unternehmenskritischen Prozesse nicht durch Regressionstests geschützt werden. Häufig sind Kosten- und Zeitdruck die Ursachen, was dazu führt, dass Projekte in puncto Qualität riskanter werden. Tatsächlich ist die Realisierung von Regressionstests im Bereich Datenbanken, Data-Warehouse-Systemen und Data-Vault-Systemen sehr aufwändig und komplex. Der nachfolgende Artikel beschreibt einen Ansatz, wie durch den Einsatz von generischem Matching und intelligenter Datenanalyse, Zeit und Kosten bei der Entwicklung von Regressionstest-Frameworks deutlich reduziert werden können.
„Unternehmenskritische Business-Funktionalität ist in relationalen Datenbanken implementiert. In Umfragen gaben 63,7% der Befragten an, dass dies in ihren Organisationen der Fall ist. Und dennoch hatten nur 46% der Befragten Regressionstests eingerichtet um die Logik zu testen. Da stellt sich die Frage: Sollten wir das nicht besser machen können?“
(Scott W. Ambler)
Anwendungsbereich Regressionstesten
Wie aus der Umfrage von Scott W. Ambler hervorgeht, gibt es bei der Regression einen erheblichen Verbesserungsbedarf. Dies wird bestätigt durch Erfahrungen in der eigenen Praxis und in Workshops mit Fachkollegen. Im Bereich der datenintensiven Systeme werden Regressions-Probleme nur teilweise als solche wahrgenommen. Auch wohl weil Seiteneffekte nicht ständig sondern eher nur ab zu auftreten. Daneben gibt es andere Probleme, wie z.B. das Testdaten-Problem, die mit dem Regressions-Problem um Aufmerksamkeit konkurrieren.
Ein Symptom für die mangelnde frühzeitige Kontrolle der Regression ist die späte Erkennung der Folgen von Seiteneffekten in der Anwendung oder verbundenen Liefersystemen. Also wenn Seiteneffekte als Folge von Änderungen erst von den Anwendern beim Abnahmetest entdeckt werden, anstatt im Systemtest, oder wenn Regressions-Probleme erst beim Integrationstest auffallen anstatt beim Komponententest.
Am Beispiel eines Data-Warehouse-Systems mit Liefersystemen sind deren Schnittstellen der richtige Punkt um die Regression nach Änderungen in den Liefersystemen zu testen. Hierdurch bleibt die Datenintegrität des Data-Warehouse-Systems geschützt vor Seiteneffekten von außen.
Zusammenhang mit Testdaten
Der Deckungsgrad beeinflusst die Qualität des Regressionstests.
Um einen sinnvollen Regressionstest ausführen zu können, ist eine ausreichende Qualität von Testdaten bezüglich des Deckungsgrads der Funktionalität notwendig. Was ein ausreichender Deckungsgrad ist, muss der Tester einschätzen. Idealerweise können physische Testdaten logischen Testfällen zugeordnet werden, die wiederum einen Bezug auf User-Stories, Design-Dokumente und Requirements haben.
User-Story/ Requirement/ Design/ Testfall/ Testdaten
Aber auch wenn gute Testdaten vorhanden sind, bedeutet das noch nicht, dass ein Regressionstest ausgeführt werden kann. Hierzu braucht man mindestens ein Testorakel bzw. Nullmessung eines akzeptierten Testergebnisses und das technische Know-how um beide Messungen miteinander matchen zu können.
Regressionstests erfordern Know-how beim Matchen von Soll und Ist.
Antizipation und Investition
Die Tatsache, dass Regressionstests üblicherweise nach einem Change durchgeführt werden, dessen Testergebnis (Ist) dann mit einem Soll (akzeptiertes vorheriges Testergebnis bzw. Testorakel) verglichen werden muss, erfordert ein Mindestmaß an Antizipation beim Testmanagement.
Zu viel Selbstüberschätzung bei Entwicklern verhindert Tests.
Die Vorbereitung auf einen Regressionstest bedeutet jedoch auch, dass man eine Investition tätigen muss, deren Amortisation erst in Zukunft stattfindet. Denn für einen aussagekräftigen Regressionstest ist es notwendig, den Testfall reproduzieren zu können, was in der Praxis bedeutet, dass Konfigurationen, Testdaten, Testergebnisse bzw. Testorakel wirklich gepflegt werden müssen. Hierzu ist es notwendig, das Stadium des Ad-hoc-Arbeitens zu verlassen.
Typische Arten der Ausführung
Regressionstests können zufällig, geplant, manuell oder automatisch ausgeführt werden. Wie ein Regressionstest ausgeführt wird, hängt von der Einschätzung des Testers in Bezug auf mögliche Risiken, der Einrichtung der Umgebung, Budget, Planung usw. ab.
Oft wird die Frage der Regression am Schluß den Benutzern überlassen.
- Stichprobe: Die Stichprobe ist praktisch immer mit einfachsten Mitteln möglich. Situationsabhängig kann diese Methode ausreichen. Der Nachteil ist der geringe Deckungsgrad und damit verbundenen Qualitätsrisiken.
- Prüfsumme: Die Prüfsumme kann in Fällen, in denen Zahlen aggregiert werden sehr wirksam sein, wie z.B. im Bereich der Buchhaltungssysteme; der Nachteil ist jedoch, dass nur wenige Systeme auf diese Weise getestet werden können.
- Testfallbasiert aber manuell: Übliches Verfahren in mehr traditionell wasserfallartigen Prozessen bei denen die Frequenz der Changes geringer ist. Hier ist die Testausführung noch mit sehr viel Handarbeit verbunden.
- Testfallbasiert und automatisch: Die Testausführung verläuft automatisch. Gerade im Bereich der agilen Softwareentwicklung, bei der häufig kleine Änderungen durchgeführt werden, amortisieren sich Investitionskosten relativ schnell.
Generisches Matching anstatt SQL
Beim Testen von datenintensiven Systemen wie z.B. Data-Warehouse-Systemen oder Informationssystemen ist auffallend, wie viel Zeit das Vergleichen bzw. Matchen von Daten während der Testausführung kostet. Ständig und unter großem Zeitdruck stehend werden beim Testen Ist und Soll miteinander verglichen. Typischerweise wird das Testergebniss mit dem Testorakel, einem vorherigem, bereits akzeptierten Testergebnis oder einer Nullmessung verglichen.
Das Matching ist ein Großteil des Aufwands beim Regressionstesten.
Bei zunehmender Testaktivität und häufigeren Testzyklen, verursacht durch immer kleinere und häufigere Changes bei der Entwicklung von wasserfallartigen Prozessen zu mehr Agilität, steigt der Aufwand des Matchens immer weiter an. Das Ende ist dann eine Ineffizienz beim Regressionstesten.
Herkömmliche Test-Frameworks im Datenbankbereich basieren auf SQL-Statements.
Um das Matchen zwischen Testergebnis und Testorakel bzw. einer Nullmessung zu automatisieren, bieten herkömmliche Test-Frameworks die Möglichkeit, mittels Programmierung von SQL das Testergebnis mit dem Testorakel zu vergleichen. Der Vorteil dieser Lösung ist die Möglichkeit der automatischen Ausführung von Tests, die dann z.B. auch während der Nachtzeit laufen können. Die Wiederholung eines Testlaufes ist kostengünstig. Ein Nachteil dabei ist, dass das Test-Framework SQL Quellcode enthält, der synchron neben der eigentlichen Business-Anwendung als weitere Anwendung gepflegt werden muss.
Generische Matching-Algorithmen anstatt SQL-Statements.
Eine Alternative zum Lösungsansatz bei dem SQL programmiert wird, ist die Verwendung von generischen Matching-Algorithmen beim Vergleich von Daten und Datenstrukturen wie z.B. Tabellen, Excel-Dateien, XML-Dateien usw.. Anstatt ein SQL-Statement zu schreiben, das dafür sorgt, dass Testergebnis und Testorakel verglichen werden, definiert man einfach die Daten des Testorakels und überlässt einem generischen Matching-Algorithmus die Kontrolle zwischen Testergebnis und Testorakel. Bei der Regression kann anstatt mit einem vordefinierten Testorakel auch mit einer Nullmessung gearbeitet werden. Testergebnisse eines akzeptierten Tests können dabei als Nullmessung für spätere Regressionstests dienen. Der Vorteil von generischen Matching-Algorithmen ist, dass das Test-Framework nicht programmiert werden muss.
Matchen von Daten in Datenstrukturen.
Die Anforderungen, die an einen generischen Matching-Algorithmus gestellt werden, ergeben sich aus der Praxis des Vergleichens von Daten.
- Dabei sollte der Algorithmus elastisch sein und in praktisch allen Situationen den Match zwischen Daten möglich machen. Also auch, wenn sich Daten in verschiedenen Datenstrukturen befinden, wie z.B. der Vergleich zwischen Tabellen mit teilweise unterschiedlichen Spalten bzw. XML-Files mit unterschiedlichen Tags.
- Auch sollte der Matching-Algorithmus einen Unterschied machen zwischen Daten, die identifizierbar sind und Daten, die als Mengen betrachtet werden müssen. Nicht alle Tabellen haben z.B. einen eindeutigen Schlüssel und Tabellen mit mehrfach vorkommenden Datensätzen sind schwieriger zu vergleichen.
- Der Matching-Algorithmus sollte in der Lage sein, jeden Unterschied im Detail zu finden; also Unterschiede in jeder möglichen Zelle.
- Und es sollte möglich sein, Unterschiede zur Übersicht auf höhere Niveaus in der Datenstruktur zu aggregieren; dass heißt, von den Blättern über die Äste zum Stamm im Fall von XML und von Records auf das Niveau von Tabellen im RDBMS.
Das Matchen von Daten ist basal aber nicht trivial.
Wann genau ein Match zwischen dem Testergebnis und dem Testorakel bzw. der Nullmessung erfolgreich ist, kann pro Testfall mehr oder weniger streng definiert werden, z.B.:
- Streng: Testergebnis und Testorakel sind exakt gleich.
- Weniger streng: Testorakel ist im Testergebis enthalten.
Der generische Matching-Algoritmus bietet auf jeden Fall die Informationen, die nötig sind, um den Erfolg des Regressionstests beurteilen zu können.
Intelligente Datenanalyse hilft beim Suchen
Die Verwendung eines generischen Matching-Algorithmus liefert wichtige Daten über Differenzen zwischen Testorakel bzw. Nullmessung und dem eigentlichen Testergebnis. Wie schon oben angedeutet ist das basale Finden von Unterschieden zwischen Daten nicht trivial und auch für erfahrene Analysten eine zeitraubende Angelegenheit.
Dem Finden von Unterschieden folgt die Analyse der Ursachen.
Nachdem erst einmal Unterschiede gefunden sind, schließt sich ein zweiter Schritt, nämlich die Suche nach deren Ursachen an. Hierzu ein Beispiel: Angenommen ein Analyst bzw. Tester findet beim Regressionstest von zwei Tabellen mit Zahlungsaufträgen gewisse Unterschiede. Dann wird er wahrscheinlich zuerst den Umfang der Unterschiede einschätzen: Geht es um einen einzigen Datensatz, sind es mehr oder sind es sogar alle Datensätze? Schrittweise versucht der Analyst die Ursachen der Unterschiede weiter zu bestimmen.
Schneller Rückschlüsse ziehen über Ursachen durch intelligente Datenanalyse.
Bei der Suche nach Ursachen gehen Analysten ähnlich vor, wie im Bereich Business Intelligence. Ausgehend von den Fakten, also den Unterschieden zwischen den Tabellen, betrachtet man die Unterschiede unter verschiedenen Aspekten bzw. Dimensionen, um festzustellen, ob es gehäufte Auffälligkeiten gibt. Stellt man z.B. fest, dass die Unterschiede immer dann auftreten, wenn der Zahlungsauftrag ein Auslandsauftrag ist, dann hat der Analyst einen möglichen ersten Ansatzpunkt bei der Suche nach der Ursache. Dies ist zunächst eine Hypothese, die dann durch das Entwickler-Team am Quellcode verifiziert und behoben werden kann.
Effiziente Ausführung in der Praxis
Im Bereich der datenintensiven Systeme und besonders im Fall von Data-Warehouse-Systemen, Data-Vault-Systemen und Informationssystemen stellt sich die Frage nach der praktischen Realisierung von automatischen Regressionstests. Ausgehend von User-Stories/ Requirements/ Design-Dokumenten ergeben sich Testfälle, zugehörige Testdaten und das Testorakel. Eventuell gibt es akzeptierte Testergebnisse aus vorherigen Tests.
Datenrecycling durch die Wiederverwendung von Testergebnissen bei der Regression.
Abhängig von der Testdatensituation, dem gewünschten Deckungsgrad und der Investitionsbereitschaft kann das Regressionstest-Framework auf zwei Arten eingerichtet werden:
- Mit einem vordefinierten Testorakel das z.B. in Tabellen anlegt wird. Testfälle und Testdaten sind in diesem Fall verfügbar. Diese Methode ist sehr effektiv.
- Mit einem Testorakel bzw. einer Nullmessung, dass das Testergebnis eines vorherigen akzeptierten Testergebnisses ist. Diese Methode ist sehr effizient.
Durch den generischen Matching-Algorithmus entsteht ein Regressions-Framework, das vollständig auf Daten basiert, wobei es egal ist, ob die Daten in XML, relationalen Tabellen oder anders angelegt sind. Entstehen beim Matching Unterschiede, so können deren Ursachen schnell durch intelligente Datenanalyse entdeckt werden.
Quellen
[1] Ambler, Scott W.: Agile Data, How to Regression Test a Relational Database?