Development

Documentation/de_DE/book/1.0/15-Unit-and-Functional-Testing (diff)

You must first sign up to be able to contribute.

Changes between Version 1 and Version 2 of Documentation/de_DE/book/1.0/15-Unit-and-Functional-Testing

Show
Ignore:
Author:
Jan.Kunzmann (IP: 87.234.70.169)
Timestamp:
03/27/08 17:34:49 (10 years ago)
Comment:

15%

Legend:

Unmodified
Added
Removed
Modified
  • Documentation/de_DE/book/1.0/15-Unit-and-Functional-Testing

    v1 v2  
    11'''ARBEITSENTWURF ROHÜBERSETZUNG / TRANSLATION WORKING DRAFT'''[[BR]] 
    22Originaldokument: http://svn.symfony-project.com/doc/branches/1.1/book/15-Unit-and-Functional-Testing.txt, Version 7705 vom 2008-03-01[[BR]] 
    3 Übersetzungsfortschritt: 0%[[BR]] 
     3Übersetzungsfortschritt: 15%[[BR]] 
    44Übersetzung: JK[[BR]] 
    55Korrekturfortschritt: 0%[[BR]] 
    1010=========================================== 
    1111 
     12Automatisierte Tests stellen einen der größsten Fortschritte in der Programmierung seit der Objektorientierung dar. Besonders hilfreich sind sie bei der Entwicklung von Webanwendungen, denn sie garantieren die Qualität einer Applikation selbst dann, wenn oft released wird. Symfony stellt eine ganze Reihe an Werkzeugen für das automatisierte Testen bereit, die in diesem Kapitel vorgestellt werden. 
     13 
     14Automatisierte Tests 
     15-------------------- 
     16 
     17Jeder erfahrene Entwickler weiß genau, welche Zeit es benötigt, um Webanwendungen gut zu testen. Es ist lästig, Testcases zu schreiben, sie laufen zu lassen und die Ergebnisse zu analyiseren. Zusätzlich ändern sich die Anforderungen an Webanwendungen meist stetig, was wiederum zu einem ununterbrochenen Strom von Releases führt und ein fortwährendes Refactoring des Codes notwendig macht. In diesem Umfeld ist es sehr wahrscheinlich, dass regelmäßig neue Fehler auftauchen. 
     18 
     19Aus diesem Grund werden automatisierte Tests als Teil einer sinnvollen Entwicklungsumgebung gesehen, auch wenn sie nicht unbedingt notwendig sind. Ein paar Testcases kann sicherstellen, dass eine Anwendung das tut, was man erwartet. Selbst wenn die Internas oft überarbeitet werden, verhindern automatisierte Tests versehentliche Rückschritte. Außerdem zwingen sie Entwickler dazu, Tests in einem standardisierten, starren Format zu schreiben, das von einem Test-Framework verstanden werden kann. 
     20 
     21Automatisierte Tests können gelegentlich auch die Entwicklerdokumentation ersetzen, da sie deutlich machen, was die Anwendung eigentlich tun soll. Eine gute Testsuite zeigt an, welche Ausgaben von einer Testeingabe erwartet werden, was wiederum eine gute Möglichkeit ist, den Zweck einer Methode zu erklären. 
     22 
     23Das Symfony-Framework wendet dieses Prinzip auch auf sich selbst an. Die Internas des Frameworks werden durch automatisierte Tests überprüft. Diese Unit- und Funktionalitäts-Tests werden nicht zusammen mit der normalen Symfony-Distribution ausgeliefert, aber Sie können sie aus dem SVN-Repository auschecken oder utner [http://trac.symfony-project.com/browser/trunk/test](http://trac.symfony-project.com/browser/trunk/test) durchstöbern. 
     24 
     25### Unit-Test und Funktionalitäts-Tests 
     26 
     27Unit-Tests bestätigen, dass eine abgeschlossene Code-Komponente die korrekte Ausgabe für eine bestimmte Eingabe liefert. Sie überprüfen, wie Funktionen und Methoden in allen Einzelfällen arbeiten. Unit-Tests behandeln stets nur einen Test auf einmal, und somit könnte eine einzige Methode mehrere Unit-Tests benötigen, wenn sie in bestimmten Situationen unterschiedlich arbeitet. 
     28 
     29Funktionalitäts-Tests überprüfen nicht nur eine einfache Umsetzung von Eingabe zu Ausgabe, sondern ein komplettes Feature. Ein Cache-System beispielsweise kann nur durch einen Funktionalitätstest überprüft werden, da hierfür mehr als ein einzelner Schritt notwendig ist: Wird die Seite das erste mal aufgerufen, wird sie ausgeführt; beim zweiten Mal wird sie aus dem Cache geholt. Funktionalitäts-Tests überprüfen also einen Prozess und brauchen ein Szenario. In Symfony sollten Sie Funktionalitäts-Tests für all Ihre Actions schreiben. 
     30 
     31Für hochkomplexe Interaktionen können sich die beiden Testarten überschneiden. Ajax-Interaktionen benötigen beispielsweise einen Webbrowser, um JavaScript auszuführen, weshalb automatische Tests ein entsprechendes Tool eines Drittanbieters benötigen. Und visuelle Effekte können überhaupt nur von einem Menschen überprüft werden. 
     32 
     33Wenn Sie automatisierte Tests intensiv nutzen wollen, müssen Sie wahrscheinlich eine Kombination all dieser Methoden verwenden. Als Regel sollten Sie sich merken, die Tests einfach und lesbar zu halten. 
     34 
     35>**NOTE** 
     36>Automatisierte Tests vergleichen ein Ergebnis mit der erwarteten Ausgabe. Mit anderen Worten werden Behauptungen (engl. "Assertion") ausgewertet (Ausdrücke wie `$a == 2`). Das Ergebnis einer Behauptung ist entweder wahr (`true`) oder falsch (`false`), wovon abhängt, ob ein Test erfolgreich war oder fehlgeschlagen ist. Das Wort "Assertion" wird häufig verwendet, wenn es um Techniken für automatisierte Tests geht. 
     37 
     38### Testgestützte Entwicklung 
     39 
     40Bei der Testgestützten Entwicklung (engl. Test-Driven Development, TDD) werden die Tests noch vor dem eigentlichen Code geschrieben. Indem Sie die Tests zuerst schreiben, können Sie sich noch vor dem Entwickeln einer Funktion darauf konzentrieren, welche Aufgaben sie erledigen soll. Es handelt sich um eine gute Technik, die auch von anderen Entwicklungsmethoden wie Extreme Programming (XP) empfohlen werden. Außerdem umschifft Sie mit dieser Methode ein nicht zu leugnendes Problem: Wenn Sie Ihre Unit-Tests nicht sofort schreiben, schreiben Sie sie nie. 
     41 
     42Stellen Sie sich vor, Sie müssen eine Funktion zum Beschneiden von Text schreiben. Die Funktion entfernt Leerzeichen an Anfang und Ende des Texts, ersetzt Sonderzeichen durch Unterstriche und wandelt alle Großbuchstaben in Kleinbuchstaben um. Bei der Testgestützten Entwicklung würden Sie zunächst über alle möglichen Fälle nachdenken, und danach für jeden Fall Beispieleingaben und die erwarteten Ausgaben zusammenstellen, wie in Tabelle 15-1 gezeigt. 
     43 
     44Tabelle 15-1 - Eine Liste mit Test-Cases für eine Funktion zum Beschneiden von Text 
     45 
     46Eingabe                 | Erwartete Ausgabe 
     47----------------------- | ----------------------- 
     48`" foo "`               | `"foo"` 
     49`"foo bar"`             | `"foo_bar"` 
     50`"-)foo:..=bar?"`       | `"__foo____bar_"` 
     51`"FooBar"`              | `"foobar`" 
     52`"Foo-bar mich nicht!"` | `"foo_bar_mich_nicht_"` 
     53 
     54Sie würden die Unit-Tests schreiben, sie ausführen und feststellen, dass sie fehlschlagen. Dann würden Sie Code hinzufügen, der den ersten Testcase abhandelt, die Tests erneut ausführen, feststellen, dass nun der erste erfolgreich ist, usw. Wenn schließlich alle Testcases erfolgreich sind, arbeitet die Funktion korrekt. 
     55 
     56Eine Anwendung, die mit TDD erstellt wurde, hat am Ende in etwa so viel Testcode wie tatsächlichen Code. Weil Sie für das Debuggen Ihrer Testcases keine Zeit verschwenden wollen, sollten Sie sie einfach halten. 
     57 
     58>**NOTE** 
     59>Das Refactoring (dt. "Umgestaltung") einer Methode kann neue Fehler einführen, die vorher so nicht aufgetaucht sind. Aus diesem Grund ist es üblich, alle automatisierten Tests laufen zu laseen, bevor ein neues Release einer Anwendung in den Produktivbetrieb entlassen wird - dies wird auch als Regressionstest (engl. Regression Testing) bezeichnet. 
     60 
     61### Das "Lime"-Testframework 
     62 
     63In der PHP-Welt gibt es einige Frameworks für Unit-Tests, z.B. PhpUnit oder SimpleTest. Symfony besitzt sein eigenes namens `lime`. Es basiert auf der Perl-Bibliothek `Test::More` und ist TAP-konform, was bedeutet, dass die Ausgaben gemäß des Test Anything Protocols angezeigt werden, welches für bessere Lesbarkeit von Testausgaben gestaltet wurde. 
     64 
     65Lime unterstützt Sie bei Unit-Tests. Es ist einfacher als andere PHP-Testframeworks und mehrere Vorteile: 
     66 
     67  * Es started die Testdateien in einer abgeschlossenen Umgebung ("Sandbox"), um seltsame Seiteeffekte zwischen den einzelnen Testläufen zu vermeiden. Nicht alle Test-Frameworks garantieren eine saubere Umgebung für jeden Testlauf. 
     68  * Lime-Tests sind äußerst leserlich, genauso wie ihre Ausgabe. Bei entsprechenden Systemvoraussetzungen verwendet Lime farbige Ausgabe, um wichtige Informationen hervorzuheben. 
     69  * Symfony selbst verwendet Lime-Tests als Regressionstests, und somit finden Sie viele Beispiele für Unit- und Funktionalitätstests im Sourcecode von Symfony. 
     70  * Lime selbst wird ebenfalls durch Unit-Tests überprüft. 
     71  * Es ist komplett in PHP geschrieben, sauber implementiert und schnell. Und es besteht nur aus einer einzigen Datei, `lime.php`, ohne weitere Abhängigkeiten. 
     72 
     73Die diversene Tests in den nächsten Abschnitten verwenden die Syntax von Lime. Sie funktionieren ohne weitere Anpassung in jeder Symfony-Installation. 
     74 
     75>**NOTE** 
     76>Unit- und Funktionalitätstests sind nicht dazu gedacht, in einer Produktivumgebung ausgeführt zu werden. Sie sind Entwicklungswerkzeuge und sollten als solche auch nur auf dem Computer des Entwicklers laufen, nicht auf dem Server. 
     77 
     78Unit-Tests 
     79---------- 
     80 
     81Symfonys Unit-Tests sind einfache PHP-Dateien, die auf `Test.php` enden und im Verzeichnis `test/unit/` innerhalb Ihres Projekts liegen müssen. Ihre Syntax ist einfach und lesbar. 
     82 
     83### Wie sehen Unit-Tests aus? 
     84 
     85Listing 15-1 zeigt eine typische Abfolge eines Unit-Tests für die Funktion `strtolower()`. Es beginnt mit der Instantiierung des `lime_test`-Objekts (im Augenblick müssen Sie sich noch keine Gedanken über die Parameter machen). Jeder Unit-Test besteht aus einem Aufruf einer Methode der Instanz von `lime_test`. Der letzte Parameter dieser Methoden ist stets ein optionaler Zeichenkette, der als Ausgabe dient. 
     86 
     87Listing 15-1 - Beispieldatei für einen Unit-Test, in `test/unit/strtolowerTest.php` 
     88 
     89    [php] 
     90    <?php 
     91 
     92    include(dirname(__FILE__).'/../bootstrap/unit.php'); 
     93    require_once(dirname(__FILE__).'/../../lib/strtolower.php'); 
     94 
     95    $t = new lime_test(7, new lime_output_color()); 
     96 
     97    // strtolower() 
     98    $t->diag('strtolower()'); 
     99    $t->isa_ok(strtolower('Foo'), 'string', 
     100        'strtolower() gibt einen String zurück'); 
     101    $t->is(strtolower('FOO'), 'foo', 
     102        'strtolower() formt die Eingabe in Kleinbuchstaben um'); 
     103    $t->is(strtolower('foo'), 'foo', 
     104        'strtolower() lässt Kleinbuchstaben unverändert'); 
     105    $t->is(strtolower('12#?@~'), '12#?@~', 
     106        'strtolower() lässt Sonderzeichen unverändert'); 
     107    $t->is(strtolower('FOO BAR'), 'foo bar', 
     108        'strtolower() lässt Leerzeichen bestehen'); 
     109    $t->is(strtolower('FoO bAr'), 'foo bar', 
     110        'strtolower() kommt mit gemischter Groß- und Kleinschreibung zurecht'); 
     111    $t->is(strtolower(''), 'Nichts', 
     112        'strtolower() formt Leerstrings zu Nichts um'); 
     113 
     114Führen Sie den Test von der Kommandozeile über den `test-unit`-Task aus. Die Ausgabe auf der Kommandozeile ist sehr ausführlich und hilft Ihnen, zu ermitteln, welche Tests fehlgeschlagen sind und welche erfolgreich waren. Die Ausgabe der Beispieltests sehen Sie in Listing 15-2. 
     115 
     116Listing 15-2 - Starten eines einzelnen Unit-Tests von der Kommandozeile 
     117 
     118    > symfony test-unit strtolower 
     119 
     120    1..7 
     121    # strtolower() 
     122    ok 1 - strtolower() gibt einen String zurück 
     123    ok 2 - strtolower() formt die Eingabe in Kleinbuchstaben um 
     124    ok 3 - strtolower() lässt Kleinbuchstaben unverändert 
     125    ok 4 - strtolower() lässt Sonderzeichen unverändert 
     126    ok 5 - strtolower() lässt Leerzeichen bestehen 
     127    ok 6 - strtolower() kommt mit gemischter Groß- und Kleinschreibung zurecht 
     128    not ok 7 - strtolower() formt Leerstrings zu Nichts um 
     129    #     Failed test (.\batch\test.php at line 21) 
     130    #            got: '' 
     131    #       expected: 'foo' 
     132    # Looks like you failed 1 tests of 7. 
     133 
     134>**TIPP** 
     135>Das `include`-Statement am Anfang von Listing 15-1 ist optional. Es sorgt allerdings dafür, dass die Testdatei ein unabhängiges PHP-Script wird, das Sie auch ohne das Kommandozeilenwerkzeug von Symfony starten können, indem Sie `php test/unit/strtolowerTest.php` aufrufen. 
     136 
     137### Methoden für Unit-Tests 
     138 
     139Das `lime_test`-Objekt besitzt eine Reihe von Testmethoden, die in Tabelle 15-2 aufgeführt sind. 
     140 
     141Tabelle 15-2 - Methoden des `lime_test`-Objekts für Unit-Tests 
     142 
     143Methode                                     | Beschreibung 
     144------------------------------------------- | ------------------------------------------------------------------------------------------------ 
     145`diag($msg)`                                | Gibt einen Kommentar aus, ohne einen Test auszuführen 
     146`ok($test, $msg)`                           | Testet eine Bedingung und ist erfolgreich, wenn sie wahr ist 
     147`is($value1, $value2, $msg)`                | Vergleicht zwei Werte und ist erfolgreich, wenn sie identisch sind (`==`) 
     148`isnt($value1, $value2, $msg)`              | Vergleicht zwei Werte und ist erfolgreich, wenn diese verschieden sind 
     149`like($string, $regexp, $msg)`              | Testst eine Zeichenkette gegen einen Regulären Ausdruck 
     150`unlike($string, $regexp, $msg)`            | Prüft, ob eine Zeichenkette nicht auf einen Regulären Ausdruck passt 
     151`cmp_ok($value1, $operator, $value2, $msg)` | Vergleicht zwei Argumente mit einem bestimmten Operatoren 
     152`isa_ok($variable, $type, $msg)`            | Prüft den Variablentyp des Arguments 
     153`isa_ok($object, $class, $msg)`             | Prüft die Klasse eines Objekts 
     154`can_ok($object, $method, $msg)`            | Prüft die Verfügbarkeit einer Methode in einem Objekt oder einer Klasse 
     155`is_deeply($array1, $array2, $msg)`         | Prüft, ob zwei Arrays die gleichen Werte enthalten 
     156`include_ok($file, $msg)`                   | Prüft, ob eine Datei existiert und ob sie korrekt inkludiert ist 
     157`fail()`                                    | Schlägt immer fehl - nützlich zum Testen von Exceptions 
     158`pass()`                                    | Ist immer erfolgreich - nützlich zum Testen von Exceptions 
     159`skip($msg, $nb_tests)`                     | Überspringt eine Anzahl von `$nb_tests` Tests - nützlich bei Tests, die von Bedingungen abhängen 
     160`todo()`                                    | Zählt als Test - nützlich für Tests, die noch nicht geschrieben wurden 
    12161}}}