VBA-Funktionen testen

Wenn Sie VBA-Funktionen entwickeln, sollen diese reproduzierbare und für alle übergebenen Parameterwerte korrekte Ergebnisse liefern. Manch einer testet die Funktion dann für einen Wert, erhält das gewünschte Ergebnis, erhält für einen anderen Wert ein falsches Ergebnis, ändert die Funktion … und: Irgendwann stellt sich heraus, dass diese nach den änderungen nicht mehr das korrekte Ergebnis für den eingangs verwenden Parameter liefert. Hier hilft es, wenn Sie das Entwickeln von VBA-Funktionen etwas systematischer angehen, nämlich mit organisierten Tests. Dabei testen Sie die Funktion mit allen Parameterwerten, die Ihnen einfallen und wiederholen diese Tests auch nach änderungen an der Funktion, um sicherzustellen, dass die änderung der Funktion die Ergebnisse nicht beeinflusst. Wie das gelingt, zeigen wir in diesem Artikel.

Beispieldatenbank

Die Beispiele dieses Artikels finden Sie in der Datenbank 1905_VBAFunktionenTesten.accdb.

Schnell mal programmiert

Eine VBA-Funktion ist mal mehr, mal weniger anspruchsvoll. Einfache Prozeduren, die vielleicht nur einen Datenbankaufruf kapseln sollen, brauchen kaum für viele verschiedene Fälle getestet zu werden. Aber je mehr verschiedene Eingabewerte eine Funktion hat und desto komplexer und umfangreicher die enthaltenen Anweisungen werden, umso wichtiger wäre es, während der Entwicklung der Funktion regelmäßig zu prüfen, ob diese für alle Fälle, für die sie vorgesehen ist, noch funktioniert.

Das ist insbesondere dann gefragt, wenn ein Eingabewert auftaucht, den die Funktion nicht in der gewünschten Weise verarbeitet – was bedeutet, dass sie nicht das erwartete Ergebnis liefert. Dann ändert man die Funktion so, dass sie auch auf die neuen Eingabewerte wie erwartet reagiert. Aber prüft man dann auch immer automatisch, ob die Eingabe- und Ausgabewerte, an die man die Funktion vorher angepasst hat, noch passen Das ist vielleicht nicht der Fall, und dort liegt eine mögliche Fehlerquelle.

Anhand von Funktionen möchten wir in diesem Artikel aufzeigen, wie Sie automatisierte Tests von Code aufbauen können. Das erfordert zwar auf den ersten Blick zunächst mehr Programmieraufwand, aber wenn Sie den Code später anpassen wollen, sparen Sie viel Zeit, weil alle Tests, die Sie bis dahin durchgeführt haben, nun per Mausklick erledigt werden können.

Ein Beispiel ist eine Funktion aus dem Artikel Feldinhalte aufteilen. Hier haben wir eine Funktion programmiert, mit der wir die Bestandteile einer Adressangabe, in diesem Fall Straße und Hausnummer, auf zwei Zeichenketten mit Straße und Hausnummer aufteilen wollen. Die Funktion hat die folgende Kopfzeile:

Public Function StrasseUndHausnummer(         strStrasseUndHausnummer As String, strStrasse           As String, strHausnummer As String) As Boolean

Dabei erfasst der erste Parameter die zu verarbeitende Zeichenkette, der zweite und dritte liefert das Ergebnis der Funktion zurück. Der Rückgabewert gibt als Boolean-Wert an, ob die Funktion überhaupt ordnungsgemäß funktioniert hat.

Das ist eine Form, mit der wir beim automatisierten Testen gut arbeiten können. Wenn die Funktion nur einen Rückgabewert hat und nicht wie in diesem Fall gleich zwei beziehungsweise drei, können Sie den Rückgabewert auch direkt als Funktionswert zurückgeben.

Wir wollen die Funktion nun mit verschiedenen Aufrufen testen, wobei wir immer andere Kombinationen aus Straßenname und Hausnummer übergeben:

  • Straße und Hausnummer mit Leerzeichen dazwischen,
  • Straßen, die bereits Leerzeichen im Straßennamen enthalten,
  • Straße und Hausnummer, bei denen zwischen dem Punkt von “Str.” und der Hausnummer kein Leerzeichen ist oder auch
  • Straßen, bei denen die Hausnummer selbst Leerzeichen enthält (2 a).

Wenn wir eine Funktion erstellen wollen, die all diese Konstellationen wie gewünscht verarbeitet, müssen wir in der Funktion entsprechend viele Fälle berücksichtigen. Und um sicherzustellen, dass man beim Anpassen der Funktion auf einen neuen Fall auch die anderen Fälle noch berücksichtigt, sollte man alle bekannten Fälle nach jeder änderung nochmals prüfen.

Ich schreibe bewusst von “allen bekannten Fällen”, denn der Benutzer ist gnadenlos und wird Möglichkeiten finden, um Ihre Funktion zum Versagen zu bringen. Doch das ist dann nur eine weitere Aufgabe, die es zu lösen gilt und das ist viel einfacher, wenn man wie nachfolgend beschrieben Testroutinen für die zu erstellende Funktion programmiert hat.

Einfach testen

Am einfachsten testet man, indem man die Funktion schlicht mit dem zu untersuchenden Parameterwert aufruft und die Rückgabewerte der Funktion auf Richtigkeit überprüft. Liefert die Funktion die erwarteten Werte zurück, braucht nichts weiter zu geschehen. Wenn diese jedoch andere Werte als erwartet liefert, sollte man durch eine Meldung oder durch eine Ausgabe im Direktbereich darauf hingewiesen werden.

Wie kann das aussehen Im Fall der Funktion StrasseUndHausnummer sieht ein einfacher Test so aus wie in Listing 1. Hier prüfen wir zunächst, ob der Aufruf der Funktion den Wert True zurückliefert. Falls ja, prüfen wir, ob die beiden Rückgabeparameter strStrasse und strHausnummer die erwarteten Werte enthalten. Wenn dies zutrifft, geschieht nichts weiter – falls nein, erscheint eine Ausgabe, welche die erwarteten Werte sowie die tatsächlich gelieferten Werte ausgibt:

<font color=blue>Public Sub </font>Test_StrasseUndHausnummer()
     <font color=blue>Dim </font>strStrasseUndHausnummer<font color=blue> As String</font>
     <font color=blue>Dim </font>strStrasse<font color=blue> As String</font>
     <font color=blue>Dim </font>strHausnummer<font color=blue> As String</font>
     strStrasseUndHausnummer = "Gerichtsstr. 27"
     <font color=blue>If </font>StrasseUndHausnummer(strStrasseUndHausnummer, strStrasse, strHausnummer) = <font color=blue>True</font><font color=blue> Then</font>
         <font color=blue>If </font><font color=blue>Not</font> (strStrasse = "Gerichtsstr." And strHausnummer = "27")<font color=blue> Then</font>
             <font color=blue>Debug.Print</font> "Aufruf mit Parameter '" & strStrasseUndHausnummer & "' fehlgeschlagen."
             <font color=blue>Debug.Print</font> "Erwartet: 'Gerichtsstr.' Geliefert: '" & strStrasse & "'"
             <font color=blue>Debug.Print</font> "Erwartet: '27' Geliefert: '" & strHausnummer & "'"
         <font color=blue>End If</font>
     <font color=blue>Else</font>
         <font color=blue>Debug.Print</font> "Funktionsaufruf mit Parameter '" & strStrasseUndHausnummer & "' nicht erfolgreich."
     <font color=blue>End If</font>
End Sub

Listing 1: Erster Entwurf einer Prozedur zum Testen einer Funktion

Aufruf mit Parameter 'Gerichtsstr. 27 a' fehlgeschlagen.
Erwartet: 'Gerichtsstr.' Geliefert: 'Gerichtsstr. 27'
Erwartet: '27' Geliefert: 'a'

Weitere Testfälle hinzufügen

Möchten Sie weiterlesen? Dann lösen Sie Ihr Ticket!
Hier geht es zur Bestellung des Jahresabonnements des Magazins Access [basics]:
Zur Bestellung ...
Danach greifen Sie sofort auf alle rund 400 Artikel unseres Angebots zu - auch auf diesen hier!
Oder haben Sie bereits Zugangsdaten? Dann loggen Sie sich gleich hier ein:

Schreibe einen Kommentar