Einführung in PHPUnit unter Windows

Vor zwei Wochen habe ich bereits eine Schritt für Schritt Anleitung zur Installation von PHPUnit unter Windows veröffentlicht und der heutige Artikel baut darauf auf: Wir wollen einen ersten Unit-Test schreiben und diesen anschließend ausführen. Dabei beachten wir auch die Struktur der Unit-Tests, damit später nicht nur einzelne Klassen, sondern die ganze Anwendung getestet werden kann.
Außer einer funktionierenden PHPUnit-Version benötigen wir nichts weiter.

Bevor wir anfangen einen Test zu schreiben, brauchen wir erstmal Code zum Testen. Und weil wir zu faul sind uns ein neues Beispiel auszudenken, nehmen wir einfach die übliche Blog-Anwendung. Für unseren Blog legen wir daher folgende Ordner-Struktur im htdocs-Verzeichnis an:

blog/
blog/app
blog/app/WebUnion
blog/tests
blog/tests/WebUnion

Anschließend erstellen wir eine erste Model-Klasse unter blog/app/WebUnion/Blog.php:

namespace WebUnion;
 
class Blog
{
	protected $posts = array();
 
	public function getPostCount()
	{
		return count($this->posts);
	}
 
	public function getPosts()
	{
		return $this->posts;
	}
 
	public function addPost(array $post)
	{
		$this->potst[] = $post;
		return $this;
	}
}

Viel erklären muss man zu dieser Klasse hoffentlich nicht, allerdings habe ich absichtlich einen kleinen Fehler eingebaut. Die Eigenschaft posts in der addPost()-Methode ist falsch geschrieben. Diesen Fehler wollen wir mit unserem Unit-Test später finden.

Im nächsten Schritt kümmern wir uns um die Struktur unserer Unit-Tests. Da wir später mit einem Befehl die komplette Anwendung testen wollen und nicht jede Klasse einzeln, ist es wichtig die Unit-Tests vernüftig zu organisieren. In PHPUnit geschiet dies über sogenannte Testsuites.
Den Ordner blog/tests haben wir bereits angelegt und hier legen wir nun eine neue Datei phpunit.xml an. Diese XML-Datei beinhaltet die Konfiguration unsere Testsuite.

<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="./TestBootstrap.php">
	<!-- Hier können wir der Testsuite einen Namen geben -->
	<testsuite name="WebUnion.de - PHPUnit Einführung">
		<directory>./</directory>
	</testsuite>
</phpunit>

Als nächstes legen wir die in der XML angegebene Datei blog/tests/TestBootstrap.php an, die nichts weiter tut als das Autoloading der Klassen vorzubereiten.

// Include-Path für unsere Anwendung angeben
set_include_path(implode(PATH_SEPARATOR, array(
	get_include_path(),
	dirname(__DIR__).'/app',
)));
 
// Damit PHPUnit die Klassen automatisch laden kann
require_once 'PHPUnit/Autoload.php';

Jetzt definieren wir die erste Testsuite. Dazu brauchen wir eine neue PHP-Datei blog/tests/AllTests.php:

// Alle Tests und Testsuites einbinden:
require_once 'WebUnion/BlogTest.php';
#require_once 'WebUnion/Foo/AllTests.php';

class AllTests
{
	public static function main()
	{
		PHPUnit_TextUI_TestRunner::run(self::suite());
	}
 
	public static function suite()
	{
		$suite = new PHPUnit_Framework_TestSuite('WebUnion');
		$suite->addTest('WebUnion_BlogTest');
 
		// Hier lassen sich nun weitere Tests oder Unter-Testsuites
		// hinzufügen
		#$suite->addTest('WebUnion_PostTest');
		#$suite->addTestSuite(WebUnion_Foo_AllTests::suite());
	}
}

Die Klasse AllTests sammelt quasi alle Tests und Testsuites, die später ausgeführt werden sollen. Und WebUnion_Foo_AllTests wäre dann genauso aufgebaut wie die Hauptklasse AllTests.

Jetzt kommen wir zum letzten Teil dieser Einführung: Dem eigentlichen Unit-Test. Aus der AllTests-Klasse lässt sich bereits rauslesen, dass wir eine neue Datei blog/tests/WebUnion/BlogTest.php benötigen:

require_once 'WebUnion/Blog.php';
 
class WebUnion_BlogTest extends PHPUnit_Framework_TestCase
{
	public function testPostCount()
	{
		$blog = new \WebUnion\Blog();
		$this->assertEquals(0, $blog->getPostCount());
	}
 
	public function testAddPost()
	{
		$blog = new \WebUnion\Blog();
		$blog->addPost(array(
			'title' => 'Mein erster Blog Post',
			'body' => 'Lorem ipsum dolor sit amet.',
		));
		$blog->addPost(array(
			'title' => 'PHPUnit Einführung',
			'body' => 'WebUnion präsentiert eine Einführung in PHPUnit.',
		));
 
		$this->assertEquals(2, $blog->getPostCount());
	}
}

Was wird hier gemacht?
Zunächst wird die zu testende Klasse eingebunden. Dann folgenden zwei sogenannte Test-Cases testPostCount() und testAddPost(), die unseren Test-Code beinhalten. Hier werden erst einige Testdaten erstellt und anschließend mittels assertEquals() das Ergebnis überprüft.
PHPUnit bietet natürlich noch weitere Assert-Methoden zum Testen der Daten. Unter anderem lassen sich Array-Inhalte überprüfen oder ob eine bestimmte Datei existiert.

Jetzt müssen wir den Test nurn noch starten. Dazu öffnen wir die Konsole (Start > Ausführen > cmd), navigieren zum Tests-Verzeichnis unserer Anwendung und starten PHPUnit:

cd C:\xampp\htdocs\blog\tests
phpunit

Der Befehl phpunit reicht schon aus, um alle unsere definierten Tests zu starten. Nun solltet ihr folgende Ausgabe erhalten:

Wie man sieht hat PHPUnit den Fehler in unserer Blog-Klasse sofort gefunden und zeigt uns natürlich genau an, in welchem Test der Fehler aufgetreten ist. Jetzt müssen wir den Fehler nur noch beheben 😉

Den kompletten Beispiel-Code habe ich auch nochmal als ZIP-Archiv zum Download zusammengestellt.

Ich hoffe ich konnte euch auch mit dem zweiten Tutorial den Einstieg in PHPUnit nochmal erleichtern.

3 Kommentare zu “Einführung in PHPUnit unter Windows

  1. Sehr nett,

    würde mich über etwas mehr freuen, z.B. arbeiten mit der Datenbank oder so 🙂

    Gruß
    Alex

  2. Aber der Aufbau Deiner Beispiel Testsuite ist schon etwas old-skoolig. Empfiehlt sich diese per PHPUnit’s XML Konfiguration zusammenzubauen bzw. zusammenbauen zu lassen.

  3. Hi,

    danke für das Beispiel.
    Bis auf ein paar kleine Fehler funktioniert das ganze – aber mir kommt die Frage ob das wirklich so richtig ist.
    Was soll denn AllTest bewirken? Die Tests werden doch auch ohne dies ausgeführt.

    Gruß, Mark

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.