Testdaten modellieren und generieren

Abgeschlossene Projekte

Projektteam: Nikolaus Moll, Thomas Fox, Christian Baranowski, Jürgen Wäsch

In jeder Anwendung, die ihren Zustand persistent in einer Datenbank speichert, müssen zum Testen der Anwendung Testdaten spezifiziert werden.  In Anwendungen mit einem komplexeren Datenmodell wird diese Modellierung meist sehr komplex, da in den Daten auch Beziehungen modelliert werden müssen. Diese Beziehungen unterliegen i.d.R. einer Menge komplexere Regeln, die sich aus der Geschäftslogik einer Anwendung ergeben.

In den Standard-Ansätzen zur Modellierung der Testdaten werden die Inhalte einzelner Datenbankzeilen spezifiziert. Dieses Vorgehen macht einerseits das Modellieren von geeigneten Testdaten schwierig, da die Befolgung aller Geschäftslogik-Regeln meist nicht trivial ist. Andererseits ist es schwierig, den modellierten Testdaten anzusehen, welche fachlichen Fälle durch sie abgedeckt werden und welche nicht.

In diesem Projekt wird eine geeignete DSL (Domain specific Language) entwickelt, die einerseits das Modellieren der Testdaten vereinfacht und andererseits die Übersicht über die abgedeckten fachlichen Fälle erleichtert. Anhand der Modellierung kann automatisch ein Vorschlag für ein Set an geeigneten Testdaten erzeugt werden. Dabei wurde besonderes Augenmerk auf die Beziehungen zwischen Entitäten gelegt.

Die erstellte DSL basiert auf der Programmiersprache Groovy; die Testdaten werden in einer Tabellenschreibweise modelliert. Diese Art der Modellierung ist übersichtlich, syntaktisch einfach und wird von IDEs (z.B. Eclipse) syntaktisch unterstützt.

Besipielsweise können in der DSL die Daten in einer Tabelle, die Professoren einer Hochschule enthält, folgendermaßen modelliert werden:

      professorTable.rows {

      REF  |  name  |  vorname |  titel  |  fakultaet
      WAESCH | "Wäsch" | "Jürgen"  | "Prof. Dr." | "Informatik"
      HAASE | "Haase" | "Oliver" | "Prof. Dr.-Ing." | "Informatik"

      }

      Dabei enthält die erste Zeile die Spaltennamen der Tabelle, die anderen Zeilen enthalten die einzufügenden Daten. Die erste Spalte einer Datenzeile enthält jeweils einen symbolischen Namen (Konstante) für den Tabelleneintrag. 

      Anforderungen an die zu generierenden Daten:

      1. Die Testdaten müssen der Datenbankstruktur entsprechen, um diese Daten überhaupt in die Datenbank einspielen zu können.
      2. Es ist für die Tests von Vorteil, wenn diese Testdaten auch den weitergehenden Anforderungen der Anwendung an die Daten entsprechen, um in den Tests realistische Szenarien abzubilden. Beispielsweise kann eine Anwendung eine 1<->1-* Beziehung zwischen zwei Entitäten definieren; in der Datenbank durch Fremdschlüssel und not-null-constraints einfach abbildbar ist jedoch nur eine 1<->0-* Beziehung. Davon ist der obige Fall zwar ein Spezialfall; dennoch gibt es Testdatensätze, die eine 1..0 Beziehung enthalten und die zwar formal der Datenbankstruktur entsprechen, aber die durch die Applikation niemals erzeugt werden können; solche Daten führen erfahrungsgemäß nicht zu realistischen Tests.
      3. Die Testdaten für einen Test sollen einerseits genügend Daten enthalten, um die fachliche Struktur der Daten zu erhalten, andererseits sollen möglichst wenig Daten erzeugt werden, damit die eingespielten Daten übersichtlich bleiben.
      4. Für die Wartbarkeit von Tests ist es von Vorteil, wenn möglichst viele Tests dieselben Testdaten verwenden. Denn sonst sind bei einer Änderung des Datenmodells viele Testdaten anzupassen, was einen großen Aufwand mit sich bringt; zudem verliert man leicht die Übersicht, welche Daten zu welchem Test gehören.

      Testdatengenerator 

      Der Testdatengenerator generiert für jede Tabelle eine konfigurierbare Mindestanzahl an Tabellenzeilen. Zusätzlich werden für jede Beziehung zwischen Tabellen die Grenzwerte modelliert: also z.B. bei einer 0..1<->0..m Beziehung folgende Beziehungen:

          Dabei werden nur Beziehungen zwischen zwei Tabellen betrachtet; es können keine expliziten Beziehungen zwischen 3 und mehr Tabellen definiert werden (Ausnahme sind m..n Beziehungen, die in der Datenbank über eine assoziative Tabelle abgebildet werden und somit technisch eine Beziehung zwischen drei Tabellen darstellen).

          STU in der Praxis

          Der Testdatengenerator wurden auf ein Datenmodell mit ca. 20 Tabellen mit wenig fachlichen Einschränkungen und ein etwas größeres Datenbankmodell mit ca. 30 Tabellen mit vielen fachlichen Einschränkungen angewendet und konnte in beiden Fällen einen konsistenten, übersichtlichen Satz an Testdaten erzeugen, der eine gute Startbasis für Tests bietet. 

          Weitere Beispiele und Quelltext

          Ein Beispielmodell und der gesamte Quelltext des DSL-Interpretors und des Testdatengenerators ist über github verfügbar.