Das Testen Ihres Codes ist ärgerlich, aber die Auswirkungen, wenn Sie dies nicht tun, kann um Größenordnungen ärgerlicher sein! In diesem Artikel verwenden wir testgetriebene Entwicklung, um unseren Code effektiver zu schreiben und zu testen.
Seit dem Beginn des Computerzeitalters haben Programmierer und Fehler um die Vorherrschaft gekämpft. Es ist ein unvermeidliches Ereignis. Sogar die größten Programmierer fallen diesen Anomalien zum Opfer. Kein Code ist sicher. Deshalb testen wir. Programmierer, zumindest vernünftige, testen ihren Code, indem sie ihn auf Entwicklungscomputern ausführen, um sicherzustellen, dass er das tut, was er soll.
Testgetriebene Entwicklung ist eine Programmiertechnik, bei der Sie gleichzeitig aktuellen Code und automatisierten Testcode schreiben müssen. Dies stellt sicher, dass Sie Ihren Code testen - und ermöglicht Ihnen, Ihren Code schnell und einfach erneut zu testen, da er automatisiert ist.
Testgetriebene Entwicklung, oder TDD, wie wir es von nun an nennen, dreht sich um einen kurzen iterativen Entwicklungszyklus, der etwa so abläuft:
Haben Sie schon einmal das Testen eines Programms übersprungen, weil:
Meistens passiert nichts, und Sie können Ihren Code ohne Probleme erfolgreich in die Produktion bringen. Aber manchmal, nachdem Sie zur Produktion übergegangen sind, geht alles schief. Sie stecken fest und reparieren hundert Löcher in einem sinkenden Schiff, wobei jede Minute mehr erscheint. Sie machen nicht Ich möchte mich in dieser Situation wiederfinden.
TDD sollte unsere Ausreden beseitigen. Wenn ein Programm mit TDD entwickelt wurde, können wir Änderungen schnell und effizient durchführen und testen. Wir müssen nur die automatisierten Tests durchführen und voila! Wenn alle automatisierten Tests bestanden sind, können wir loslegen. Wenn nicht, bedeutet dies nur, dass wir mit den Änderungen etwas gebrochen haben. Durch das Wissen, welche genauen Teile des Tests fehlgeschlagen sind, können wir auch leicht feststellen, an welchem Teil der Änderungen der Fehler aufgetreten ist. Dies erleichtert die Behebung der Fehler.
Es gibt eine Vielzahl von PHP-Frameworks für automatisierte Tests, die wir verwenden können. Eines der am häufigsten verwendeten Testframeworks ist PHPUnit.
PHPUnit ist ein großartiges Testframework, das sich leicht in eigene Projekte oder andere Projekte integrieren lässt, die auf gängigen PHP-Frameworks aufbauen.
Für unsere Zwecke benötigen wir jedoch nicht die Vielzahl von Funktionen, die PHPUnit bietet. Stattdessen entscheiden wir uns für die Erstellung unserer Tests mit einem viel einfacheren Test-Framework namens SimpleTest.
Nehmen wir in den nächsten Schritten an, dass wir eine Gästebuchanwendung entwickeln, in der jeder Benutzer Gästebucheinträge hinzufügen und anzeigen kann. Nehmen wir an, dass das Markup abgeschlossen wurde und wir einfach eine Klasse erstellen, die das enthält Anwendungslogik des Gästebuchs, wo die Anwendung die Datenbank einfügt und liest. Der Leseteil dieser Klasse ist das, was wir entwickeln und testen werden.
Dies ist wohl der einfachste Schritt von allen. Sogar dieser Typ könnte es schaffen:
Laden Sie SimpleTest hier herunter und entpacken Sie es in einen Ordner Ihrer Wahl - vorzugsweise den Ordner, in dem Sie Ihren Code entwickeln, oder Ihren PHP include_path für den einfachen Zugriff.
Für dieses Tutorial habe ich den Ordner so eingerichtet:
Index.php führt guestbook.php aus, ruft die View-Methode auf und zeigt die Einträge an. Innerhalb des Klassenordners legen wir die guestbook.php-Klasse ab, und im Testordner platzieren wir die einfachste Bibliothek.
Der zweite und eigentlich wichtigste Schritt besteht darin, mit der Erstellung Ihrer Tests zu beginnen. Zu diesem Zweck müssen Sie wirklich planen und darüber nachdenken, was Ihre Funktion bewirkt, welche möglichen Eingänge sie erhalten und welche Ausgänge sie senden werden. Dieser Schritt ähnelt einem Schachspiel. Sie müssen alles über Ihren Gegner (das Programm) wissen, einschließlich aller Schwächen (mögliche Fehler) und Stärken (was passiert, wenn er erfolgreich ausgeführt wird)..
Lassen Sie uns für unsere Gästebuch-Anwendung die Schaltpläne festlegen:
Array ([0] => Array (['name'] = "Bob" ['message'] = "Hi, ich bin Bob.") [1] => Array (['name'] = "Tom") ['message'] = "Hallo, ich bin Tom."))
Nun können wir unseren ersten Test schreiben. Beginnen wir mit dem Erstellen einer Datei namens guestbook_test.php im Testordner.
Dann konvertieren wir das, was wir aus Schritt zwei bestimmt haben,.
add ("Bob", "Hi, ich bin Bob."); $ guestbook-> add ("Tom", "Hallo, ich bin Tom."); $ entries = $ guestbook-> viewAll (); $ count_is_greater_than_zero = (count ($ entries)> 0); $ this-> assertTrue ($ count_is_greater_than_zero); $ this-> assertIsA ($ entries, 'array'); foreach ($ entries as $ entry) $ this-> assertIsA ($ entry, 'array'); $ this-> assertTrue (isset ($ entry ['name'])); $ this-> assertTrue (isset ($ entry ['message'])); Funktion testViewGuestbookWithNoEntries () $ guestbook = new Guestbook (); $ guestbook-> deleteAll (); // Lösche zuerst alle Einträge, damit wir wissen, dass es sich um eine leere Tabelle handelt. $ Entries = $ guestbook-> viewAll (); $ this-> assertEqual ($ entries, array ());Assertions stellen sicher, dass eine bestimmte Sache das ist, was sie sein soll - im Grunde stellt sie sicher, dass das, was zurückgegeben wird, das ist, was Sie erwarten, dass es zurückkehrt. Wenn zum Beispiel eine Funktion true zurückgeben soll, wenn sie erfolgreich ist, sollten wir dies in unserem Test tun behaupten dass der Rückgabewert gleich true ist.
Wie Sie hier sehen, testen wir die Anzeige des Gästebuches mit und ohne Einträge. Wir prüfen, ob diese beiden Szenarien unsere Kriterien aus Schritt zwei erfüllen. Sie haben wahrscheinlich auch bemerkt, dass jede unserer Testfunktionen mit dem Wort "Test" beginnt. Wir haben dies getan, da SimpleTest diese Klasse ausführt und nach allen Funktionen sucht, die mit dem Wort 'test' beginnen, und es ausführen.
In unserer Testklasse haben wir auch einige Assertionsmethoden verwendet, wie assertTrue, assertIsA und assertEquals. Die Funktion assertTrue prüft, ob ein Wert wahr ist oder nicht. AssertIsA prüft, ob eine Variable einen bestimmten Typ oder eine bestimmte Klasse hat. Als letztes überprüft assertEquals, ob eine Variable einem bestimmten Wert entspricht.
Es gibt andere Bestätigungsmethoden, die von SimpleTest bereitgestellt werden, und zwar:
assertTrue ($ x) | Scheitern, wenn $ x falsch ist |
assertFalse ($ x) | Fehler, wenn $ x wahr ist |
assertNull ($ x) | Fail, wenn $ x gesetzt ist |
assertNotNull ($ x) | Fehler, wenn $ x nicht gesetzt ist |
assertIsA ($ x, $ t) | Fehler, wenn $ x nicht die Klasse oder der Typ $ t ist |
assertNotA ($ x, $ t) | Fehler, wenn $ x der Klasse oder dem Typ $ t entspricht |
assertEqual ($ x, $ y) | Fehler, wenn $ x == $ y falsch ist |
assertNotEqual ($ x, $ y) | Fehler, wenn $ x == $ y wahr ist |
assertWithinMargin ($ x, $ y, $ m) | Scheitern, wenn abs ($ x - $ y) < $m is false |
assertOutsideMargin ($ x, $ y, $ m) | Scheitern, wenn abs ($ x - $ y) < $m is true |
assertIdentical ($ x, $ y) | Schlagen Sie fehl, wenn $ x == $ y falsch ist oder ein Typkonflikt besteht |
assertNotIdentical ($ x, $ y) | Fehler, wenn $ x == $ y wahr ist und die Typen übereinstimmen |
assertReference ($ x, $ y) | Fehler, es sei denn, $ x und $ y sind dieselbe Variable |
assertClone ($ x, $ y) | Schlagen Sie fehl, wenn $ x und $ y identische Kopien sind |
assertPattern ($ p, $ x) | Scheitern, es sei denn, der Regex $ p stimmt mit $ x überein |
assertNoPattern ($ p, $ x) | Fehler, wenn der Regex $ p mit $ x übereinstimmt |
expectError ($ x) | Verschluckt jeden anstehenden Übereinstimmungsfehler |
behaupten ($ e) | Fehler bei fehlgeschlagenem Erwartungsobjekt $ e |
Liste der Assertionsmethoden mit freundlicher Genehmigung von http://www.simpletest.org/de/unit_test_documentation.html
Wenn Sie mit dem Schreiben des Codes fertig sind, sollten Sie den Test ausführen. Wenn Sie den Test zum ersten Mal ausführen, Sollte fehlschlagen. Wenn dies nicht der Fall ist, bedeutet dies, dass Ihr Test nichts wirklich testet.
Um den Test auszuführen, führen Sie einfach aus guestbook_test.php in Ihrem Browser Sie sollten dies zuerst sehen:
Dies geschah, weil wir unsere Gästebuchklasse noch nicht erstellt haben. Erstellen Sie dazu die Datei guestbook.php in Ihrem Klassenordner. Die Klasse sollte die Methoden enthalten, die wir verwenden möchten, aber zunächst noch nichts. Denken Sie daran, wir schreiben die Tests zuerst Vor einen beliebigen Code schreiben.
Wenn Sie den Test erneut ausführen, sollte er ungefähr so aussehen:
Wie wir hier sehen können, gewinnt unser Test jetzt, wenn er versagt. Dies bedeutet, dass unser Test jetzt bereit ist, "beantwortet" zu werden.
Bild mit freundlicher Genehmigung von http://www.gamercastnetwork.com/forums
Schritt 5. Beantworten Sie Ihren Test, indem Sie Code schreiben
Irgendwann haben wir uns alle beim Programmieren so gefühlt.
Bild mit freundlicher Genehmigung von http://fermentation.typepad.com/fermentationJetzt, da wir einen funktionierenden automatisierten Test haben, können wir mit dem Schreiben von Code beginnen. Öffne deine guestbook.php Klasse und beginnen Sie, die Antwort auf Ihren Test zu erstellen.
'Kirk', 'message' => 'Hi, ich bin Kirk.' ), array ('name' => 'Ted', 'message' => 'Hi, ich bin Ted.')); public function viewAll () // Hier sollten wir alle Datensätze aus der Datenbank abrufen. // Dies wird simuliert, indem das Array $ _entries zurückgegeben wird. Return self :: $ _ entries; public function add ($ name, $ message) // Hier simulieren wir das Einfügen in die Datenbank, indem wir einen neuen Datensatz in das $ _entries-Array einfügen. // Dies ist der richtige Weg: self :: $ _ entries [] = Array ('name' => $ name, 'message' => $ message); self :: $ _ entries [] = array ('notname' => $ name, 'notmessage' => $ message); // oops, hier gibt es einen Fehler, irgendwo zurückgeben true; public function deleteAll () // Wir setzen das $ _entries-Array so, dass es self :: $ _ entries = array (); wahr zurückgeben;Diese guestbook.php-Klasse enthält absichtlich einige Fehler, sodass wir sehen können, wie es aussieht, wenn unser Test fehlschlägt.
Sobald wir unseren Test durchgeführt haben, sollten wir so etwas sehen:
Die Testausgabe zeigt uns, bei welchem Test und bei welcher Aussage unser Code fehlgeschlagen ist. Daraus lässt sich leicht feststellen, dass die Zeile 16 und 17 die Behauptung war, die den Fehler ausgelöst hat.
assertTrue (isset ($ entry ['name'])); $ this-> assertTrue (isset ($ entry ['message'])) ;?Dies zeigt uns eindeutig, dass das zurückgegebene Eintragsfeld nicht den richtigen Feldschlüssel hatte. Auf dieser Grundlage wissen wir leicht, welcher Teil unseres Codes fehlerhaft ist.
$ name, 'message' => $ message); //Fest! wahr zurückgeben;Nun, wenn wir unseren Test erneut durchführen, sollte es uns zeigen:
Schritt 6. Refactor und Verfeinern Sie Ihren Code
Bilder mit freundlicher Genehmigung von http://www.osborneink.com und http://phuketnews.phuketindex.comDa der Code, den wir hier testen, ziemlich einfach ist, dauerten unser Testen und die Fehlerbehebung nicht sehr lange. Wenn es sich jedoch um eine komplexere Anwendung handelt, müssen Sie Ihren Code mehrfach ändern, sauberer machen, damit er einfacher zu warten ist und viele andere Dinge. Das Problem dabei ist jedoch, dass Änderungen in der Regel zusätzliche Fehler verursachen. Hier kommt unser automatisierter Test ins Spiel - sobald wir Änderungen vorgenommen haben, können wir den Test einfach noch einmal durchführen. Wenn es immer noch durchgeht, bedeutet das, dass wir nichts kaputt gemacht haben. Wenn es fehlschlägt, wissen wir, dass wir einen Fehler gemacht haben. Es informiert uns auch, wo das Problem liegt und wie wir es hoffentlich beheben können.
Schritt 7. Spülen und wiederholen
Mit freundlicher Genehmigung von http://www.philstockworld.comWenn Ihr Programm neue Funktionen erfordert, müssen Sie möglicherweise neue Tests schreiben. Das ist einfach! Spülen Sie die Prozeduren ab Schritt zwei und wiederholen Sie sie (da Ihre SimpleTest-Dateien bereits eingerichtet sein sollten), und starten Sie den Zyklus erneut.
Fazit
Es gibt viel tiefgreifendere, testgetriebene Entwicklungsartikel und noch mehr Funktionalität für SimpleTest, als in diesem Artikel dargestellt wurde. Dazu gehören Mock-Objekte und Stubs, die das Erstellen von Tests erleichtern. Wenn Sie mehr erfahren möchten, sollten Sie auf der testgetriebenen Entwicklungsseite von Wikipedia den richtigen Weg finden. Wenn Sie SimpleTest als Testframework verwenden möchten, durchsuchen Sie die Online-Dokumentation und stellen Sie sicher, dass Sie auch die anderen Funktionen überprüfen.
Das Testen ist ein wesentlicher Bestandteil des Entwicklungszyklus, es ist jedoch zu oft das erste, was bei unmittelbar bevorstehenden Fristen gekürzt werden muss. Wenn Sie diesen Artikel gelesen haben, werden Sie hoffentlich schätzen, wie hilfreich es ist, in testgetriebene Entwicklung zu investieren.
Was halten Sie von testgetriebener Entwicklung? Interessieren Sie sich für die Implementierung oder denken Sie, dass es Zeitverschwendung ist? Lass es mich in den Kommentaren wissen!