Präsentation herunterladen
Die Präsentation wird geladen. Bitte warten
1
PHP Testing
2
Einführung
3
Eigenschaften von guten Tests
Korrekt Schnell Isoliert ausführbar Wartbar Begrenzt einfach durchführbar Dokumentation korrekt: Die Test müssen in sich fehlerfrei sein und zu den Anforderungen passen. schnell: Die Tests müssen schnell laufen, um häufig durchgeführt werden zu können. abgeschlossen: Die Tests müssen ein klares Ergebnis liefern und dürfen keine Interpretation benötigen. isoliert: Die Tests müssen unabhängig von anderen Tests durchführbar sein und dürfen andere Tests nicht beeinflussen. sprechend: Die Tests sollten ihre Absicht durch sprechende Benennung kundtun (wie etwa beim BDD). wartbar: Die Tests sollten den Regeln für sauberen Code folgen und sich leicht an den veränderten Produktivcode anpassen lassen. begrenzt: Die Tests sollten jeweils nur einen kleinen Bereich des Testobjekts prüfen (und nicht etwa mehrere Methoden gleichzeitig). einfach durchführbar: Die Tests müssen so einfach wie möglich (am besten auf Knopfdruck) durch einen beliebigen Entwickler durchführbar sein.
4
Was soll getestet werden
Coordinators: CAB Translator classes Nicht immer Unit Test sinnvoll => Integration Tests stattdessen
5
Strategie für Legcy Code ohne Tests
Time Box für Legacy Code nicht generell alten, schlechten Code testen Legacy Tests über Bugs Bug -> Repro ->Test -> Fix Testabdeckung an der richtigen Stelle Unit oder Integration oder End to End-Test
6
Testbarer Code: Clean Code
Funktionen sollte sehr klein sein, kaum länger als 20 Zeilen. Alle Funktionen die länger sind, lassen sich zu kleineren Funktionen refakturieren Einrückungstiefe nicht mehr als 2 Ebenen sie sollten eine Aufgabe erledigen besten falls kein Funktionsargument und höchstens 2 bis 3 Argumente Kein Flag-Funktionsargumente
7
Probleme Keine Hilfe / Dokumentation Nicht wartbar Kein Mehrwert
Besser: Nicht die Funktionen Mocken => test für andere Funktionen werden überflüssig
8
Learnings des Testing kurs
9
AAA Pattern <?php public function testTwoIsEven(){ } //Arrange
$sut = new OddEven(); //Act $actualResult = $sut->IsEven(2); //Assert $this->assert(true, $result); } Wie schreibt man am besten einen Test? Arrange all necessary preconditions and inputs. Act on the object or method under test. Assert that the expected results have occurred. Vorteile: klare Trennung von Was wird getestet Setup des Tests Verifikation des Testergebnisses Vermeidung: Act und Assertion Mix Überladung von Tests, die zu viel auf einmal testen
10
Testdaten generieren IST-Stand: Im Provider $flight = new Flight();
$flight->carrier = „AB“; $flight2 = new Flight(); $flight2->carrier = “EY”;
11
Testdaten: Object Mother Pattern
Auslagern in Funktion, die alle benutzen Private function getFlugdaten($carrier) ->schlecht, wenn viele Varianten, gut wenn nur eine Default Variante benötigt wird
12
Testdaten: Databuilder Pattern
Class FlugDatenBuilder{ Private $number; Public function setNumber($number){ $this->number = $number; } Public function build(){ $flugDaten = new FlugDaten(); $flugDaten->number = $number; Return $flugDaten; Wieso nicht extens
13
Datenbank Integration Tests: Fixtures
Löschen der alten Daten Erzeugen der gebrauchten Daten Testen mit den Daten -> so kann man analysieren am Ende, was in der DB steht, wenn der Test fehlschlägt ->eigene DB für Tests notwendig
14
Datenbank testen Transport Objekte helfen beim testen mit der Datenbank Möglichkeit 1: Objektrelationaler Mapper, z.B. Doctrine oder Propel Möglichkeit 2: PDOStatement::fetchObject public mixed PDOStatement::fetchObject ([ string $class_name = "stdClass" [, array $ctor_args ]] ) $pdos = $this->dBase->prepare('SELECT user_id AS objectId, name, description, password, active, created, last_update AS lastUpdate FROM user WHERE user_id = :id'); $pdos->bindParam(':id', $userId, \PDO::PARAM_INT); $pdos->execute(); return $pdos->fetchObject('\DomainObjects\User', array($this->password));
15
Dont‘s Evil PHP: exit(); die(); Warum?
Führt auch zum abbrechen des Tests, Exceptions benutzen
16
Dependency Handling Best: Dependency Injection
Ansonsten Best Practice: Constructor Injection Class object{ private $db public function __construct($db){ $this->db = $db; } -> das Objekt brauch nicht gemockt werden, sondern kann mit den gewünschten Abhängigkeiten initialisiert werden
17
Kein Mock Testing Tests werden nicht auf einem Mock ausgeführt, sondern auf dem zu testenden Objekt Andernfalls wird nicht unter realen Bedingungen getestet Nicht der Mock soll getestet werden
18
CAB Exception Testing Was kann zu Fehlern führen hier? try { $mock->doSomething($data); } catch (\Exception $e) { $this->assertEquals($exception, $e); } Was ist an diesem Code Exception => zu allgemein, Fehlermeldung werden unterdrückt Assertion gehört in den PHPDoc, weil wenn keine Exception fliegt, der Test nicht fehlert -> Dazu muss die Excpetion einen eigenen Testcase erhalten
20
Regex auch möglich, aber nicht gleichzeitig anwendbar!
21
Was kann zu Fehlern führen hier?
try { $mock->doSomething($data); } catch(\AmadeusAddServicesToCartException$e) { $this->assertEquals($exception, $e); }
23
Zeitabhängige Funktionen testen
Funktionalität, die new Datetime benutzt -> auslagern und mocken getDatetime
24
Private Funktionen Achtung: sind nicht mock-bar
Sollten aber auch nicht getestet werden, genauso wie public, also können wieder benutzt werden!
25
Keine geskippten Tests
Reparieren statt skippen Jetzt Laufen alle Wenn Fehler auftretten in Teamcity -> sofort fixen Sofortiges Feedback notwendig
26
CAB Verbesserungen Keine protected/private Methoden testen
Integration Tests, End-To-End Tests in Agreements Benutzen des Original Objects zum Testen, nicht des Mocks So wenig expects() und willReturns() wie möglich um flexible Tests zu haben Nicht mehr ein Test pro Methode, Exceptions werden in extra Test getestet Kein UnitTestGenerator mehr Dev-Datenbank anlegen mit uid im DB-Namen NameSpacing für Tests, damit sich Unit, Integration und SystemTests nicht in die Quere kommen Testdaten generieren mit Databuildern Tools nutzen: DBUnit Update auf PHPUnit 6, inkl. Namespacing PHPUnit Kata 2 Stunden im Programmierraum möglich wie im Workshop
27
Test Driven Development TDD
28
TDD: Red-Green-Refactor
Schreibe einen Test, bevor du Code für das Produktivsystem verfasst. Schreibe nur so viel Code für den Test, wie du für das Nichtbestehen des Tests benötigst (oder für das fehlgeschlagene Kompilieren) Schreibe nur so viel Code, wie es für den aktuellen Testfall und dessen Bestehen hinreichend ist. Robert C. Martin (Uncle Bob) The Three Rules Of TDD. Sehr kurze Coding Zyklen: Auch Red-Green-Refactor bezeichnet wird Test schreiben: Test schlägt fehl und wird rot markiert. Produktivcode schreiben und in das Produktivsystem integrieren: Test wird bestanden und wird grün markiert. Refactoring Loop: Der Code wird Schritt für Schritt erweitert, ergänzt und neu strukturiert. Entsprechende Testfälle und die zugehörigen Codebestandteile werden geschrieben. Sie durchlaufen den Zyklus erneut
29
Beispiel TDD Aufgabe: Erstellen einer Klasse „NumberCalculator“ mit einer öffentlichen Methode „add“ Eingabeparameteranzahl: 0, 1 oder 2 Rückgabe: die Summe der Eingabeparameter als Ergebnis zurück gibt. Wenn kein numerischer Wert übergeben wird, dann Exception werfen 0 Eingabeparameter gibt „0“ zurück als Ergebnis
30
1. Schritt Start mit dem einfachsten Tests Make it red!
32
2. Schritt Implementieren der Logik im Produktions Code Make it green!
34
3. Schritt Eine Funktionalität hinzufügen: Make it red!
Bei einem Eingabeparameter, wird der Eingabeparameter zurückgegeben Make it red!
36
4. Schritt Implementieren des Produktions Code Make it green
38
5.Schritt 2. Parameter hinzufügen Make it red!
40
6.Schritt Implementieren des Produktions Code Make it green
42
7.Schritt Ausnahmen prüfen Exception Handling Make it red!
44
8.Schritt Implementieren des Produktions Code Make it green
46
9. Schritt: Refactoring
Ähnliche Präsentationen
© 2025 SlidePlayer.org Inc.
All rights reserved.