Tests sind sinnvoll! Das hat jeder schon mal gehört und dann halt auch mal paar Tests geschrieben. War das dann schon „Test-getriebene Entwicklung“ (TDD)? Nein! Also was steckt dann tatsächlich dahinter? Wir werden das im Laufe dieses Artikels anhand des Katas zur Primfaktorenzerlegung durchspielen.
Grundregeln des TDD
- Du darfst keinen Produktiv-Code schreiben, solange du keinen Test geschrieben hast, der fehlschlägt.
- Du darfst nicht mehr Test-Code schreiben als für einen Fehlschlag notwendig ist. E_FATAL ist dabei ebenfalls schon ein Fehlschlag.
- Du darfst nicht mehr Produktiv-Code schreiben als notwendig ist um alle Tests zu bestehen.
Sich an diese Regeln zu halten, ist in der Praxis ziemlich schwer, und ihr werdet euch am Anfang recht dämlich dabei vorkommen. Ihr schreibt dann nämlich eine Zeile Test-Code und eine Zeile Produktiv-Code im ständigen Wechsel.
Vorbedingungen
Bevor es los geht legen wir eine phpunit.xml und eine bootstrap.php an. In laufenden Projekten sollte beides schon vorhanden sein, hier nur der Vollständigkeit halber.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<?xml version="1.0" encoding="UTF-8"?> <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd" backupGlobals="false" colors="true" bootstrap="bootstrap.php"> <testsuites> <testsuite name="Project Test Suite"> <directory>tests</directory> </testsuite> </testsuites> <filter> <whitelist> <directory>src</directory> </whitelist> </filter> </phpunit> |
Die bootstrap.php ist zunächst noch leer. Wir haben ja noch kein „Projekt“.
Der erste Test
Achtung, jetzt kommt der härteste Teil, also durchhalten, gleich ergibt es Sinn!
1 2 3 4 5 6 7 8 9 10 11 |
namespace TDD\Test; use TDD\App\PrimeFactors; class PrimeFactorsTest extends \PHPUnit_Framework_TestCase { public function testPrimeFactors() { $primeFactors = new PrimeFactors(); } } |
1 |
Fatal error: Class 'TDD\Test\PrimeFactors' not found |
Laut Regel 1 dürfen wir keinen Produktiv-Code schreiben, ohne das ein Test das erforderlich macht. Und laut Regel 2 dürfen wir nicht mehr Test-Code schreiben als für einen Fehlschlag notwendig. Tja und da wir ja überhaupt noch nichts haben, ist bereits die Nennung der Klasse direkt ein E_FATAL also ein Fehlschlag.
Also gut, jetzt dürfen wir aber endlich mal anfangen mit „echtem“ Code, oder? Ja, aber nicht euphorisch werden, das hier reicht völlig:
1 2 3 4 5 6 |
namespace TDD\App; class PrimeFactors { } |
In die bootstrap.php packen wir noch unseren ausgeklügelten Autoloader 😉
1 |
require_once 'src'.DIRECTORY_SEPARATOR.'PrimeFactors.php'; |
Et voila: OK (1 test, 0 assertions)
Das war auch schon alles, was wir laut Regel 3 machen durften.