{"id":55000235,"date":"2004-10-01T00:00:00","date_gmt":"2023-02-10T14:50:20","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=235"},"modified":"2024-02-19T08:17:41","modified_gmt":"2024-02-19T08:17:41","slug":"testgetriebene_entwicklung_mit_access","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/testgetriebene_entwicklung_mit_access\/","title":{"rendered":"Testgetriebene Entwicklung mit Access"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg06.met.vgwort.de\/na\/aa4cb9507fcc46ce954cfe465386ec91\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>Andr&eacute; Minhorst, Duisburg und Uwe Sch&auml;fer, Essen<\/b><\/p>\n<p><b>Die Schlagw&ouml;rter Extreme Programming (XP), Unit-Testing, Test Driven Development, Refactoring oder Pair Programming geistern durch die Entwicklerwelt. Dabei ist Extreme Programming der Oberbegriff f&uuml;r die anderen und fasst diese und mehr zu einer neuartigen Philosophie der Softwareentwicklung zusammen. Ziel der dahinter stehenden Konzepte sind Projekte, die von kleinen Entwicklerteams durchgef&uuml;hrt werden. Da die meisten Leser dieses Beitrags vermutlich allein entwickeln, stellt dieser Beitrag ein elementares Konzept von XP heraus: das Test Driven Development (TDD), zu deutsch testgetriebene Entwicklung.<\/b><\/p>\n<p>Extreme Programming ist ein Thema, mit dem man leicht mehrere hundert Seiten f&uuml;llen k&ouml;nnte &#8211; wenn man nur die theoretischen Aspekte ber&uuml;cksichtigt.<\/p>\n<p>Da dieser Platz leider nicht zur Verf&uuml;gung steht, greifen wir die Teilbereiche auf, die auch Ein-Mann-Teams bei der Entwicklung von Access-Datenbanken Gewinn bringend nutzen k&ouml;nnen. Der Kern ist die &#8222;testgetriebene Entwicklung&#8220;, eng damit verbunden sind die Begriffe &#8222;Unit Test&#8220; und &#8222;Refactoring&#8220;.<\/p>\n<p>Der vorliegende Beitrag soll m&ouml;glichst praxisnah die Vorteile der testgetriebenen Entwicklung beschreiben. Dennoch sind einige einf&uuml;hrende Worte erforderlich.<\/p>\n<h3>Hinweis<\/h3>\n<p>Im Internet und in der Literatur finden Sie eine Menge theoretischer Abhandlungen &uuml;ber diesen Themenkomplex. Wir m&ouml;chten Ihnen neben den theoretischen Grundlagen ein Tool vorstellen, das Sie f&uuml;r die testgetriebene Entwicklung mit Access einsetzen k&ouml;nnen; au&szlig;erdem lernen Sie, wie Sie dieses installieren und wie Sie Ihre ersten Schritte mit der testgetriebenen Entwicklung durchf&uuml;hren. <\/p>\n<h2>Test a little, code a little<\/h2>\n<p>Diese Entwicklungsmethode erfordert vom Programmierer eine Menge Disziplin, da sie voraussetzt, dass f&uuml;r jede Funktion einer Anwendung zun&auml;chst ein Test geschrieben wird.<\/p>\n<p>Damit Sie sehen, ob der Test funktioniert &#8211; was der erste und wichtigste Schritt bei der testgetriebenen Entwicklung ist &#8211; schreiben Sie einen Test, der beim ersten Start scheitert.<\/p>\n<p>Erst dann implementieren Sie die eigentliche Funktion.<\/p>\n<p>Durch erneuten Start des Tests wird dann verifiziert, dass die Implementierung den Anforderungen des Tests gen&uuml;gt, dieser also nicht mehr fehlschl&auml;gt.<\/p>\n<h3>Hinweis<\/h3>\n<p>Schreiben Sie niemals mehr als einen neuen Test gleichzeitig! Vermutlich kennen Sie das Problem, Funktionen zu einer Anwendung hinzuf&uuml;gen oder &auml;ndern zu wollen, die Anpassungen an mehr als einer Stelle erfordern. Die wiederum beeinflussen andere Programmfunktionen oder machen diese gar untauglich. Wenn Sie jeweils nur einen Test gleichzeitig hinzuf&uuml;gen oder &auml;ndern, halten Sie auch den durch diese Anforderungen verursachten Aufwand minimal. <\/p>\n<h3>Kleine Schritte, einfache Wege<\/h3>\n<p>Jeder Test soll auf m&ouml;glichst einfache Weise erf&uuml;llt werden. Wenn ein Test fordert, dass eine Funktion den Eingangswert &#8222;andr&eacute;&#8220; in die Zeichenkette &#8222;Andr&eacute;&#8220; umwandelt, dann schreiben Sie einfach eine Funktion, die den gew&uuml;nschten Wert hartcodiert zur&uuml;ckgibt &#8211; das reicht f&uuml;r den ersten Ansatz, denn damit ist ja der erste Test bestanden! Wenn der zweite Test die Umwandlung eines zweiten, anderen Wertes einfordert, m&uuml;ssen Sie die Funktion nat&uuml;rlich anpassen, was Sie in dem Fall leicht mit einer bestimmten VB-Funktion tun k&ouml;nnen. Auf diese Weise stellen Sie sicher, dass die Definition der Anforderungen (durch den Test) m&ouml;glichst vollst&auml;ndig ist und nicht von Ihrem Verst&auml;ndnis der Implementierung abh&auml;ngt.<\/p>\n<h3>Einmal testen, immer testen<\/h3>\n<p>Nat&uuml;rlich bringt das ganze Testen nicht viel, wenn Sie einen Test nach erfolgreichem Bestehen aus den Augen verlieren und sich direkt dem n&auml;chsten Test zuwenden.<\/p>\n<p>Deshalb f&uuml;gen Sie jeden neuen Test zu den bereits erf&uuml;llten Tests hinzu und f&uuml;hren mit jedem neuen Test alle bestehenden Tests erneut durch. Auf diese Weise stellen Sie sicher, dass bereits erf&uuml;llte Anforderung durch neuen Code oder Code&auml;nderungen unber&uuml;hrt bleiben.<\/p>\n<h3>Hinweis<\/h3>\n<p>Unit-Testing-Frameworks wie accessUnit bieten durch so genannte Testsuites die M&ouml;glichkeit, Tests nach beliebigen Gesichtspunkten zusammenzufassen. So k&ouml;nnen Sie etwa alle Tests, die nicht den gerade in Arbeit befindlichen Code betreffen, zusammenfassen und beispielsweise einmal am Tag ausf&uuml;hren, um unvorhergesehene Defekte der Software fr&uuml;hzeitig zu erkennen. Die Tests, auf deren Basis Sie gerade entwickeln, fassen Sie ebenfalls zusammen. Da Sie damit h&auml;ufig testen (was dem Grundprinzip der testgetriebenen Entwicklung entspricht), sollten diese Test m&ouml;glichst schnell abgearbeitet werden. Je schneller ein Test abl&auml;uft, desto geringer ist die Wahrscheinlichkeit, dass Sie ihn einmal aus &#8222;Zeitnot&#8220; auslassen. <\/p>\n<h2>Automatisierung ist Trumpf<\/h2>\n<p>Nach den ersten Abschnitten fragen Sie sich vermutlich wie jeder andere, der sich erstmalig mit dieser Thematik auseinandersetzt, wie die Tests &uuml;berhaupt ablaufen. Die Antwort ist: Sie werden &#8211; genau wie normale Anwendungen auch &#8211; programmiert, und zwar als Abfolge von Pr&uuml;fungen bestimmter Ausdr&uuml;cke.<\/p>\n<p>Wenn Sie beispielsweise eine Funktion testen m&ouml;chten, die zwei Zahlen addiert, dann vergleichen Sie einfach das Ergebnis dieser Funktion mit dem zu erwartenden Ergebnis. Und damit Sie sich nur um die Festlegung dieser Tests und die Eingabe der erwarteten Ergebnisse k&uuml;mmern m&uuml;ssen, gibt es so genannte Test-Frameworks. Mehr dar&uuml;ber erfahren Sie sp&auml;ter im praktischen Teil dieses Beitrags.<\/p>\n<h2>Refactoring &#8211; alles bleibt besser<\/h2>\n<p>Der Begriff &#8222;Refactoring&#8220; ist eng mit der testgetriebenen Entwicklung verbunden. Refactoring ist eine Ver&auml;nderung, Anpassung oder Verbesserung des Designs. Dabei m&uuml;ssen nat&uuml;rlich bestehende, durch Tests definierte Anforderungen auch nach dem Refactoring noch erf&uuml;llt werden.<\/p>\n<p>Ein Ad-hoc-Programmierstil, der aus dem immer h&ouml;heren Zeit- und Erfolgsdruck entsteht und m&ouml;glicherweise auch im ersten Schritt zu einer lauff&auml;higen Anwendung f&uuml;hrt, garantiert gro&szlig;en Aufwand, wenn nachtr&auml;glich zu behebende Fehler und\/oder sich w&auml;hrend der Entwicklung &auml;ndernde Anforderungen auftreten; auch die nachtr&auml;gliche Optimierung einer Anwendung, die nicht die gew&uuml;nschte Performance aufweist, f&uuml;hrt sicher zu Kopfschmerzen beim Entwickler(team).<\/p>\n<p>Die testgetriebene Entwicklung bietet wesentlich mehr M&ouml;glichkeiten, den bestehenden Code ohne Angst anzufassen: n&auml;mlich immer, wenn alle bis dato vorhandenen Tests zuverl&auml;ssig laufen. Da Sie mit jedem Testlauf den neuen und alle bereits bestehenden Tests durchf&uuml;hren, erfahren Sie nicht nur, ob der neue Test erfolgreich ist oder scheitert, sondern auch, ob alles andere noch wie gew&uuml;nscht funktioniert.<\/p>\n<p>So k&ouml;nnen Sie den bestehenden und regelm&auml;&szlig;ig getesteten Code nach Lust und Laune refaktorisieren, solange &#8211; ja, solange die &auml;nderungen nicht bewusst ein anderes Ergebnis f&uuml;r einen beliebigen Test zur&uuml;ckliefern sollen. Das fiele dann nicht mehr unter den Begriff &#8222;Refactoring&#8220;; statt dessen hei&szlig;t die Devise: Erst den Test schreiben beziehungsweise anpassen und dann die Funktionalit&auml;t &auml;ndern.<\/p>\n<p>Wenn Sie beispielsweise einen Vorgang, der in mehreren getesteten Routinen auftritt, in eine eigene Funktion auslagern und von den jeweiligen Routinen aus aufrufen m&ouml;chten, k&ouml;nnen Sie das nat&uuml;rlich, ohne die Tests zu &auml;ndern, denn Sie lagern ja nur ein paar Zeilen in eine Funktion aus (Mathematiker w&uuml;rden hier von &#8222;Ausklammern&#8220; sprechen).<\/p>\n<p>Noch besser w&auml;re allerdings, Sie w&uuml;rden vorher Tests schreiben, welche die ausgelagerte Funktion auf Herz und Nieren pr&uuml;fen. Damit w&auml;ren Sie wieder bei der kleinsten Einheit &#8211; der &#8222;Unit&#8220;.<\/p>\n<h2>Unit Test &#8211; was hei&szlig;t das<\/h2>\n<p>Der Begriff &#8222;Unit Test&#8220; ist so eng mit der testgetriebenen Entwicklung verkn&uuml;pft, weil beide sich auf die kleinstm&ouml;gliche Einheit beziehen. Wenn Sie kleinste Einheiten testen m&ouml;chten, dann ist damit nicht eine Anwendung, auch kein Teil einer Anwendung wie ein Formular oder eine Klasse gemeint, sondern ein elementarer Bestandteil davon &#8211; eine Eigenschaft, eine Methode oder ein Ereignis, kurz: die &#8222;Unit under Test&#8220;.<\/p>\n<p>Je kleiner die Einheiten sind, die Sie testen, desto schneller und leichter finden Sie fehlerhafte Stellen. Zumindest aber sollte es f&uuml;r jede testbare Schnittstelle Ihrer Klassen und Objekte einen oder mehrere Tests geben, die deren Funktionalit&auml;t jederzeit sicherstellen k&ouml;nnen. Nur auf diese Weise k&ouml;nnen Sie sich auf das im vorherigen Abschnitt beschriebene &#8222;Refactoring&#8220; st&uuml;rzen.<\/p>\n<h2>Alles auf einmal<\/h2>\n<p>Bei jeder gr&ouml;&szlig;eren &auml;nderung oder Erweiterung sollten Sie alle vorhandenen Tests Ihrer Anwendung durchf&uuml;hren. Wichtig ist, dass jeder Aspekt Ihrer Anwendung f&uuml;r sich allein testbar ist, und zwar in beliebiger Reihenfolge, um Wechselwirkungen auszuschlie&szlig;en.<\/p>\n<h2>Dummys<\/h2>\n<p>Nat&uuml;rlich k&ouml;nnen Sie mit der testgetriebenen Entwicklung nicht nur Einheiten, sondern auch deren Interaktion testen &#8211; man spricht hier von Integrationstests. Das entspricht allerdings nicht dem Grundprinzip der testgetriebenen Entwicklung. Um dennoch die Wechselwirkung zwischen Klassen testen zu k&ouml;nnen, verwendet man verschiedene Arten von Dummies.<\/p>\n<p>Das Testen ohne Wechselwirkung ist in manchen F&auml;llen nicht so einfach, da auch die Interaktion zwischen Klassen getestet werden muss. Dabei gibt es zwei Varianten:<\/p>\n<li>Im ersten Fall ben&ouml;tigt die erste Klasse eine Eigenschaft oder Funktion der zweiten Klasse, um einen bestimmten Wert zu ermitteln. Im Idealfall l&auml;sst sich die zweite Klasse dabei durch eine Dummy-Implementierung ersetzen, die den gew&uuml;nschten Wert liefert &#8211; dabei handelt es sich um einen so genannten &#8222;Stub&#8220;. Im zweiten Fall l&ouml;st die Interaktion der beiden Klassen die &auml;nderung einer Eigenschaft oder Verhaltensweise der zweiten Klasse aus, die f&uuml;r den Test der ersten Klasse wichtig ist. Will man f&uuml;r die zweite Klasse einen Dummy verwenden, reicht es nicht aus, wenn dieser einfach auf Anfrage einen bestimmten Wert liefert. Statt dessen muss man die Auswirkung der Interaktion zwischen den Klassen pr&uuml;fen k&ouml;nnen. Ein solcher Dummy ist ein wenig komplizierter und hei&szlig;t in der Fachsprache &#8222;Mock&#8220;.<\/li>\n<h3>Hinweis<\/h3>\n<p>Mocks und Stubs werden im Rahmen dieses Beitrags nicht weiter erl&auml;utert. <\/p>\n<h2>Testdaten<\/h2>\n<p>Elementar wichtig f&uuml;r Tests sind Testdaten. Optimal w&auml;re nat&uuml;rlich ein &#8222;echter&#8220; Testdatenbestand; wenn es sich um eine neue Anwendung handelt, ist dieser aber in der Regel nicht verf&uuml;gbar. Um f&uuml;r alle Tests die gleiche Ausgangsposition zu schaffen, sollten Sie die vorhandenen Daten vorher auf einen fest definierten Stand bringen &#8211; am besten jedes Mal neu.<\/p>\n<p>Dazu gibt es zwei M&ouml;glichkeiten:<\/p>\n<li>Sie erstellen die Daten mit jedem Test durch geeignete SQL-Skripte neu und l&ouml;schen diese anschlie&szlig;end wieder. Testframeworks enthalten geeignete Methoden, um die notwendigen Anweisungen unterzubringen.<\/li>\n<li>Wenn die zu entwickelnden Klassen selbst Methoden enthalten, um die notwendigen Daten anzulegen, stellen Sie die Testdaten doch einfach im Rahmen der Tests der entsprechenden Klassen zusammen! Vermutlich finden sich auch Methoden zum L&ouml;schen von Daten in den Klassen, die Sie zum Entfernen der Testdaten verwenden k&ouml;nnen.<\/li>\n<h2>Zusammenspiel und Vorz&uuml;ge<\/h2>\n<p>Die vorhergehenden Abschnitte machen bereits deutlich, dass testgetriebene Entwicklung, Unit Tests und Refactoring ein eingespieltes &#8222;Team&#8220; sein m&uuml;ssen, wenn sie zum Erfolg f&uuml;hren sollen.<\/p>\n<p>Zusammengefasst haben Sie die folgenden Vorz&uuml;ge kennen gelernt:<\/p>\n<li>Vorausschauend planen: Wenn Sie vor jedem Programmierschritt einen Test erstellen, setzen Sie sich intensiver mit dem Ziel ausei-nander.<\/li>\n<li>Die Wahrscheinlichkeit, nach der Erstellung einigen Codes festzustellen, dass Sie eigentlich am Ziel vorbeiprogrammiert haben, ist geringer.<\/li>\n<li>Schritt f&uuml;r Schritt statt Entwicklung im Multitasking-Stil: Erst wenn der vorherige Test positiv ausf&auml;llt (und die damit verbundene Code-&auml;nderung keine &auml;lteren Tests scheitern l&auml;sst), d&uuml;rfen Sie einen neuen Test und neue Funktionalit&auml;t hinzuf&uuml;gen. Vorteil: Sie arbeiten immer nur an einer Baustelle; wenn ein oder mehrere Tests durch neuen Code fehlschlagen, wissen Sie sofort, woran es liegt.<\/li>\n<li>Absicherung: Dadurch, dass Sie mit jedem neuen Test auch alle anderen Tests ausf&uuml;hren, sind Sie immer sicher, dass Sie durch Hinzuf&uuml;gen neuer Funktionen oder Refactoring nichts Funktionierendes zerst&ouml;ren.<\/li>\n<li>Durch den automatisierten Ablauf der Tests k&ouml;nnen Sie sich jederzeit davon &uuml;berzeugen, dass noch alles entsprechend der Spezifikation funktioniert.<\/li>\n<li>Hinzu kommen die folgenden Vorteile:<\/li>\n<li>Mit jedem Test stellen Sie sich eine neue Aufgabe, die Sie schnell erf&uuml;llen k&ouml;nnen &#8211; au&szlig;er, Sie haben den Anspruch an den Test zu hoch angesetzt.<\/li>\n<li>Sie haben eine Menge kleiner Erfolgserlebnisse.<\/li>\n<li>Sie k&ouml;nnen jederzeit, wenn Sie einen Test erfolgreich durchgef&uuml;hrt haben, Pause oder Feierabend machen in dem Gef&uuml;hl, dass die Anwendung im aktuellen Zustand wie gew&uuml;nscht l&auml;uft.<\/li>\n<li>Tests sind eine sehr genaue Formulierung von Anfordungen. Sie k&ouml;nnen mit ihnen sehr schnell feststellen, ob die tats&auml;chlichen Anforderungen umgesetzt wurden.<\/li>\n<li>Tests sind Dokumentation: Wenn Sie f&uuml;r alle Methoden, Eigenschaften und Ereignisse einer Klasse Tests schreiben, k&ouml;nnen Entwickler, die sich anschlie&szlig;end mit Weiterentwicklungen oder &auml;nderungen der Anwendung besch&auml;ftigen, diese Tests als Dokumentation heranziehen.<\/li>\n<p>Nachdem die theoretischen Grundlagen Ihr Interesse geweckt haben, lernen Sie nun den praktischen Ablauf kennen.<\/p>\n<p>Dazu sind einige Vorbemerkungen erforderlich: Die testgetriebene Entwicklung wurde zuerst in Zusammenhang mit objektorientierten Sprachen eingesetzt. Sie k&ouml;nnen diese Entwicklungsmethode nat&uuml;rlich auch f&uuml;r die Entwicklung mit prozeduralen Sprachen heranziehen. Es ist aber zu empfehlen, sich direkt mit der objektorientierten Entwicklung im Rahmen der M&ouml;glichkeiten von VBA auseinanderzusetzen (s. Beitrag Objektorientierte Entwicklung mit Access).<\/p>\n<p>Die meisten Quellen zum Thema testgetriebene Entwicklung enthalten in der Regel keine Hinweise zum Testen von Benutzeroberfl&auml;chen. In gewisser Weise k&ouml;nnen Sie die testgetriebene Entwicklung aber dennoch dazu verwenden: Formulare, die ja den gr&ouml;&szlig;ten Teil der Benutzeroberfl&auml;che ausmachen, sind eigentlich ebenfalls Objekte mit Methoden, Eigenschaften und Ereignissen. Der einzige Unterschied zu einem aus einer herk&ouml;mmlichen Klasse erzeugten Objekt ist, dass es eine Benutzeroberfl&auml;che hat. Wie Sie Formulare testgetrieben entwickeln, erfahren Sie in einem der Update-Magazine zu diesem Werk.<\/p>\n<h2>Das Werkzeug: accessUnit<\/h2>\n<p>Die Werkzeuge zum Durchf&uuml;hren von Unit Tests hei&szlig;en Testframework. Die Namen der entsprechenden Testframeworks f&uuml;r die unterschiedlichen Programmiersprachen sind immer nach dem gleichen Muster aufgebaut und enden auf Unit. F&uuml;r Java gibt es unter anderem JUnit, f&uuml;r .NET NUnit und f&uuml;r Visual Basic vbUnit. Das nachfolgend vorgestellte Testframework ist einer der j&uuml;ngeren Vertreter, aber &auml;hnlich aufgebaut wie die anderen: accessUnit.<\/p>\n<h3>Hinweis<\/h3>\n<p>Sie finden die bei Drucklegung aktuelle Version von accessUnit auf der beiliegenden CD. Um neuere Versionen und Update-Informationen zu erhalten, besuchen Sie einfach im Internet die Seite www.accessunit.de. <\/p>\n<p>accessUnit bietet eine grafische Benutzeroberfl&auml;che zur Darstellung des Ablaufs der Tests sowie der im Anschluss vorliegenden Testergebnisse (s. Abb. 1).<\/p>\n<h3>Hinweis<\/h3>\n<p>Das Testframework accessUnit funktioniert in der zum Zeitpunkt der Drucklegung dieses Textes vorliegenden Version mit Access 2000 und h&ouml;her. <\/p>\n<p><IMG height=\"382\" src=\"..\/fileadmin\/_temp_\/{AABFE1CC-8D7A-4C68-A61F-3AB4D4DA36D5}\/pic001.png\" width=\"458\" border=\"0\"><\/p>\n<p><b><\/b><\/p>\n<p><b>Abb. 1: Das Testframework accessUnit im Einsatz<\/b><\/p>\n<h2>Installation von accessUnit<\/h2>\n<p>accessUnit liegt in Form eines Formulars, eines Makros und einiger Klassenmodule vor, die in der Datenbankdatei accessUnit.mdb zu finden sind.<\/p>\n<p>Sie k&ouml;nnen das Unit-Testing-Framework nachtr&auml;glich in eine Datenbank einbinden oder eine neue Datenbank damit entwickeln.<\/p>\n<p>Im ersten Fall importieren Sie einfach alle Objekte der Datenbank accessUnit.mdb in die Zieldatenbank. Das Framework steht dann sofort zur Verf&uuml;gung.<\/p>\n<p>Falls Sie eine neue Datenbank mit Hilfe des Unit-Testing-Frameworks entwickeln m&ouml;chten, erstellen Sie einfach eine Kopie der Datenbank accessUnit.mdb und speichern Sie diese unter dem gew&uuml;nschten Namen.<\/p>\n<h2>Elemente von accessUnit<\/h2>\n<p>Vor dem ersten Beispiel sollen Sie noch kurz die wichtigsten Elemente des accessUnit-Frameworks kennen lernen.<\/p>\n<p>Die Benutzeroberfl&auml;che besteht aus dem Formular frmTestrunner, das eine Schaltfl&auml;che zum Starten der Tests und Steuerelemente zur Ausgabe der Testergebnisse liefert.<\/p>\n<pre>Option Compare Database\nOption Explicit\nPublic Sub Suite(objTestsuite As Object)\n    objTestsuite.AddTest New clsSampleTest\nEnd Sub<\/pre>\n<p><b>Quellcode 1<\/b><\/p>\n<pre>Public Function TestsuiteWrapper(strTestsuitename _    As String) As Object\n    Select Case strTestsuitename\n        Case \"clsTestsuite\"\n            Set TestsuiteWrapper = New clsTestsuite\n    End Select\nEnd Function<\/pre>\n<p><b>Quellcode 2<\/b><\/p>\n<pre>Option Compare Database\nOption Explicit\nPublic Sub Setup()\nEnd Sub\nPublic Sub Teardown()\nEnd Sub\nPublic Property Get Fixturename() As String\n    Fixturename = \"clsSampleTest\"\nEnd Property\nPublic Sub Test1(objTestcase As aUTestcase)\n    On Error GoTo RunTest_Err\n    objTestcase.Assert \"Sample assertion 1a\", True\n    objTestcase.Assert \"Sample assertion 1b\", True\n    Exit Sub\nRunTest_Err:\n    objTestcase.Assert \"#Error in \" & Me.Fixturename, False\n    Resume Next\nEnd Sub<\/pre>\n<p><b>Quellcode 3<\/b><\/p>\n<p>Charakteristisch f&uuml;r Unit-Testing-Frameworks mit Benutzeroberfl&auml;che ist dabei je nach Testergebnis die Anzeige eines roten oder gr&uuml;nen Balkens. Der rote Balken bringt in der Regel eine oder mehrere Meldungen mit sich, die auf den oder die gescheiterten Tests hinweisen.<\/p>\n<p>Das in der Datenbank enthaltene Autoexec-Makro enth&auml;lt eine Anweisung, die der VBA-Entwicklungsumgebung ein Men&uuml; mit einer Schaltfl&auml;che zum Aufrufen des Testrunner-Formulars hinzuf&uuml;gt. So k&ouml;nnen Sie den Testrunner komfortabel von dort aus aktivieren.<\/p>\n<p>Neben dem Formular und dem Makro ben&ouml;tigt das Framework einige Module mit der Funktionalit&auml;t: das Standardmodul aUMenu und die Klassenmodule aUMenuEvents, aUModule, aUTestcase, aUTestsuite und aUTestsuites. Die Modulnamen enthalten das Pr&auml;fix aU, um die accessUnit-Module leicht von den anderen Modulen unterscheiden zu k&ouml;nnen.<\/p>\n<p>Die &uuml;brigen Klassen der Datenbank accessUnit.mdb beinhalten die Tests. Sie ben&ouml;tigen auf jeden Fall eine Testsuite.<\/p>\n<p>Sie enth&auml;lt die Aufrufe der einzelnen Testcases, die in eigenen Klassen untergebracht sind. Eine solche Testsuite-Klasse sieht etwa wie in Quellcode 1 aus.<\/p>\n<p>Eine Testsuite enth&auml;lt nur eine Methode namens Suite. Diese Methode f&uuml;gt der Testsuite mit der AddTest-Methode eine oder mehrere Testklassen hinzu.<\/p>\n<p>Die Testsuite dieses Beispiels sorgt f&uuml;r die Ausf&uuml;hrung der in dem Klassenmodul clsSampleTest enthaltenen Tests. <\/p>\n<p>Damit Sie eine Testsuite &uuml;ber den Testrunner aufrufen k&ouml;nnen, m&uuml;ssen Sie einen Eintrag wie in dem Code aus Quellcode 2 in der Klasse aUTestsuites anlegen.<\/p>\n<p>Fehlt noch der eigentliche Test. Jeder Test wird in einer Testklasse untergebracht. Eine einfache Testklasse sieht wie in Quellcode 3 aus.<\/p>\n<p>Einen Test bringt man in je einer Methode unter, deren Methodenname mit &#8222;Test&#8220; beginnen muss. Ein Test besteht aus einer oder mehreren Assertions (deutsch: Absicherung), die Werte von (Funktions-)Methoden oder Eigenschaften der zu testenden Klasse &uuml;berpr&uuml;fen. Eine Assertion hat zwei Parameter: eine aussagekr&auml;ftige Bezeichnung dessen, was getestet wird, sowie einen Bool&#8220;schen Ausdruck als Ergebnis der Assertion.<\/p>\n<p>Ein oder mehrere Tests, die sich in der gleichen Testklasse befinden und denselben Aspekt einer Klasse testen &#8211; etwa eine Methode oder Eigenschaft -, nennt man Testcase.<\/p>\n<p>Die verschiedenen Tests einer Testklasse erfordern h&auml;ufig die gleiche Startkonfiguration, und wenn es sich nur um das Instanzieren der zu testenden Klasse handelt. Oft kommen noch weitere Vorbereitungen wie beispielsweise das Anlegen von Testdaten hinzu. Damit man die entsprechenden Anweisungen nicht in jede einzelne Test-Methode einbauen muss, verwenden alle Tests einer Testklasse eine gemeinsame Methode, die alle notwendigen Vorbereitungen enth&auml;lt. Diese Methode hei&szlig;t Setup.<\/p>\n<p>Die vor und w&auml;hrend des Testens angefallenen Testdaten sollen auch wieder entfernt werden, was in einer Methode passiert, die automatisch nach der Ausf&uuml;hrung jeder einzelnen Testmethode aufgerufen wird: die Methode Teardown. Diese beiden Methoden nennt man zusammenfassend &#8222;Fixture&#8220;.<\/p>\n<p>Als Beispielanwendung erstellen wir nachfolgend eine Klasse, die zur Kontrolle und gegebenenfalls zur Korrektur der Gro&szlig;- und Kleinschreibung von Namen dient. Sie soll sicherstellen, dass ein eingegebener Benutzername einen f&uuml;hrenden Gro&szlig;buchstaben und nachfolgend klein geschriebene Buchstaben enth&auml;lt. Die Methode soll also beispielsweise die Eingabe andR&eacute; in Andr&eacute; umwandeln.<\/p>\n<p>Desweiteren soll die Methode Capitalize hei&szlig;en und in einer Klasse namens clsStringfunctions enthalten sein. Die Klasse erh&auml;lt diesen Namen, weil sp&auml;ter vielleicht noch weitere Zeichenkettenfunktionen hinzugef&uuml;gt werden sollen.<\/p>\n<h3>Hinweis<\/h3>\n<p>Die Funktion strConv mit dem Parameter vbProperCase deckt die gew&uuml;nschte Funktionalit&auml;t in den meisten F&auml;llen bereits ab. Daher verwenden wir diese Funktion als Grundlage und f&uuml;gen die Behandlung von Sonderf&auml;llen sp&auml;ter hinzu. <\/p>\n<p>Ohne Test kein neuer Code &#8211; diese Regel haben Sie bereits weiter oben kennengelernt. Das gilt im &uuml;brigen f&uuml;r jeden Schritt, den Sie mit dem Testframework gehen. Sie schreiben einen Test, bevor Sie Quellcode schreiben, und genauso f&uuml;gen Sie dem Testframework erstmal eine Testklasse und den entsprechenden Aufruf hinzu.<\/p>\n<h3>Hinweis<\/h3>\n<p>Die nachfolgenden Schritte m&uuml;ssen Sie bei der testgetriebenen Entwicklung noch h&auml;ufiger gehen; beachten Sie diese daher besonders aufmerksam. <\/p>\n<h2>Neue Testsuite erstellen<\/h2>\n<p>F&uuml;r das Erstellen der ben&ouml;tigten Testsuite kopieren Sie einfach die enthaltene Beispieltestsuite clsTestsuite in eine neue Klasse namens clsTestsuite_StringFunctions. &ouml;ffnen Sie das Klassenmodul und passen Sie es wie in Quellcode 4 an.<\/p>\n<pre>Public Sub Suite(objTestsuite As Object)\n    objTestsuite.AddTest _        New clsStringfunctionsTest\nEnd Sub<\/pre>\n<p><b>Quellcode 4<\/b><\/p>\n<h3>Testsuite im Testrunner verf&uuml;gbar machen<\/h3>\n<p>Damit die Testsuite im Testrunner-Formular ausgew&auml;hlt werden kann, f&uuml;gen Sie den folgenden Eintrag zu der Select Case-Anweisung der Methode TestsuiteWrapper der Klasse aUTestSuites hinzu (s. Quellcode 5).<\/p>\n<pre>Public Function TestsuiteWrapper(strTestsuitename As _    String) As Object\n    Select Case strTestsuitename\n        ''... weitere Testsuites\n        Case \"clsStringfunctionsTest\"\n            Set TestsuiteWrapper = _                New clsStringfunctionsTest\n    End Select\nEnd Function<\/pre>\n<p><b>Quellcode 5<\/b><\/p>\n<pre>Option Compare Database\nOption Explicit\nPublic Sub Setup()\nEnd Sub\nPublic Sub Teardown()\nEnd Sub\nPublic Property Get Fixturename() As String\n    Fixturename = \"clsStringfunctionsTest\"\nEnd Property\nPublic Sub Test1(objTestcase As aUTestcase)\n    On Error GoTo RunTest_Err\n    ''Add assertions\n    Exit Sub\nRunTest_Err:\n    objTestcase.Assert \"#Error in \" & Me.Fixturename, _        False\n    Resume Next\nEnd Sub<\/pre>\n<p><b>Quellcode 6<\/b><\/p>\n<p>Wenn Sie nun den Testrunner &ouml;ffnen m&ouml;chten, erhalten Sie vermutlich eine Meldung, die Sie zum Kompilieren der Anwendung auffordert.<\/p>\n<p>Das passiert zu Recht, denn der nachfolgende Kompiliervorgang, den Sie beispielsweise &uuml;ber den Men&uuml;eintrag Debuggen\/Kompilieren von &#8230; starten, wird auf die fehlende Klasse clsStringfunctionsTest hinweisen.<\/p>\n<h3>Testklasse anlegen<\/h3>\n<p>Das Ger&uuml;st der Testklasse erstellen Sie genauso wie im Fall der Testsuite: Kopieren Sie die Klasse clsNoTest in eine neue Klasse und nennen Sie diese clsStringfunctionsTest. Diese sollte nun den Inhalt aus Quellcode 6 haben.<\/p>\n<p>Passen Sie die Eigenschaft Fixturename wie folgt an, indem Sie clsNoTest durch clsStringfunctionsTest ersetzen. Kompilieren Sie erneut und &ouml;ffnen Sie den Testrunner. Das Kombinationsfeld Testsuite (s. Abb. 2) sollte nun unter anderem den Eintrag clsTestsuite_StringfunctionsTest anzeigen.<\/p>\n<h2>Testen mit dem Testrunner<\/h2>\n<p>Da noch keine Assertions vorhanden sind, sollte der Test erfolgreich verlaufen, da keine negativen Ergebnisse zu erwarten sind. Ein Klick auf die Schaltfl&auml;che Start zeigt, dass die Annahme richtig war &#8211; es erscheint der gr&uuml;ne Balken.<\/p>\n<p>Nach der Auswahl der Testsuite clsTestsuite_Stringfunctions zeigt der Testrunner an, dass die Suite einen Test enth&auml;lt. Dabei handelt es sich um den (noch) leeren Test1 (s. Quellcode 6).<\/p>\n<p><IMG height=\"382\" src=\"..\/fileadmin\/_temp_\/{AABFE1CC-8D7A-4C68-A61F-3AB4D4DA36D5}\/pic002.png\" width=\"458\" border=\"0\"><\/p>\n<p><b><\/b><\/p>\n<p><b>Abb. 2: Auswahl einer Testsuite<\/b><\/p>\n<pre>Public Sub Test_SingleWord(objTestcase As aUTestcase)\n    On Error GoTo RunTest_Err\n    objTestcase.Assert \"Andre -&gt; Andre\", StrComp(mClass.Capitalize(\"Andre\"), _        \"Andre\", vbBinaryCompare) = 0\n    objTestcase.Assert \"andre -&gt; Andre\", StrComp(mClass.Capitalize(\"andre\"), _        \"Andre\", vbBinaryCompare) = 0\n    objTestcase.Assert \"ANDRE -&gt; Andre\", StrComp(mClass.Capitalize(\"ANDRE\"), _        \"Andre\", vbBinaryCompare) = 0\n    objTestcase.Assert \"AnDrE -&gt; Andre\", StrComp(mClass.Capitalize(\"AnDrE\"), _         \"Andre\", vbBinaryCompare) = 0\n    objTestcase.Assert \"-&gt;\", StrComp(mClass.Capitalize(\"\"), \"\", vbBinaryCompare) = 0\n    objTestcase.Assert \"Sonderzeichen\", StrComp(mClass.Capitalize(\"(\/&$$=(''&sect;\/&sect;\"), _         \"(\/&$$=(''&sect;\/&sect;\", vbBinaryCompare) = 0\n    Exit Sub\nRunTest_Err:\n    objTestcase.Assert \"#Error in \" & Me.Fixturename, False\n    Resume Next\nEnd Sub<\/pre>\n<p><b>Quellcode 7<\/b><\/p>\n<h3>Hinweis<\/h3>\n<p>Schlie&szlig;en Sie den Testrunner jedesmal, wenn Sie &auml;nderungen am Code vornehmen, und &ouml;ffnen Sie ihn f&uuml;r weitere Tests erneut. Auf diese Weise macht der Testrunner Sie darauf aufmerksam, wenn Sie die Anwendung nach &auml;nderung des Codes nicht kompiliert haben. Wenn Sie den Testrunner ge&ouml;ffnet lassen, k&ouml;nnen anderenfalls Laufzeitfehler auftreten. <\/p>\n<p>Nun wollen wir zum ersten Test schreiten: Dazu legen wir zun&auml;chst im Kopf der Testklasse eine Objektvariable f&uuml;r die zu testende Klasse an:<\/p>\n<pre>Private mClass As clsStringfunctions<\/pre>\n<p>Zum Instanzieren der Klasse verwenden wir die Methode Setup:<\/p>\n<pre>Public Sub Setup()\n    Set mClass = New clsStringfunctions\nEnd Sub<\/pre>\n<p>Der Ordnung halber wird nach dem Test aufger&auml;umt:<\/p>\n<pre>Public Sub Teardown()\n    Set mClass = Nothing\nEnd Sub<\/pre>\n<p>Und jetzt folgt der gro&szlig;e Moment. Wir legen den ersten Test an, der voraussetzt, dass ein Name, der aus beliebigen Gro&szlig;- und Kleinbuchstaben besteht, in einen Namen mit f&uuml;hrendem gro&szlig;em Buchstaben umgewandelt wird. Dazu verwenden wir verschiedene Assertions (s. Quellcode 7). Diese sechs Assertions &uuml;berpr&uuml;fen verschiedene Varianten f&uuml;r die Eingabe, darunter die &uuml;bergabe eines Leerstrings und einer Sonderzeichenkombination als &#8222;Randf&auml;lle&#8220;.<\/p>\n<h3>Hinweis<\/h3>\n<p>Sie k&ouml;nnen jetzt nat&uuml;rlich zu Recht fragen, wozu wir soviele Assertions ben&ouml;tigen, da die strConv-Funktion doch zuverl&auml;ssig arbeitet. Die Antwort ist: Bei der testgetriebenen Entwicklung werden Einheiten getestet, und zwar an den Schnittstellen. Diese m&uuml;ssen immer das erwartete Ergebnis liefern, egal, wie die Implementierung aussieht. Wenn Sie die eine Methode einmal &#8211; etwa aus Performance-Gr&uuml;nden &#8211; &auml;ndern und die strConv-Funktion durch ein v&ouml;llig anderes Mittel wie beispielsweise regul&auml;re Ausdr&uuml;cke ersetzen, liefern die Tests nach wir vor eine Zusicherung, dass die Funktionen den Anforderungen entsprechen. <\/p>\n<p>Bevor Sie den Testrunner erneut &ouml;ffnen, kompilieren Sie die Anwendung und stellen fest, dass die zu testende Klasse clsStringfunctions noch nicht vorhanden ist.<\/p>\n<p><IMG height=\"382\" src=\"..\/fileadmin\/_temp_\/{AABFE1CC-8D7A-4C68-A61F-3AB4D4DA36D5}\/pic003.png\" width=\"458\" border=\"0\"><\/p>\n<p><b><\/b><\/p>\n<p><b>Abb. 3: Ein Test mit nicht erf&uuml;llten Anforderungen<\/b><\/p>\n<p>Legen Sie ein leeres Klassenmodul namens clsStringfunctions an und kompilieren Sie erneut.<\/p>\n<p>Der n&auml;chste Kompilierversuch bringt erwartungsgem&auml;&szlig; zu Tage, dass die Methode Capitalize nicht vorhanden ist.<\/p>\n<p>Legen Sie diese als leere Methode an:<\/p>\n<pre>Public Function Capitalize(strName _    As String) As String\nEnd Function<\/pre>\n<p>Die Kompilierung funktioniert nun. &ouml;ffnen Sie den Testrunner, w&auml;hlen Sie die richtige Suite aus und starten Sie den Test. Wie Abb. 3 zeigt, scheitert der Test, weil f&uuml;nf der sechs Assertions nicht erf&uuml;llt wurden.<\/p>\n<p>Nur die leere Zeichenfolge wird als leere Zeichenfolge zur&uuml;ckgegeben und erf&uuml;llt die entsprechende Assertion.<\/p>\n<p>In dieser Abbildung ist sch&ouml;n zu sehen, wie accessUnit von der Testsuite &uuml;ber den Test bis hin zum Assertion zeigt, wo es hapert. Passen wir also nun den Test so an, dass die Anforderungen erf&uuml;llt werden:<\/p>\n<pre>Public Function Capitalize(strName _    As String) As String\n    Capitalize = StrConv(strName, _        vbProperCase)\nEnd Function<\/pre>\n<p>Es folgt die &uuml;bliche Prozedur: Kompilieren, Testrunner starten, Test durchf&uuml;hren. Erwartungsgem&auml;&szlig; wird der Test nun bestanden.<\/p>\n<h2>Anforderungen erweitern<\/h2>\n<p>Die Funktion soll aber nicht nur einzelne Namen anpassen, sondern auch Kombinationen aus Vor- und Nachname. Diese Anforderung formulieren wir in einem neuen Test, der folgenderma&szlig;en aussieht und wie erwartet erfolgreich verl&auml;uft (s. Quellcode 8).<\/p>\n<h3>Hinweis<\/h3>\n<p>Mit diesem &#8222;Erg&auml;nzungstest&#8220; haben Sie der Gewissheit, dass der Test funktionieren wird, eine zus&auml;tzliche Sicherheit gegeben. Wenn aber einmal ein Test funktioniert, von dem Sie es nicht erwarten, sollten Sie kontrollieren, ob nicht der Test selbst eventuell fehlerhaft ist &#8211; m&ouml;glicherweise wurde er gar nicht aufgerufen. Wenn Sie unsicher sind, bauen Sie einfach eine Assertion ein, die fehlschl&auml;gt &#8211; damit finden Sie auf jeden Fall heraus, ob der Test &uuml;berhaupt aufgerufen wird. Das geht etwa mit folgendem Ausdruck: objTestcase.Assert &#8222;Test the test&#8220;, False. <\/p>\n<h3>Doppelnamen<\/h3>\n<p>Die Methode gibt nun sowohl einzelne Namen als auch Kombinationen aus Vor- und Nachname in der gew&uuml;nschten Form zur&uuml;ck. Nachdem wir diese Klasse nun beispielsweise in einer Web-Anwendung zum &#8222;Geradebiegen&#8220; von Namen bei der Anmeldung etwa f&uuml;r einen Newsletter verwenden, stellt sich fr&uuml;her oder sp&auml;ter heraus, dass die Anforderungen nicht alle F&auml;lle abgedeckt haben.<\/p>\n<pre>Public Sub Test_FirstAndLastname(objTestcase As aUTestcase)\n    On Error GoTo RunTest_Err\n    objTestcase.Assert \"Andre Minhorst -&gt; Andre Minhorst\", _        mClass.Capitalize(\"Andre Minhorst\") = \"Andre Minhorst\"\n    objTestcase.Assert \"andre minhorst -&gt; Andre Minhorst\", _        mClass.Capitalize(\"andre minhorst\") = \"Andre Minhorst\"\n    objTestcase.Assert \"ANDRE MINHORST -&gt; Andre Minhorst\", _        mClass.Capitalize(\"ANDRE MINHORST\") = \"Andre Minhorst\"\n    objTestcase.Assert \"AnDrE MiNhOrSt -&gt; Andre Minhorst\", _        mClass.Capitalize(\"AnDrE MiNhOrSt\") = \"Andre Minhorst\"\n    Exit Sub\nRunTest_Err:\n    objTestcase.Assert \"#Error in \" & Me.Fixturename, False\n    Resume Next\nEnd Sub<\/pre>\n<p><b>Quellcode 8<\/b><\/p>\n<pre>Public Sub Test_MinusBetweenNames(objTestcase As aUTestcase)\n    On Error GoTo RunTest_Err\n    objTestcase.Assert \"M&uuml;ller-L&uuml;denscheid -&gt; M&uuml;ller-L&uuml;denscheid\", _        StrComp(mClass.Capitalize(\"M&uuml;ller-L&uuml;denscheid\"), \"M&uuml;ller-L&uuml;denscheid\", _        vbBinaryCompare) = 0\n    objTestcase.Assert \"m&uuml;ller-l&uuml;denscheid -&gt; M&uuml;ller-L&uuml;denscheid\", _        StrComp(mClass.Capitalize(\"m&uuml;ller-l&uuml;denscheid\"), \"M&uuml;ller-L&uuml;denscheid\", _        vbBinaryCompare) = 0\n    Exit Sub\nRunTest_Err:\n    objTestcase.Assert \"#Error in \" & Me.Fixturename, False\n    Resume Next\nEnd Sub<\/pre>\n<p><b>Quellcode 9<\/b><\/p>\n<p>Meldet sich dort jemand mit einem Doppelnamen an, der durch Bindestrich getrennt ist, wird der zweite Teil des Namens komplett klein geschrieben.<\/p>\n<p>Schreiben wir also einen Test f&uuml;r diesen Fall. Dieser Test enth&auml;lt nur zwei Assertions: Eine, die &uuml;berpr&uuml;ft, dass ein gro&szlig;er Buchstabe hinter einem Bindestrich auch gro&szlig; bleibt, und eine, die &uuml;berpr&uuml;ft, ob ein kleiner Buchstabe hinter dem Bindestrich in einen gro&szlig;en umgewandelt werden soll (s. Quellcode 9).<\/p>\n<p>Beide Tests schlagen wie fehl, weil die Buchstaben hinter dem Minus-Zeichen durch die strConv-Funktion verkleinert werden.<\/p>\n<p>Passen wir also die Capitalize-Funktion an. Dazu f&uuml;gen wir eine Do While-Schleife ein, die so lange durchlaufen wird, bis keine Minus-Zeichen mehr enthalten sind (s. Quellcode 10). Normalerweise ist das zwar maximal eines, aber mit dieser Vorgehensweise gehen wir auf Nummer Sicher.<\/p>\n<p>Der Test verl&auml;uft erfolgreich: Die Methode erf&uuml;llt nun alle vorl&auml;ufig bekannten Anforderungen. Nat&uuml;rlich gibt es noch einige Varianten, die hier nicht  ber&uuml;cksichtig sind &#8211; beispielsweise Namenszus&auml;tze wie &#8222;de&#8220;, &#8222;van&#8220; oder &#8222;von&#8220;. Diese w&uuml;rden von der Methode im aktuellen Zustand wie alle anderen Bestandteile gro&szlig; geschrieben. F&uuml;r Beispielzwecke reicht uns allerdings die jetzige Form der Methode.<\/p>\n<pre>Public Function Capitalize(strName As String) As String\n    Dim posMinus As Integer\n    Capitalize = StrConv(strName, vbProperCase)\n    posMinus = InStr(1, Capitalize, \"-\")\n    Do While posMinus &gt; 0\n        If Mid(Capitalize, posMinus + 1, 1) Like \"[a-z]\" Then\n            Capitalize = Mid(Capitalize, 1, posMinus) & StrConv(Mid(Capitalize, _\n                posMinus + 1, 1), vbUpperCase) & Mid(Capitalize, posMinus + 2)\n        End If\n        posMinus = InStr(posMinus + 1, Capitalize, \"-\")\n    Loop\nEnd Function<\/pre>\n<p><b>Quellcode 10<\/b><\/p>\n<pre>Public Function Capitalize(strName As String) As String\n    Dim posMinus As Integer\n    Dim strCapitalize As String\n    strCapitalize = StrConv(strName, vbProperCase)\n    posMinus = InStr(1, strCapitalize, \"-\")\n    Do While posMinus &gt; 0\n        If Mid(strCapitalize, posMinus + 1, 1) _\n            Like \"[a-z]\" Then\n            strCapitalize = Mid(strCapitalize, 1, _\n                posMinus) & StrConv(Mid(strCapitalize, _\n                posMinus + 1, 1), vbUpperCase) & _\n                Mid(strCapitalize, posMinus + 2)\n        End If\n        posMinus = InStr(posMinus + 1, strCapitalize, \"-\")\n    Loop\n    Capitalize = strCapitalize\nEnd Function<\/pre>\n<p><b>Quellcode 11<\/b><\/p>\n<h2>Ein wenig Refactoring<\/h2>\n<p>Allerdings m&ouml;chten wir noch einen kleinen Ausflug in die Welt des Refactoring unternehmen. Die Methode hat den kleinen Makel, dass die Funktionsbezeichnung nicht nur f&uuml;r die Zuweisung des R&uuml;ckgabewertes, sondern als Hilfsvariable verwendet wird.<\/p>\n<p>Da alle Tests gerade bestanden sind, k&ouml;nnen wir ohne Sorge eine neue Hilfsvariable einbauen &#8211; der anschlie&szlig;ende Test wird uns mitteilen, ob die Funktion der Methode durch den Umbau beeintr&auml;chtigt wurde.<\/p>\n<p>Abb. 4 veranschaulicht die einzelnen Positionen, die man bei der testgetriebenen Entwicklung durchlaufen kann.<\/p>\n<p>Derzeit haben wir die Wahl zwischen einem der beiden &#8222;Test bestanden&#8220;-Pfeile &#8211; und w&auml;hlen den Weg zum Refactoring. Wir bauen die Methode also wie in Quellcode 11 um und &uuml;berpr&uuml;fen direkt im Anschluss, ob die Tests noch durchlaufen. Bei positivem Ergebnis k&ouml;nnen wir beruhigt an die Entwicklung der n&auml;chsten Methode oder Klasse herangehen.<\/p>\n<h2>Randf&auml;lle testen<\/h2>\n<p><IMG height=\"228\" src=\"..\/fileadmin\/_temp_\/{AABFE1CC-8D7A-4C68-A61F-3AB4D4DA36D5}\/pic004.png\" width=\"363\" border=\"0\"><\/p>\n<p><b><\/b><\/p>\n<p><b>Abb. 4: Ablauf der testgetriebenen Entwicklung<\/b><\/p>\n<p>Mit den hier beschreibenen Tests haben Sie relativ einfache F&auml;lle abgedeckt. Dabei bestand kein gr&ouml;sserer Anlass, sich Gedanken um so genannte Randf&auml;lle zu machen. Bei Randf&auml;llen handelt es sich um solche Anforderungen, die nicht triviale F&auml;lle abdecken und deren Erf&uuml;llung spezielle Vorgehensweisen erfordert, weil durch das Eintreten des Randfalls beispielsweise ein Fehler ausgel&ouml;st w&uuml;rde. Im vorliegenden Test gibt es keinen solch schwerwiegenden Randfall, da die Methode ohnehin nur Werte mit dem Datentyp String akzeptiert. Ein Beispiel w&auml;re aber etwa eine Funktion, die den Quotienten zweier Zahlen ermittelt und die man mit solchen Werten f&uuml;ttert, dass eine Division durch 0 auftritt. Diesen Fall w&uuml;rde man im Test ber&uuml;cksichtigen, damit er bei der Ausf&uuml;hrung entsprechend behandelt wird.<\/p>\n<h2>Wie geht es weiter<\/h2>\n<p>Auf die gleiche Art wie im Beispiel k&ouml;nnen Sie komplette Anwendungen erstellen, indem Sie Klasse f&uuml;r Klasse testgetrieben entwickeln. Dabei werden Sie oft Testklassen erstellen, die sich jeweils auf nur eine zu testende Klasse beziehen; Sie werden aber auch Testklassen verwenden, die dem Testen der Interaktion zwischen Klassen dienen.<\/p>\n<h2>Wohin mit den Tests<\/h2>\n<p>Sie haben mittlerweile gemerkt, dass Sie bei der testgetriebenen Entwicklung bestimmt noch einmal soviel Code produzieren wie f&uuml;r die eigentliche Anwendung erforderlich ist.<\/p>\n<p>Wenn die Anwendung fertig ist, m&ouml;chten Sie diesen Code m&ouml;glicherweise loswerden &#8211; vielleicht aber auch nicht, denn immerhin haben Sie eine Menge Arbeit hineingesteckt. Au&szlig;erdem sollten Sie nicht vergessen: Die Tests sind eine Dokumentation der damit erstellten Klassen. Sie sollten die Tests auf jeden Fall in Ihrer eigenen Kopie der Anwendung behalten, und es gibt eigentlich auch keinen Grund, die Tests nicht mit auszuliefern.<\/p>\n<p>Dass Sie zus&auml;tzlich zu den Tests auch noch das Framework in der Anwendung belassen, kann ebenfalls Vorteile haben: Gegebenenfalls gibt es einmal neue Versionen des Frameworks, die mit mit den aktuell in der getesteten Datenbank vorhandenen Objekten nicht mehr zusammenarbeiten. Das enthaltene Framework wird seinen Dienst aber klaglos tun, solange Sie es nicht ersetzen.<\/p>\n<p>Die testgetriebene Entwicklung mag Ihnen nach der Lekt&uuml;re dieses Beitrags sinnvoll erscheinen &#8211; v&ouml;llig &uuml;berzeugt sein werden Sie vielleicht erst, wenn Sie es selbst ausprobiert haben. Um sich den Einstieg zu erleichtern, nehmen Sie sich einfach eine m&ouml;glichst kleine bestehende Anwendung und erstellen diese neu. Damit haben Sie schon eine Vorstellung davon, in welche Richtung die Anwendung gehen soll, und k&ouml;nnen sich voll auf die Art der Entwicklungsmethode konzentrieren.<\/p>\n<p>Die Internetseite www.accessunit.de besch&auml;ftigt sich mit dem Testframework selbst und mit den damit in Zusammenhang stehenden Techniken wie der testgetriebenen Entwicklung oder Refactoring; hier finden Sie regelm&auml;&szlig;ig neue Versionen und neue Informationen zum Unit-Testing mit Access sowie interessante Links.<\/p>\n<h2>Downloads zu diesem Beitrag<\/h2>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>accessUnit_e_1.06.mdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/F044CE2F-C370-49B2-B7D6-317A339EA423\/aiu_235.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Die Schlagw&ouml;rter Extreme Programming (XP), Unit-Testing, Test Driven Development, Refactoring oder Pair Programming geistern durch die Entwicklerwelt. Dabei ist Extreme Programming der Oberbegriff f&uuml;r die anderen und fasst diese und mehr zu einer neuartigen Philosophie der Softwareentwicklung zusammen. Ziel der dahinter stehenden Konzepte sind Projekte, die von kleinen Entwicklerteams durchgef&uuml;hrt werden. Da die meisten Leser dieses Beitrags vermutlich allein entwickeln, stellt dieser Beitrag ein elementares Konzept von XP heraus: das Test Driven Development (TDD), zu deutsch testgetriebene Entwicklung.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[662004,66052004,44000025],"tags":[],"class_list":["post-55000235","post","type-post","status-publish","format-standard","hentry","category-662004","category-66052004","category-VBA_und_Programmiertechniken"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.4) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Testgetriebene Entwicklung mit Access - Access im Unternehmen<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/access-im-unternehmen.de\/testgetriebene_entwicklung_mit_access\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Testgetriebene Entwicklung mit Access\" \/>\n<meta property=\"og:description\" content=\"Die Schlagw&ouml;rter Extreme Programming (XP), Unit-Testing, Test Driven Development, Refactoring oder Pair Programming geistern durch die Entwicklerwelt. Dabei ist Extreme Programming der Oberbegriff f&uuml;r die anderen und fasst diese und mehr zu einer neuartigen Philosophie der Softwareentwicklung zusammen. Ziel der dahinter stehenden Konzepte sind Projekte, die von kleinen Entwicklerteams durchgef&uuml;hrt werden. Da die meisten Leser dieses Beitrags vermutlich allein entwickeln, stellt dieser Beitrag ein elementares Konzept von XP heraus: das Test Driven Development (TDD), zu deutsch testgetriebene Entwicklung.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/testgetriebene_entwicklung_mit_access\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2023-02-10T14:50:20+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-02-19T08:17:41+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg06.met.vgwort.de\/na\/aa4cb9507fcc46ce954cfe465386ec91\" \/>\n<meta name=\"author\" content=\"Andr\u00e9 Minhorst\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andr\u00e9 Minhorst\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"26\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/testgetriebene_entwicklung_mit_access\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/testgetriebene_entwicklung_mit_access\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"Testgetriebene Entwicklung mit Access\",\"datePublished\":\"2023-02-10T14:50:20+00:00\",\"dateModified\":\"2024-02-19T08:17:41+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/testgetriebene_entwicklung_mit_access\\\/\"},\"wordCount\":5141,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/testgetriebene_entwicklung_mit_access\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/aa4cb9507fcc46ce954cfe465386ec91\",\"articleSection\":[\"2004\",\"5\\\/2004\",\"VBA und Programmiertechniken\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/testgetriebene_entwicklung_mit_access\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/testgetriebene_entwicklung_mit_access\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/testgetriebene_entwicklung_mit_access\\\/\",\"name\":\"Testgetriebene Entwicklung mit Access - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/testgetriebene_entwicklung_mit_access\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/testgetriebene_entwicklung_mit_access\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/aa4cb9507fcc46ce954cfe465386ec91\",\"datePublished\":\"2023-02-10T14:50:20+00:00\",\"dateModified\":\"2024-02-19T08:17:41+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/testgetriebene_entwicklung_mit_access\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/testgetriebene_entwicklung_mit_access\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/testgetriebene_entwicklung_mit_access\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/aa4cb9507fcc46ce954cfe465386ec91\",\"contentUrl\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/aa4cb9507fcc46ce954cfe465386ec91\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/testgetriebene_entwicklung_mit_access\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Testgetriebene Entwicklung mit Access\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"name\":\"Access im Unternehmen\",\"description\":\"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access\",\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/access-im-unternehmen.de\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\",\"name\":\"Andr\u00e9 Minhorst Verlag\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"contentUrl\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"width\":370,\"height\":111,\"caption\":\"Andr\u00e9 Minhorst Verlag\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\",\"name\":\"Andr\u00e9 Minhorst\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"caption\":\"Andr\u00e9 Minhorst\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Testgetriebene Entwicklung mit Access - Access im Unternehmen","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/access-im-unternehmen.de\/testgetriebene_entwicklung_mit_access\/","og_locale":"de_DE","og_type":"article","og_title":"Testgetriebene Entwicklung mit Access","og_description":"Die Schlagw&ouml;rter Extreme Programming (XP), Unit-Testing, Test Driven Development, Refactoring oder Pair Programming geistern durch die Entwicklerwelt. Dabei ist Extreme Programming der Oberbegriff f&uuml;r die anderen und fasst diese und mehr zu einer neuartigen Philosophie der Softwareentwicklung zusammen. Ziel der dahinter stehenden Konzepte sind Projekte, die von kleinen Entwicklerteams durchgef&uuml;hrt werden. Da die meisten Leser dieses Beitrags vermutlich allein entwickeln, stellt dieser Beitrag ein elementares Konzept von XP heraus: das Test Driven Development (TDD), zu deutsch testgetriebene Entwicklung.","og_url":"https:\/\/access-im-unternehmen.de\/testgetriebene_entwicklung_mit_access\/","og_site_name":"Access im Unternehmen","article_published_time":"2023-02-10T14:50:20+00:00","article_modified_time":"2024-02-19T08:17:41+00:00","og_image":[{"url":"http:\/\/vg06.met.vgwort.de\/na\/aa4cb9507fcc46ce954cfe465386ec91","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"26\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/testgetriebene_entwicklung_mit_access\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/testgetriebene_entwicklung_mit_access\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"Testgetriebene Entwicklung mit Access","datePublished":"2023-02-10T14:50:20+00:00","dateModified":"2024-02-19T08:17:41+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/testgetriebene_entwicklung_mit_access\/"},"wordCount":5141,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/testgetriebene_entwicklung_mit_access\/#primaryimage"},"thumbnailUrl":"http:\/\/vg06.met.vgwort.de\/na\/aa4cb9507fcc46ce954cfe465386ec91","articleSection":["2004","5\/2004","VBA und Programmiertechniken"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/testgetriebene_entwicklung_mit_access\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/testgetriebene_entwicklung_mit_access\/","url":"https:\/\/access-im-unternehmen.de\/testgetriebene_entwicklung_mit_access\/","name":"Testgetriebene Entwicklung mit Access - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/testgetriebene_entwicklung_mit_access\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/testgetriebene_entwicklung_mit_access\/#primaryimage"},"thumbnailUrl":"http:\/\/vg06.met.vgwort.de\/na\/aa4cb9507fcc46ce954cfe465386ec91","datePublished":"2023-02-10T14:50:20+00:00","dateModified":"2024-02-19T08:17:41+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/testgetriebene_entwicklung_mit_access\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/testgetriebene_entwicklung_mit_access\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/testgetriebene_entwicklung_mit_access\/#primaryimage","url":"http:\/\/vg06.met.vgwort.de\/na\/aa4cb9507fcc46ce954cfe465386ec91","contentUrl":"http:\/\/vg06.met.vgwort.de\/na\/aa4cb9507fcc46ce954cfe465386ec91"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/testgetriebene_entwicklung_mit_access\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"Testgetriebene Entwicklung mit Access"}]},{"@type":"WebSite","@id":"https:\/\/access-im-unternehmen.de\/#website","url":"https:\/\/access-im-unternehmen.de\/","name":"Access im Unternehmen","description":"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access","publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/access-im-unternehmen.de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/access-im-unternehmen.de\/#organization","name":"Andr\u00e9 Minhorst Verlag","url":"https:\/\/access-im-unternehmen.de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/","url":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","contentUrl":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","width":370,"height":111,"caption":"Andr\u00e9 Minhorst Verlag"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f","name":"Andr\u00e9 Minhorst","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","caption":"Andr\u00e9 Minhorst"}}]}},"_links":{"self":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000235","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/comments?post=55000235"}],"version-history":[{"count":1,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000235\/revisions"}],"predecessor-version":[{"id":88075293,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000235\/revisions\/88075293"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55000235"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55000235"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55000235"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}