Sebastian Bergmann, Stefan Priebsch
Softwarequalität in PHP-Projekten
Inhaltsverzeichnis
6
Geleitwort
16
Vorwort
18
Teil I Grundlagen
26
Kapitel 1 Software-Qualität
28
1.1 Was ist Software-Qualität
28
1.1.1 Externe Qualität
29
1.1.2 Interne Qualität
30
1.2 Technical Debt
31
1.3 Konstruktive Qualitätssicherung
33
1.4 Sauberer Code
34
1.4.1 Explizite und minimale Abhängigkeiten
34
1.4.2 Klare Verantwortlichkeiten
35
1.4.3 Keine Duplikation
35
1.4.4 Kurze Methoden mit wenigen Ausführungszweigen
35
1.5 Software-Metriken
35
1.5.1 Zyklomatische Komplexität und NPath-Komplexität
36
1.5.2 Change Risk Anti-Patterns (CRAP) Index
36
1.5.3 Non-Mockable Total Recursive Cyclomatic Complexity
37
1.5.4 GlobalMutable State
37
1.5.5 Kohäsion und Kopplung
38
1.6 Werkzeuge
38
1.7 Fazit
41
Kapitel 2 Testen von Software
42
2.1 Black-Box- und White-Box-Tests
42
2.2 Wie viele Tests braucht man?
43
2.3 Systemtests
45
2.3.1 Testen im Browser
45
2.3.2 Automatisierte Tests
46
2.3.3 Testisolation
48
2.3.4 Akzeptanztests
49
2.3.5 Grenzen von Systemtests
50
2.4 Unit-Tests
50
2.4.1 Rückgabewerte
53
2.4.2 Abhängigkeiten
55
2.4.3 Seiteneffekte
56
2.5 Praxisbeispiel
57
2.5.1 Den zu testenden Code analysieren
61
2.5.2 Eine Testumgebung aufbauen
62
2.5.3 Globale Abhängigkeiten vermeiden
65
2.5.4 Unabhängig von Datenquellen testen
66
2.5.5 Asynchrone Vorgänge testen
74
2.5.6 Änderungen in der Datenbank speichern
79
2.5.7 Nicht vorhersagbare Ergebnisse
81
2.5.8 Eingabedaten kapseln
84
2.5.9 Weiterführende Überlegungen
86
2.6 Fazit
87
Teil II Best Practices
88
Kapitel 3 TYPO3: die agile Zukunft eines schwergewichtigen Projekts
90
3.1 Einführung
90
3.1.1 Die Geschichte von TYPO3 – 13 Jahre in 13 Absätzen
90
3.1.2 Den Neuanfang wagen!
92
3.1.3 Unsere Erfahrungen mit dem Testen
93
3.2 Grundsätze und Techniken
94
3.2.1 Bittersüße Elefantenstückchen
95
3.2.2 Testgetriebene Entwicklung
96
3.2.3 Tests als Dokumentation
97
3.2.4 Kontinuierliche Integration
98
3.2.5 Sauberer Code
99
3.2.6 Refaktorierung
101
3.2.7 Programmierrichtlinien
102
3.2.8 Domänengetriebenes Design
103
3.3 Vorgehen bei der Entwicklung
104
3.3.1 Neuen Code entwickeln
104
3.3.2 Code erweitern und ändern
105
3.3.3 Code optimieren
106
3.3.4 Fehler finden und beheben
108
3.3.5 Alten Code fachgerecht entsorgen
108
3.4 Testrezepte
109
3.4.1 Ungewollt funktionale Unit-Tests
109
3.4.2 Zugriffe auf das Dateisystem
110
3.4.3 Konstruktoren in Interfaces
111
3.4.4 Abstrakte Klassen testen
112
3.4.5 Testen von geschützten Methoden
113
3.4.6 Verwendung von Callbacks
116
3.5 Auf in die Zukunft
117
Kapitel 4 Bad Practices in Unit-Tests
120
4.1 Einführung
120
4.2 Warum guter Testcode wichtig ist
120
4.3 Bad Practices und Test-Smells
121
4.3.1 Duplizierter Testcode
122
4.3.2 Zusicherungsroulette und begierige Tests
124
4.3.3 Fragile Tests
127
4.3.4 Obskure Tests
129
4.3.5 Lügende Tests
137
4.3.6 Langsame Tests
138
4.3.7 Konditionale Logik in Tests
139
4.3.8 Selbstvalidierende Tests
141
4.3.9 Websurfende Tests
142
4.3.10 Mock-Overkill
144
4.3.11 Skip-Epidemie
145
4.4 Fazit
146
Kapitel 5 Qualitätssicherung bei Digg
148
5.1 Die Ausgangssituation
148
5.1.1 Unsere Probleme
148
5.1.2 Code-Altlasten
149
5.1.3 Wie lösen wir unsere Probleme?
151
5.1.4 Ein Test-Framework wählen
153
5.1.5 Mit einem Experten arbeiten
153
5.2 Das Team trainieren
154
5.3 Testbaren Code schreiben
158
5.3.1 Statische Methoden vermeiden
158
5.3.2 Dependency Injection
161
5.4 Mock-Objekte
162
5.4.1 Überblick
162
5.4.2 Datenbank
162
5.4.3 Lose gekoppelte Abhängigkeiten
163
5.4.4 Beobachter für klasseninternes Verhalten
164
5.4.5 Memcache
166
5.4.6 Mocken einer serviceorientierten Architektur
167
5.5 Der Qualitätssicherungsprozess bei Digg
172
5.5.1 Testen
172
5.5.2 Vorteile
174
5.5.3 Herausforderungen
176
5.6 Fazit
177
Teil III Server und Services
178
Kapitel 6 Testen von serviceorientierten APIs
180
6.1 Die Probleme
182
6.2 API-Zugangskennungen
183
6.3 API-Beschränkungen
188
6.4 Service-Protokolle offline testen
189
6.5 Konkrete Services offline testen
194
6.6 Fazit
200
Kapitel 7 Wie man einen WebDAV-Server testet
202
7.1 Über die eZ WebDAV-Komponente
202
7.1.1 WebDAV
202
7.1.2 Architektur
205
7.2 Herausforderungen bei der Entwicklung
207
7.2.1 Anforderungsanalyse
207
7.2.2 TDD nach RFC
208
7.2.3 Den Server testen
209
7.3 Automatisierte Akzeptanztests mit PHPUnit
211
7.3.1 Test-Trails aufzeichnen
213
7.3.2 Das Testrezept
215
7.3.3 Integration mit PHPUnit
217
7.4 Fazit
226
Teil IV Architektur
228
Kapitel 8 Testen von Symfony und Symfony-Projekten
230
8.1 Einführung
230
8.2 Ein Framework testen
231
8.2.1 Der Release-Management-Prozess von Symfony
231
8.2.2 Verhältnis von Testcode und getestetem Code
233
8.2.3 Die Ausführung der Testsuite muss schnell sein
233
8.2.4 Gesammelte Erfahrungen
234
8.3 Testen von Webanwendungen
240
8.3.1 Die Hemmschwelle für das Testen abbauen
240
8.3.2 Unit-Tests
241
8.3.3 Funktionale Tests
247
8.4 Fazit
252
Kapitel 9 Testen von Grafikausgaben
254
9.1 Einführung
254
9.2 Entwicklungsphilosophie
255
9.3 Die ezcGraph-Komponente
255
9.3.1 Architektur
257
9.3.2 Anforderungen an die Tests
258
9.4 Ausgabetreiber durchMock-Objekt ersetzen
259
9.4.1 Mehrfache Erwartungen
261
9.4.2 Structs
263
9.4.3 Generierung der Erwartungen
263
9.4.4 Zusammenfassung
264
9.5 Binäre Ausgaben testen
264
9.5.1 Die Ausgabetreiber
265
9.5.2 Generierung der Erwartungen
266
9.5.3 SVG
266
9.5.4 Bitmap-Erzeugung
268
9.5.5 Flash
271
9.6 Fazit
274
Kapitel 10 Testen von Datenbank-Interaktionen
276
10.1 Einführung
276
10.2 Pro und Kontra
277
10.2.1 Was gegen Datenbanktests spricht
277
10.2.2 Warum wir Datenbanktests schreiben sollten
278
10.3 Was wir testen sollten
279
10.4 Datenbanktests schreiben
281
10.4.1 Die Datenbankverbindung mocken
281
10.4.2 Die Datenbankerweiterung von PHPUnit
282
10.4.3 Die Klasse für Datenbanktestfälle
283
10.4.4 Die Verbindung zur Testdatenbank aufbauen
284
10.4.5 Datenbestände erzeugen
288
10.4.6 Operationen auf den Daten
305
10.4.7 Tests schreiben
308
10.4.8 Den Datenbanktester benutzen
317
10.5 Testgetriebene Entwicklung und Datenbanktests
319
10.6 Datenbanktests als Regressionstests
320
10.6.1 Probleme mit den Daten testen
321
10.6.2 Probleme testen, die durch Daten sichtbar werden
322
10.7 Zusammenfassung
323
Teil V QA im Großen
324
Kapitel 11 Qualitätssicherung bei studiVZ
326
11.1 Einführung
326
11.2 Akzeptanztests
328
11.3 Selenium
330
11.3.1 Die Selenium-Erweiterung von PHPUnit
332
11.4 Technisches Setup von studiVZ
333
11.4.1 Codeumgebung
333
11.4.2 Testumgebung
334
11.5 Best Practices
335
11.5.1 Jugendsünden
335
11.5.2 Strategiewechsel
338
11.6 Eine DSL muss her
351
11.6.1 Interne DSL
352
11.6.2 Testing SeleniumDSL 1.0
352
11.6.3 Testing SeleniumDSL 2.0 – ein Entwurf
355
11.7 Fazit
356
Kapitel 12 Kontinuierliche Integration
360
12.1 Einführung
360
12.1.1 Kontinuierliche Integration
362
12.1.2 Statische Analyse
364
12.2 Installation und Inbetriebnahme
378
12.3 Konfiguration
378
12.3.1 Statische Tests
381
12.3.2 Dynamische Tests
388
12.3.3 Reporting
388
12.3.4 Deliverables erzeugen
390
12.4 Betrieb
391
12.5 Weiterführende Themen
392
12.5.1 Continuous Deployment
392
12.5.2 Einen Reverse Proxy nutzen
394
12.5.3 Kontinuierliche Integration und agile Paradigmen
394
12.6 Fazit
395
Kapitel 13 swoodoo – eine wahrhaft agile Geschichte
398
13.1 Einührung
398
13.2 Evolution: Nur die Starken überleben
399
13.3 Wie wir die ”eXtreme Seite” erreichten
404
13.3.1 Kontinuierliche Integration
405
13.3.2 Testgetriebene Entwicklung
406
13.3.3 Tägliche Standup-Meetings
407
13.4 Und wo wir schon einmal dabei sind ...
408
13.4.1 User Storys und Story Points
409
13.4.2 Velocity
410
13.4.3 Iterationsplanung
411
13.4.4 Programmieren in Paaren
411
13.4.5 Kollektives Eigentum
413
13.4.6 Offenheit für Änderungen
414
13.4.7 Überstunden
416
13.5 Die Kunst der Evolution
416
13.6 KISS und YAGNI – zwei Seiten einer Medaille
422
13.7 Evolutionstheorie und Fazit
423
Teil VI Nichtfunktionale Aspekte
426
Kapitel 14 Gebrauchstauglichkeit
428
14.1 Einführung
428
14.2 Anything goes – aber zu welchem Preis?
430
14.3 Designaspekte
432
14.3.1 Barrierefreiheit
432
14.3.2 Lesbarkeit
432
14.3.3 Label für Formularelemente
433
14.3.4 Tastaturbedienbare Webseite
433
14.3.5 Gute Farbkontraste
435
14.3.6 Logo zur Startseite verlinken
435
14.3.7 Alternativtexte für Bilder
435
14.3.8 Hintergrundbild mit Hintergrundfarbe
435
14.3.9 Druckversion nicht vergessen
436
14.3.10 Erkennbare Links
436
14.3.11 Gute Bookmarks
436
14.3.12 Keine Frames
437
14.3.13 Skalierbare Schrift
437
14.4 Technische Aspekte
437
14.4.1 Performanz
437
14.4.2 JavaScript
439
14.5 Benutzerführung
440
14.5.1 Der Mythos des Falzes
441
14.5.2 Feedback bei Interaktionen
442
14.5.3 Navigation
442
14.5.4 Popups und andere Störenfriede
443
14.5.5 Gewohnheiten bedienen, Erwartungen nicht enttäuschen
444
14.5.6 Fehlertoleranz und Feedback
444
14.6 Testen der Usability
445
14.7 Fazit
446
Kapitel 15 Performanz
448
15.1 Einführung
448
15.1.1 Werkzeuge
449
15.1.2 Umgebungsbezogene Gesichtspunkte
450
15.2 Lasttests
452
15.2.1 Apache Bench
453
15.2.2 Pylot
455
15.2.3 Weitere Werkzeuge für Lasttests
457
15.3 Profiling
457
15.3.1 Callgrind
459
15.3.2 APD
464
15.3.3 Xdebug
465
15.3.4 XHProf
467
15.3.5 OProfile
468
15.4 Systemmetriken
470
15.4.1 strace
470
15.4.2 Sysstat
471
15.4.3 Lösungen im Eigenbau
473
15.5 Übliche Fallstricke
474
15.5.1 Entwicklungsumgebung gegen Produktivumgebung
474
15.5.2 CPU-Zeit
475
15.5.3 Mikro-Optimierungen
475
15.5.4 PHP als Glue Language
476
15.5.5 Priorisierung von Optimierungen
476
15.6 Fazit
477
Kapitel 16 Sicherheit
480
16.1 Was ist eigentlich Sicherheit?
480
16.2 Secure by Design
481
16.2.1 Der Betrieb
481
16.2.2 Physikalischer Zugang
483
16.2.3 Software-Entwicklung
483
16.3 Was kostet Sicherheit?
487
16.4 Die häufigsten Probleme
488
16.4.1 A10 – Transportschicht
488
16.4.2 A9 – Kryptografie
489
16.4.3 A8 –Weiterleitungen
490
16.4.4 A7 – Zugriffsschutz
491
16.4.5 A6 – Konfiguration
492
16.4.6 A5 – Cross Site Request Forgery (CSRF/XSRF)
493
16.4.7 A4 – Direkte Zugriffe
493
16.4.8 A3 – Authentifizierung und Session-Management
494
16.4.9 A2 – Cross Site Scripting (XSS)
495
16.4.10 A1 – Injections
497
16.5 Fazit
498
Teil VII Schlussbetrachtungen
500
Literaturverzeichnis
506
Stichwortverzeichnis
514
© 2009-2024 ciando GmbH