PHPUnit und die auf Eclipse basierende PHP-IDE PDT

Im folgenden Text wird beschrieben, wie man das UnitTest Framework PHPUnit 3.0.3 manuell (ohne PEAR)
unter Windows installiert und im auf Eclipse basierenden
PDT (PHP Development Tool) einbindet.

Requirements:

Es empfihelt sich hier, jeweils die aktuellste Version herunter zu laden. Bei XDebug muss man eventuell ein paar
Versionen testen, da jede PHP-Version ihr eigenes XDebug-Modul braucht.

Installation

Nachdem man die jeweils aktuellste Version heruntergeladen hat, entpackt man die Archive in separate temporäre Verzeichnisse.
Das Eclipse-Verzeichnis (von PDT) verschiebt man nun in sein Programmverzeichnis (z.B. „D:\Programme\Eclipse“).
Das PHPUnit-Verzeichnis verschiebt man nun an eine beliebige Stelle. Eine vermeintlich sinnvolle Stelle wäre D:\Programme\Eclipse\frameworks\PHPUnit3.
Dieses Verzeichnis muss nun in die Umgebungsvariable PATH eingetragen werden. Hierzu macht man einen Rechtsklick auf den
Arbeitsplatz und wählt dann „Eigenschaften“ aus. In dem neuen Fenster wählt man dann den Reiter/die Registerkarte „Erweitert“ aus, wo man dann
auf den Button „Umgebungsvariablen“ klickt. Hier sind nun zwei Felder zu sehen:

  • oben: Umgebungsvariablen des angemeldeten Benutzers
  • unten: Umgebungsvariablen des Systems

Man kann die PATH-Variable in beiden Feldern ändern. Wenn man der einzige Benutzer des Systems ist und Administratorrechte hat, dann empfiehlt sich, die PATH-Variable des Systems anzupassen. Anderenfalls die des aktuellen Benutzers (gilt tatsächlich ausschließlich für den aktuell angemeldeten Benutzer!).
Im System-Fenster sollte schon eine entsprechende Variable vorhanden sein. Diese wählt man aus und klickt auf „Bearbeiten“. Sollte sie nicht vorhanden sein (in den meisten Fällen ist dem so im Benutzer-Fenster), dann klickt man auf „Neu“, trägt in der obersten Zeile „PATH“ ein (ohne die Anführungszeichen) und unten den Pfad zum PHPUnit-Verzeichnis (z.B. „D:\Programme\Eclipse\PHPUnit3“).
Der Vollständigkeit halber fügen wir noch den „.“ hinzu, der für das aktuelle Verzeichnis steht. Demnach sollte die PATH-Variable in unserem Fall wie folgt aussehen:

.;D:\Programme\Eclipse\PHPUnit3

Nun klickt man auf „OK“ und die Einstellungen sollten übernommen sein. Als nächstes verschiebt man die XDebug.dll in das PHP-Verzeichnis von PDT.
Dieses befindet sich in unserem Fall hier:

D:\Programme\eclipse\plugins\org.zend.php.debug.debugger.win32.x86_0.1.7\resources\php5

In dem gleichen Verzeichnis befindet sich auch die php.ini, die noch editiert werden muss. Hier müssen einige Pfade angegeben werd.
Zunächst setzen wir ein „;“ vor die Zeile „zend_extension_ts=.\ZendDebugger.dll“. Damit deaktivieren wir die Zend-Extension, da XDebug damit nicht kompatibel ist.
Damit der PHP-Interpreter das Verzeichnis von PHPUnit findet, muss dies in der php.ini mit „ini_path“ festgelegt werden:

ini_path=“D:\Programme\eclipse\frameworks\PHPUnit3″

Damit PHPUnit seine Scripte findet, muss der „include_path“ noch gesetzt werden. Hier werden folgende Verzeichnisse angegeben:

  • Pfad zum PHPUnit-Hauptverzeichnis: D:\Programme\eclipse\frameworks\PHPUnit3
  • Pfad zum Eclipse Workspace: C:\Dokumente und Einstellungen\redbrick\workspace\myWebProjekt
  • Pfad zu den Tests: C:\Dokumente und Einstellungen\redbrick\workspace\myWebProjekt\tests

Diese Pfade werden mit einem „;“ separiert und in die gleiche Zeile geschrieben.
Zum Schluss muss noch das XDebug-Modul geladen werden. Dazu setzt man den Parameter zend_extension_ts und setz den Pfad zur php_xdebug.dll:

"D:\Programme\eclipse\plugins\org.zend.php.debug.debugger.win32.x86_0.1.7\ resources\php5\php_xdebug.dll"

Die Beispiel php.ini zum hier verwendeten Szenario gibt es hier.

Damit PDT (oder man selber aus der Windows-Konsole heraus) direkt PHPUnit aufrufen kann, wird mit dem Framework eine entsprechende Batchdatei mitgeliefert.
Diese befindet sich in dem Hauptverzeichnis von PHPUnit und heißt „pear-phpunit.bat“. Hier müssen ein paar Änderungen vorgenommen werden.

  • „@php_bin@“ muss jeweils durch den exakten Pfad zum PHP-Parser (php.exe) ersetz werden
  • „@php_dir@“ muss durch den exakten Pfad zum Hauptverzeichnis von PHPUnit ersetzt werden

Die Beispiel phpunit.bat zum hier verwendeten Szenario gibt es hier.

Jetzt wird als letztes noch das PHPUnit Framework in PDT (Eclipse) eingebunden. Dazu startet man zunächst Eclipse, erstellt ein neues PHP Projekt (File -> New -> PHP Projekt). In diesem neuen Projekt wird nun das Include-Verzeichnis angepasst:

  • Rechtsklick auf das neue Projekt
  • Configure Include Path
  • In dem Reiter/der Registrierkarte Libraries klickt man auf „Add Variable…“
  • „Configure Variables“
  • „New…“
  • Name: PHPUnit3
  • „Folder…“
  • Zum PHPUnit-Hauptverzeichnis durchklicken (D:\Programme\eclipse\frameworks\PHPUnit3) und bestätigen

Damit wäre die Installation und Konfiguration abgeschlossen und man kann seine UnitTests schreiben.

Beispiel UnitTest: Taschenrechner

Ich gehe hier von einem trivialen Beispiel eines simplen Taschenrechners aus. Hier die Verzeichnisstruktur:

myPhpProjekt\
            |
             - tests\
            |       |
            |        - CalcTest.php
            |
             - Calc.php

Die folgende Klasse mit ihren 6 Methoden/Funktionen befindet sich in der Datei Calc.php, welche sich im Hauptverzeichnis des PHP-Projektes befindet.

class Calc
{
	/**
	 * Speichert das Resultat der Rechenoperationen
	 */
	public $result = NULL;

	/**
	 * Methode/Funktion zum Addieren zweier Zahlen
	 *
	 * @param $var1 Summand 1
	 * @param $var2 Summand 2
	 * @return $result Die Summe der Addition
	 */
	public function add($var1, $var2)
	{
		$result = $var1 + $var2;
		return $result;
	}

	/**
	 * Methode/Funktion zum Subtrahieren zweier Zahlen
	 *
	 * @param $var1 Minuend
	 * @param $var2 Subtrahend
	 * @return $result Die Differenz der subtraktion
	 */
	public function sub($var1, $var2)
	{
		$result = $var1 - $var2;
		return $result;
	}

	/**
	 * Methode/Funktion zum Multiplizieren zweier Zahlen
	 *
	 * @param $var1 Faktor 1
	 * @param $var2 Faktor 2
	 * @return $result Das Produkt der Multiplikation
	 */
	public function mult($var1, $var2)
	{
		$result = $var1 * $var2;
		return $result;
	}

	/**
	 * Methode/Funktion zum Dividieren zweier Zahlen
	 *
	 * @param $var1 Dividend
	 * @param $var2 Divisor
	 * @return $result Der Quotient der Division
	 */
	public function divide($var1, $var2)
	{
		$result = $var1 / $var2;
		return $result;
	}

	/**
	 * Methode/Funktion um das letzte Ergebnis einer Rechenoperation auszulesen
	 *
	 * @return $result if it is set - otherwhise returns false
	 */
	public function getResult()
	{
		if($result != NULL) return $result;
		else return false;
	}

	/**
	 * Methode/Funktion um das letzte Ergebnis zurück zu setzen
	 */
	public function resetResult()
	{
		$this->result = NULL;
	}
}

Die oben angegebene Klasse soll jetzt getestet werden. Dies macht man mit der Datei CalcTest.php, die sich im Verzeichnis „tests“ innerhalb des PHP-Projektes befindet.

/* include the required files */
require_once 'PHPUnit/Framework/TestCase.php';
require_once 'PHPUnit/TextUI/TestRunner.php';
require_once 'Calc.php';

if (!defined('PHPUnit_MAIN_METHOD')) {
    define('PHPUnit_MAIN_METHOD', 'TestCalc::main');
}

class CalcTest extends PHPUnit_Framework_TestCase
{
	/**
	 * Main-Methode zum direkten Starten der Tests
	 */
	public static function main()
	{
		require_once 'PHPUnit/Framework.php';
        	require_once "PHPUnit/TextUI/TestRunner.php";

        	$suite  = new PHPUnit_Framework_TestCase("Calc Test");
        	$result = PHPUnit_TextUI_TestRunner::run($suite);
	}

	private $myCalc;

	/**
	 * Methode zum Erstellen eines Objektes, das getestet werden soll.
	 * Wird vor jedem einzelnen Test aufgerufen -> immer ein frisches Objekt!
	 */
	protected function setUp()
	{
		$this->myCalc = new Calc;
	}

	/**
	 * Funktionstes der Methode add(var1, var2)
	 */
	public function testAdd()
	{
		$this->assertEquals(5, $this->myCalc->add(3,2));
	}

	/**
	 * Funktionstes der Methode sub(var1, var2)
	 */
	public function testSub()
	{
		$this->assertEquals(5, $this->myCalc->sub(10,5));
	}

 	/**
	 * Funktionstes der Methode mult(var1, var2)
	 */
	public function testmult()
	{
		$this->assertEquals(50, $this->myCalc->mult(10,5));
	}

 	/**
	 * Funktionstes der Methode divide(var1, var2)
	 */
	public function testdivide()
	{
        	$this->assertEquals(2, $this->myCalc->divide(10,5));
	}

	/**
	 * Funktionstes der Methode divide(var1, var2):
	 * Eine Exception muss geworfen werden, wenn versucht wird, durch 0 zu dividieren
	 *
	 * Dieser Test ist noch nicht implementiert: markTestIncomplete('Hinweistext')
	 */
	public function testdivide2()
	{
 		$this->markTestIncomplete('Division durch 0 testen.');
	}

	public function testGetResult()
	{
    		$this->assertEquals(NULL, $this->myCalc->getResult());
	}

	/**
	 * Methode zum Löschen eines Objektes nach dem Test.
	 * Wird nach jedem einzelnen Test aufgerufen
	 */
	protected function tearDown()
	{
    		$this->myCalc = NULL;
	}
}

Die beiden PHP-Dateien gibt es hier im Zip-Format zum Download.

Um die Tests auszuführen, gibt es zwei Möglichkeiten. Zum einen aus Eclipse heraus und zum anderen über die Konsole von Windows.

Aus Eclipse heraus:

  • Rechtsklick auf die Test-Klasse CalcTest.php
  • „Run As“
  • „PHP Script“

Aus der Windows-Konsole
Erstellt in dem Verzeichnis C:\Dokumente und Einstellungen\redbrick\Desktop\testReport einen Report des Testlaufs im HTML-Format

phpunit --verbose --report "C:\Dokumente und Einstellungen\redbrick\Desktop\testReport" CalcTest

Ein Hinweis noch zu der Namenskonvention: Die Test-Klassen sollten immer den Namen der zu testenden Klasse tragen, mit der Erweiterung „Test“. In dem hier verwendeten Beispiel wird die Klasse Calc getestet. Also heißt die Testdatei „CalcTest.php“. Ähnliche Regel gilt für die Methoden/Funktionen. Nur steht hier der Zusatz „test“ VOR dem Namen der zu testenden Methoden/Funktion und nicht dahinter.

Weiterführende Links zum Thema

redbrick (14.10.2009 9:10:17)

Nachtrag zum Howto: Unter http://www.phphatesme.com/blog/tools/phpunit-mittels-pti-in-eclipse-einbinden/ gibt es eine weitere sehr gute Anleitung, um PHPUnit in Eclipse/PDT zu integrieren. Diesmal In Deutsch verfasst.

redbrick (15.07.2009 10:23:54)

Nachtrag zum Howto: Unter http://www.phpunit.de/wiki/Eclipse gibt es eine gute Anleitung, wie man PHPUnit in PDT 2.x integrieren kann. Die Anleitung ist in Englisch verfasst und bezieht sich auf eine Linux Desktop-Umgebung. Aber die Anweisungen sollten für MacOS X und auch Windows gleich sein.