Facebook
Twitter
Google+
Kommentare
13

PHPUnit – Eine Einführung

Schon lange ist es her, dass ich eine Kolumne veröffentlicht habe. Aus diesem Grund möchte ich gerade Neulingen als auch fortgeschrittenen PHP-Entwicklern helfen sich mit dem Begriff Qualitätssicherung bekannt zu machen.

Informationssammlung
Als am 15. März 2004 PHPUnit von Sebastian Bergmann veröffentlicht wurde, hatte wohl keiner gedacht, dass sich dieses Framework so schnell etablieren würde. xUnit Test Varianten waren zwar auch damals schon bekannt, allerdings noch nicht verbreitet. Im Grunde kam die Idee für die testorientierte Entwicklung aus dem Bereich Java und wurde von Erich Gamma und Kent Beck in die Wege geleitet. Neben Propel nutzt auch Serendipity oder das Zend Framework die PHPUnit Komponente zur Qualitätssicherung.

Der Sinn
Wie auch in anderen Programmiersprachen haben Entwickler auch in PHP mit der Qualität zu kämpfen. Man kennt es: Der Kunde möchte diese Erweiterung, jene Erweiterung und dann am besten noch eine – allerdings vergisst man dabei schnell das eigentliche Ziel des Produktes: Fehlerfreiheit. Kein Software-Entwickler schafft es seine Produktion makellos zu konstruieren. Die Frage dabei lautet aber nicht, wie ich meine Fehler ausbessere, sondern wie ich sie verhindere. Der genannte Schritt passiert nicht während der Entwicklung und auch nicht danach – sondern davor. Zunächst muss die Applikation genau geplant werden, um zu definieren welche Methoden und Klassen benötigt werden, sodass das Ganze am besten via UML erfasst werden kann. Als Devise gilt: Do not build classes or methods without a unit test.

Installation
PHPUnit bietet mehrere Möglichkeiten zur Installation und kann auf jedem System installiert werden, welches einer höheren Version als PHP 4.3.0 entspricht. Im manual des von Sebastian Bergmann entwickelten Frameworks findet man auch Schritte, die einen durch die Installation leiten.

Unser erster Test
Das Test-Framework erlaubt es dem Nutzer über diverse Methoden seine Produktionen zu prüfen. Meist beginnen diese mit assert. In unserem Fall verwenden wir neben assertSame auch assertArrayHasKey und assertObjectHasAttribute.

  • assertSame (assertSame(mixed $expected, mixed $actual[, string $message = “])) prüft ob die übergebenen Variablen dem selben Typ, sowie Wert entsprechen.
  • assertArrayHasKey (assertArrayHasKey(mixed $key, array $array[, string $message = “])) sieht nach, ob in dem übergebenen Array der zuvor deklarierte Schlüssel existiert.
  • assertObjectHasAttribute (assertObjectHasAttribute(string $attributeName, object $object[, string $message = “])) macht im Grunde dasselbe wie assertArrayHasKey. Der Unterschied der beiden Methoden liegt darin, dass assertObjectHasAttribute Klassen prüft.
class PHPHatesMeTest extends PHPUnit_Framework_TestCase
{

    public function testAuthor()
    {
        $author = 'Marc Binder';
        $this->assertSame($author, 'Marc Binder');

    }

    public function testArrayKey()
    {
        $data = array(
            'nickname' => 'MrBoolean',
            'forename' => 'Marc',
            'surname'  => 'Binder'

        );

        $this->assertArrayHasKey('nickname', $data);
        $this->assertArrayHasKey('forename', $data);
        $this->assertArrayHasKey('surname',  $data);
    }

    public function testObjectAttribute()
    {
        $object = new stdClass();
        $object->nickname = 'MrBoolean';
        $object->forename = 'Marc';
        $object->surname  = 'Binder';

        $this->assertObjectHasAttribute('nickname', $object);
        $this->assertObjectHasAttribute('forename', $object);
        $this->assertObjectHasAttribute('surname',  $object);

    }

}

Der Test kann nun ausgeführt werden. Folgendes Resultat wird zurückgeliefert:

PHPUnit 3.4.9 by Sebastian Bergmann.
… Time: 1 second, Memory: 4.25Mb OK (3 tests, 7 assertions)

Abschluss & Weiterführendes

Natürlich sind die oben genannten Methoden noch lange nicht alles was PHPUnit zu bieten hat. Jedoch ist es ein kleiner Einblick in die testgetriebene Entwicklung.

Alles rund um die Assert-Api des PHPUnit Frameworks
Annotations in PHPUnit
Mock-Objects

Natülich ist PHPUnit mit einem Artikel nicht erklärt. Genau deswegen wird dieser Artikel mehrere Teile erhalten, die tiefer in die Komponenten von PHPUnit eingehen.

Über den Autor

Marc Binder

Marc Binder, Senior Software-Engineer bei der EDELWEISS72 GmbH, München. Neben Qualitätsmanagement kümmert er sich um die Entwicklung von Software des eigenen Hauses bzw. von Kunden.
Kommentare

13 Comments

  1. Danke für Deinen Artikel, aber wirklich etwas Neues, was nicht bereits 100-fach im Netz zu finden ist, zeigt er leider nicht.
    Ich freue mich auf Deine tiefergehender Artikelserie und hoffe, dass Du keine „künstlichen“ Beispiele verwenden wirst, sondern jene direkt aus Deinem Entwicklerleben (aus einem Projekt).

    Wie sieht es aus, wenn ich erst Unit-Tests schreibe, bevor der eigene Code geschrieben wird, wie teste ich z. B. einen Webservice, wie meine eigenen Zend-Framework Plugins etc. Bitte einfach keine künstlich konstruierten Klassen / Objekte ala Auto und die üblichen verdächtigen.

    Ich bin gespannt :)

    Reply
  2. Nun ja, es gibt schon ein paar Themen im Umfeld UnitTests. Man kann zeigen wie DataProvider funktionieren, wie man Exceptions testet, die automatische Testgenerierung anschneiden, erklären was es Mocks und Streams sind und wie man mit virtuellen Dateisystemen oder virtuellen Datenbanken testet und die Grenzen von UnitTests aufzeigen – dann ist aber auch langsam wieder Schluss.

    Vielleicht noch als Sahnehäubchen ein paar erbauliche AntiPatterns zur allgemeinen Erheiterung.

    Reply
  3. Was zum Beispiel völig fehlt (wo das ZF angesprochen wurde), wäre mal ein beispielhaftes Projekt inkl. Unit Tests mit dem ZF. Allerdings nützt das ja nicht unbedingt allen Lesern hier etwas :)

    Reply
  4. Hey cool :-) Dieser Artikel hat nun sogar eine Frage beantwortet, wo ich scheinbar bisher immer zu faul war nachzuschauen. Ich hatte mich schon immer gefragt, was genau der Unterschied bei assertEquals() und assertSame() ist. Denken konnte ich es mir schon, aber genau wusste ich es nicht. War, wie schon gesagt, immer zu faul nachzuschauen.

    Reply
  5. Danke für das Feedback. Es ist ein Mehrteiler und die Artikel müssen nun mal etwas kürzer gehalten werden damit ihr sie auch liest 😉

    Stubs und Mocks habe ich im 3. Artikel vor.

    ZF ist nicht das einzige Projekt was mit UnitTests läuft und auch nicht das erste was es wirklich effizient genutzt hat daher wollte ich auch nicht darauf bezug nehmen.

    Der Plan bisher sieht so aus:

    1. Einstieg in PHPUnit
    2. PHPUnit Quereinstieg: Die Testsuite mit XML oder PHP
    3. PHPUnit Quereinstieg: Dataprovider mit XML
    4. PHPUnit Quereinstieg: Mocks und Stubs
    5. PHPUnit Quereinstieg: phpUnderControl

    Und natürlich wird es keine Autotests geben.

    Reply
  6. PHP 5.3 finde ich derzeit noch unnütz, da es noch nicht zum Standart geworden ist. Erst wenn das mal der Fall sein sollte, ist es auch wirklich rentabel Zeit für einen Artikel in diese Richtung zu investieren.

    Das Testing von Funktionen werde ich sicherlich in einen der fünf Artikel unterbringen 😉

    Reply
  7. Ich beschäftige mich auch gerade mit PHPUnit Tests. Ein weites Feld.
    Z.B. das Testen von StreamWrappern oder stark gekoppeltem Code. Abwägungen, ob einige Tests zu Gunsten einer schnelleren Ausführzeit geopfert werden sollten..
    Bin gespannt, wie es wietergeht!

    Reply
  8. Das ganze klingt sehr interessant. Das Testen virtueller Dateisysteme und vorallem virtueller Datenbanken würde mich sehr interessieren.
    Ich freue mich schon auf den Rest der Serie 😀

    Reply
  9. Ich fänd eine kurze Ziel Definition nett, erst redest Du nämlich von Qualitätssicherung und mischst dann Aussagen des TDD ein. Das sind eigentlich 2 verschiedene Paar Schuhe, wobei die Testgetrieben Entwicklung nur einen Stütztpfeiler innerhalb der QS darstellt.

    Wieso ist es am besten ein Projekt per UML zu planen? Und wieso ist das Ziel eines Projektes „Fehlerfreiheit“? Also mir ist schon klar, das jeder Artikel eine Einleitung braucht 😉 aber ich wir leben auch nicht auf dem akademischen Spielplatz: es gibt Deadlines, Abnahmephasen, Service Verträge… deswegen fänd ich es schön, solche Aussagen auch zu untermauern.

    Reply

Leave a Comment.

Link erfolgreich vorgeschlagen.

Vielen Dank, dass du einen Link vorgeschlagen hast. Wir werden ihn sobald wie möglich prüfen. Schließen