Real-World Solutions for Developing High-Quality PHP Frameworks and Applications Published by Wiley Publishing, Inc 10475 Crosspoint Boulevard Indianapolis, IN 46256 www.wiley.com Copyright © 2011 by Sebastian Bergmann and Stefan Priebsch Published by Wiley Publishing, Inc., Indianapolis, Indiana Published simultaneously in Canada ISBN: 978-0-470-87249-9 ISBN: 978-1-118-09822-6 ISBN: 978-1-118-09824-0 ISBN: 978-1-118-09823-3 Manufactured in the United States of America 10 No part of this publication may be reproduced, stored in a retrieval system or transmitted in any form or by any means, electronic, mechanical, photocopying, recording, scanning or otherwise, except as permitted under Sections 107 or 108 of the 1976 United States Copyright Act, without either the prior written permission of the Publisher, or authorization through payment of the appropriate per-copy fee to the Copyright Clearance Center, 222 Rosewood Drive, Danvers, MA 01923, (978) 750-8400, fax (978) 646-8600 Requests to the Publisher for permission should be addressed to the Permissions Department, John Wiley & Sons, Inc., 111 River Street, Hoboken, NJ 07030, (201) 748-6011, fax (201) 748-6008, or online at http://www.wiley.com/go/permissions Limit of Liability/Disclaimer of Warranty: The publisher and the author make no representations or warranties with respect to the accuracy or completeness of the contents of this work and specifi cally disclaim all warranties, including without limitation warranties of fitness for a particular purpose No warranty may be created or extended by sales or promotional materials The advice and strategies contained herein may not be suitable for every situation This work is sold with the understanding that the publisher is not engaged in rendering legal, accounting, or other professional services If professional assistance is required, the services of a competent professional person should be sought Neither the publisher nor the author shall be liable for damages arising herefrom The fact that an organization or Web site is referred to in this work as a citation and/or a potential source of further information does not mean that the author or the publisher endorses the information the organization or Web site may provide or recommendations it may make Further, readers should be aware that Internet Web sites listed in this work may have changed or disappeared between when this work was written and when it is read For general information on our other products and services please contact our Customer Care Department within the United States at (877) 762-2974, outside the United States at (317) 572-3993 or fax (317) 572-4002 Wiley also publishes its books in a variety of electronic formats Some content that appears in print may not be available in electronic books Library of Congress Control Number: 2010939958 Trademarks: Wiley, the Wiley logo, Wrox, the Wrox logo, Programmer to Programmer, and related trade dress are trademarks or registered trademarks of John Wiley & Sons, Inc and/or its affi liates, in the United States and other countries, and may not be used without written permission All other trademarks are the property of their respective owners Wiley Publishing, Inc., is not associated with any product or vendor mentioned in this book CONTENTS FOREWORD INTRODUCTION xxi xxiii PART I: FOUNDATIONS CHAPTER 1: SOFTWARE QUALITY External Quality Internal Quality Technical Debt Constructive Quality Assurance Clean Code 5 Explicit and Minimal Dependencies Clear Responsibilities No Duplication Short Methods with Few Execution Branches Software Metrics Cyclomatic Complexity and npath Complexity Change Risk Anti-Patterns (CRAP) Index Non-Mockable Total Recursive Cyclomatic Complexity Global Mutable State Cohesion and Coupling Tools PHPUnit phploc PHP Copy-Paste-Detector (phpcpd) PHP Dead Code Detector (phpdcd) PHP_Depend (pdepend) PHP Mess Detector (phpmd) PHP_CodeSniffer (phpcs) bytekit-cli PHP_CodeBrowser (phpcb) CruiseControl and phpUnderControl Hudson Arbit Conclusion 9 9 10 10 11 11 11 12 12 12 12 12 13 13 13 13 13 13 13 14 14 14 CONTENTS CHAPTER 2: SOFTWARE TESTING 15 Black Box and White Box Tests How Many Tests Are Needed? System Tests 15 16 17 Browser Testing Automated Tests Test Isolation Acceptance Tests Limits of System Tests Unit Tests 17 18 19 20 20 21 Return Values Dependencies Side Effects 23 24 25 Real-Life Example 25 Analyzing the Code to Test Setting Up a Test Environment Avoid Global Dependencies Test Independently from Data Sources Testing Asynchronous Events Storing Changes in the Database Unpredictable Results Encapsulating Input Data Further Reflections Conclusion 28 29 31 32 37 41 42 44 45 46 PART II: BEST PRACTICES CHAPTER 3: TYPO3: THE AGILE FUTURE OF A PONDEROUS PROJECT Introduction The History of TYPO3: Thirteen Years in Thirteen Paragraphs Daring to Start Over! Our Experience with Testing Policies and Techniques Bittersweet Elephant Pieces Test-Driven Development Tests as Documentation Continuous Integration x 49 49 49 51 51 52 53 53 54 55 CONTENTS Clean Code Refactoring Programming Guidelines Domain-Driven Design 56 57 58 59 Course of Action in Development 60 Developing New Code Extending and Modifying Code Optimizing Code Speed Readability Finding and Fixing Bugs Disposing of Old Code 60 61 61 61 63 63 63 Test Recipes Inadvertently Functional Unit Test Access to the File System Constructors in Interfaces Testing Abstract Classes Testing Protected Methods Use of Callbacks Into the Future CHAPTER 4: UNIT TESTING BAD PRACTICES Why Test Quality Matters Bad Practices and Test Smells Duplication in Test Code Assertion Roulette and Eager Test Fragile Test Obscure Test Problems with Global State Indirect Testing Obscure Test Names Lying Test Slow Test Conditional Logic in Tests Self-validating Tests Web-surfing Tests Mock Overkill Skip Epidemic Conclusion 64 64 64 65 66 66 68 69 71 71 72 73 74 76 78 78 80 82 83 84 85 87 87 88 90 90 xi CONTENTS CHAPTER 5: QUALITY ASSURANCE AT DIGG INC Problems We Are Facing Legacy Code Base How Do We Solve These Problems? Size Does Matter Team Size Project Size Code Size Unit Testing and You Choosing a Testing Framework Working with an Expert One Week in a Room 91 92 93 93 94 94 94 94 95 95 95 Training Our Team Writing Testable Code 95 98 Avoid Static Methods Dependency Injection 98 100 Mock Objects Overview Database Loosely Coupled Dependencies Subject/Observer for Testing Class Internals Memcached Mocking a Service-Oriented Architecture Model Service Query Service Endpoint The Base Classes Digg’s Quality Assurance Process Testing Planning the Testing Effort Tasks Automation Benefits Testing Early Testing Often Challenges Conclusion xii 91 100 100 101 101 102 103 104 104 105 105 105 107 108 108 108 108 109 109 109 110 111 CONTENTS PART III: SERVERS AND SERVICES CHAPTER 6: TESTING SERVICE-ORIENTED APIS The Problems Solutions API Credentials API Limits Offline Testing of Service Protocols Offline Testing of Concrete Services Conclusion CHAPTER 7: TESTING A WEBDAV SERVER About the eZ WebDAV Component WebDAV Architecture 115 117 118 118 121 122 126 130 131 131 131 133 Development Challenges 135 Requirements Analysis TDD after RFC Testing a Server 135 136 137 Automated Acceptance Tests with PHPUnit Capturing Test Trails Test Recipe Integration into PHPUnit A Custom Test Case The Acceptance Test Suite Acceptance Tests by Example Conclusion 139 140 141 142 142 146 147 149 PART IV: ARCHITECTURE CHAPTER 8: TESTING SYMFONY AND SYMFONY PROJECTS Testing a Framework The symfony Release Management Process Long-term Support Code Coverage Tests versus Real Code 153 154 154 154 155 155 xiii CONTENTS Running the Test Suite Main Lessons Learned Never Use the Singleton Design Pattern in PHP Decouple Your Code with Dependency Injection Lower the Number of Dependencies between Objects with an Event Dispatcher Testing Web Applications Lowering the Barrier of Entry of Testing Unit Tests Easy to Install Easy to Learn Fun to Use Functional Tests The Browser Simulator The Fixtures The CSS3 Selectors Testing Forms Debugging Conclusion CHAPTER 9: TESTING THE EZCGRAPH COMPONENT Development Philosophy Graph Component Architecture Test Requirements Driver Mocking Mock the Driver Multiple Assertions Structs Expectation Generation Conclusion Testing Binary Data The Drivers Expectation Generation SVG XML Comparison Floating-point Problems Bitmap Creation Bitmap Comparison GD Version Differences xiv 156 156 156 158 159 161 161 162 162 163 165 165 166 168 168 169 169 170 171 172 172 173 174 175 175 176 177 178 178 179 179 179 180 180 181 181 182 183 CONTENTS Flash The Assertion Conclusion 183 184 185 CHAPTER 10: TESTING DATABASE INTERACTION 187 Introduction Reasons Not to Write Database Tests Why We Should Write Database Tests What We Should Test Writing Tests: Mocking Database Connections Writing Tests: PHPUnit Database Extension 187 188 189 190 191 191 The Database Test Case Class Establishing the Test Database Connection Creating Data Sets XML Data Sets Flat XML Data Sets CSV Data Sets YAML Data Sets Database Data Sets Data Set Decorators Generating Data Sets Data Operations Creating Tests Testing the Loading of Data Testing the Modification of Data Using the Database Tester Applying Test-Driven Design to Database Testing Using Database Tests for Regression Testing Testing Problems with Data Testing Problems Revealed by Data Conclusion 192 193 196 197 199 200 201 203 204 209 209 211 211 215 218 220 220 221 222 222 PART V: Q&A IN THE LARGE CHAPTER 11: QUALITY ASSURANCE AT STUDIVZ Introduction 225 225 About studiVZ 226 Acceptance Tests 227 Acceptance Tests in Agile Environments 227 xv CONTENTS Selenium The Selenium Extension of PHPUnit The Technical Setup of studiVZ Development Environment Test Environment Best Practices Sins of Our Youth Monolithic Tests Static Users Strategy Change Atomic Tests with Dynamic Test Data Robust Selenium Tests Test Scope Must Be Clear Common Functionality or Browser Compatibility as Well? Fix Tests Right Away! Stabilize Locators, and Use IDs Speed, the Sore Subject Recipes for Last-Minute Features Tests Are Software Too Capture and Replay versus Programming Tests The Team: A Good Mix We Need a DSL Internal DSL Testing_SeleniumDSL 1.0 Problem: Context Sensitivity Testing_SeleniumDSL 2.0 — A Draft State and Outlook on Version 2.0 Conclusion CHAPTER 12: CONTINUOUS INTEGRATION Introduction Continuous Integration Configuration Build Management and Automated Tests Version Management Continuous Integration Static Analysis Code Clones Refactoring Software Metrics xvi 228 229 230 230 231 232 232 232 233 234 234 235 235 236 236 237 238 239 240 240 242 242 243 243 245 245 246 246 249 249 251 251 251 252 252 253 253 253 254 BIBLIOGRAPHY ——— “Partition (database),” 2010, accessed February 9, 2010, http://en.wikipedia.org/wiki/ Partition_(database) ——— “Shard (database architecture),” 2010, accessed February 9, 2010, http://en.wikipedia org/wiki/Sharding ——— “Visitor,” 2010, accessed February 9, 2010, http://de.wikipedia.org/wiki/Visitor ——— “Zuständigkeitskette,” 2010, accessed February 9, 2010, http://de.wikipedia.org/ wiki/Chain_of_Responsibility Wirth, Timo “Nutzerbeteiligung & Kommunikation: Mitmachbarrieren im Web 2.0,” 2009, accessed February 9, 2010, http://www.slideshare.net/aperto/mitmachbarrieren-im-web-20 Yourdon, Edward and Larry Constantine Structured Design: Fundamentals of a Discipline of Computer Program and Systems Design Prentice Hall, 1979 ISBN 978-0138544713 364 INDEX Symbols # (pound sign), commenting data sets and, 202 $backend attribute, 143 $server attribute, 143 * (asterisk character) in tables, 204 | (pipe) and |- characters, line breaks and, 202 > (greater than character), line breaks and, 202 “ (double quotes), delimiting strings and, 202 ‘ (single quotes), delimiting strings and, 202 A AB (Apache Bench), 318, 321–322, 324 abstract classes, testing, 66 Abstraction of software artifacts, 259–260 acceptance tests acceptance test suite (WebDAV), 146–147 agile development and (studiVZ), 227–228 automated (WebDAV), 139–140 basics of, 20, 46, 227–228 class PHPUnit_Framework_TestCase (WebDAV), 142–146 defi ned, examples (WebDAV), 147–149 access accessibility of websites, 304 to database objects, security and, 351–352 physical access, security and, 343–344 URL access, security and, 349 Action Message Format (AMF), 117 ActiveX, swoodoo and, 282 addDataSet() method, 205, 206–207 addUser() method, 192 addYamlFile() method, 201 Afferent Coupling, 259 agile development See also swoodoo acceptance tests and, 227–228 agile methods, advantage of, 240 agile paradigms and continuous integration, 278 Digg QA and, 107–108 algorithms, hashing, 349–350 AMF (Action Message Format), 117 Apache, profi ling and, 325, 327 Apache Bench (AB), 318, 321–322, 324 Apache HTTPD, 277 APD, 329–330 API credentials, 117, 118–121 API limits, 117, 121–122 Arbit, 14 architecture ezcGraph component, 173–174 Patterns of Enterprise Application Architecture (Addison-Wesley Professional), 32 Selenium RC, 229 service-oriented, mocking (Digg), 104–107 swoodoo and, 298 of WebDAV component, 133–135, 138 ASAP tasks (swoodoo), 289 assertDataSetsEqual() method, 215 assertions assertion roulette, 74–76 Flash and, 184–185 multiple (ezcGraph), 176–177 rules for creating, 238 assertRunCorrect() custom assertion method, 145–146 assertTablesEqual() method, 215, 217 asterisk character (*) in tables, 204 asynchronous events, testing, 37–41 Atlassian Bamboo Continuous Integration Server, 231 atomic tests with dynamic test data (studiVZ), 234–235 attributes, test case class (WebDAV), 143 authentication, broken authentication and session management, 352 automation automated acceptance tests (WebDAV), 139–140 automated forwarding, security and, 347–348 automated tests, 18–19 365 code – data set decorators decoupling with dependency injection (symfony), 158–159 dependencies, 24–25 duplicated, 9, 12, 58, 73, 253–254 faulty source code, security and, 347 guidelines, continuous integration and, 268–269 HTML code, website usability and, 309 legacy code, PEAR standard and, 269–270 semantic code, website usability and, 309 standards in daily work, 270–271 test code is software, 240 testable code, writing, 98–100 tests vs real code, 155–156 code (TYPO3) clean code, 56–57 developing new, 60–61 disposing of old, 63–64 duplicated, 58 extending and modifying, 61 optimizing, 61–63 readability of, 63 Code Rank metrics, 261 cohesions, system, 12 collection resources (WebDAV), 132 collections (WebDAV), 132 collective code ownership, swoodoo and, 290–291 compare command, 182 components See ezcGraph component; web service consumer components; WebDAV component composite decorator, 205–207 conditional logic in tests, 85–86 configuration, continuous integration and, 251, 264–266 constructive quality assurance, 7–8 constructors in interfaces, avoiding, 65 content management (TYPO3), 49 context-sensitive matcher and constraints (DSL), 245 continuous deployment, 276–277 continuous integration (CI), 249–279 agile paradigms and, 278 automated build processes, 251 basics of, 250, 252 configuration, 251, 264–266 continuous deployment, 276–277 defi ned, 252 deliverables, 274–275 Digg QA and, 95, 109, 110 dynamic tests, 272 Hudson and, 55–56 installation, 263 integration, defi ned, 251 operations, 275–276 overview, 249–250 reporting, 272–273 resource-oriented web services and, 116 reverse proxy, 277 static analysis See static analysis static tests See static tests testing techniques, 249–250 version management, 252 contrast (visual), usability of websites and, 306 COPY request (WebDAV), 132 cost of security, 346–347 coupling, loose, 12 CPU metrics and performance testing, 318, 338 CRAP (Change Risk Anti-Patterns) Index, 11 Crazyegg, 314 createDataSet() method, 203 createQueryTable() method, 203–204, 215, 217–218 Crosscheck, 286 Cross-Site Request Forgery (CSRF/XSRF), 351 Cross-Site Scripting (XSS), security and, 353–354 CruiseControl basics of, 13–14 Build Loop and, 264 configuring, 265–266 JDK and, 263 PHP_CodeBrowser and, 273 swoodoo and, 286 cryptographic storage, security and, 349–350 CSS, usability of websites and, 303, 309, 310 CSS3 selectors, 168–169 CSV data sets, 200 Cunningham, Ward, custom instrumentation, 337–338 Cyclomatic Complexity, 10, 258–259, 261 D Dambekalns, Karsten, 49 data (in databases) data operations, 209–211 testing independently from data sources, 32–37 testing loading of, 211–215 testing modification of, 215–218 testing problems revealed by, 222 testing problems with, 190–191, 221–222 data set decorators, 204–209 composite decorator, 205–207 data sets, generating, 209 fi lter decorator, 204 replacement decorator, 207–209 367 data sets – Efferent Coupling data sets, creating, 196–209 CSV data sets, 200 data set decorators See data set decorators database data sets, 203–204 flat XML data sets, 199–200 overview, 196–197 XML data sets, 197–199 YAML data sets, 201–202 database dependency (Digg QA), 101 database interaction, testing, 187–222 contraindications for, 188–189 mocking database connections, 191 overview, 187–188 PHPUnit database extension See PHPUnit database extension reasons for, 189–190 regression testing, 220–222 test-driven design, 220 what to test, 190–191 databases, security and, 341–342 DB class, 99 dbdeploy tool, 194 DDD (Domain-Driven Design), 59–60 debugging enable-debug configure option, 319, 338 microtime function and, 337 null: parameter and, 182 Subject/Observer pattern and, 102 tests, 169–170, 234, 237 tools, 137 decorators, data sets See data set decorators decoupling code with dependency injection, 158–159 core classes, 159–161 delete() method, 105–106 DELETE request (WebDAV), 132 deliverables, 274–275 dependency class, reducing, 159–161 code, 24–25 database, 93, 101 explicit, global, 31–32, 79 loosely coupled, 101–102 minimal, dependency injection complex dependency and, 11 defi ned, 9, 25 dependency injection containers, 154, 159 Digg QA and, 100 symfony and, 158–159 deployment, continuous, 276–277 developer tools, 12–14 See also specifi c tools 368 developers vs management (swoodoo), 287–288 nobody-but-me-understands-my-code developer, 296 development See also agile development; test-driven development (TDD) piece by piece development, 53 vs production environments, 338 security, software development and, 344–346 Digg quality assurance, 91–112 agile process, 107–108 Bergmann, Sebastian, 95 challenges, 110 dependency injection, 100 legacy code, 92–93, 94 mock objects See mock objects overview of Digg, 91–92 PHPUnit and, 95 PHPUnit training, 95–98 projects, smaller, 94 refactoring, 94 static methods, avoiding, 98–100 teams, smaller, 93 testing, 108–110 unit testing, 94 writing testable code, 98–100 Dijkstra, Edsger W., 7–8 DispatcherTest class, 89 Distance, software metrics and, 259, 260 doFoo() function, 98–100 Domain Specific Language (DSL) See DSL, creating and testing (studiVZ) Domain-Driven Design (DDD), 59–60 double quotes (“), delimiting strings and, 202 driver mocking basics of, 175–176 expectations, 178 multiple assertions, 176–177 structs, 177–178 drivers (ezcGraph), 179 DSL, creating and testing (studiVZ), 242–246 duplicated code, 9, 12, 58, 73, 253–254 dynamic test data (studiVZ), 234–235 dynamic tests, 272 E eager tests, 74–76 Eberlei, Benjamin, 71 edge cases, 96 edge-to-edge tests, 46 Efferent Coupling, 259 e-mails – getDataSet e-mails, sending asynchronously, 37–39 enable-debug configure option, 319 encapsulating input data, 44–45 output data in Response objects, 45–46 encryption of passwords, security and, 349–350 end-to-end tests, 4, 46 enumerated test methods, 82 environments considerations for performance testing, 319–320 development vs production environments, 338 test environments, setting up, 29–31 equivalence classes, 16 Erkkila, Matt, 91 error handling, security and, 345–346 Eure, Ian, 91 Evans, Cal, 244 event dispatchers, for reducing dependencies, 159–161 explicit dependencies, extensibility (WebDAV), 133 external DSL, 243–244 external quality (software), EXtreme Programming (XP), swoodoo and, 285–286 eZ WebDAV component See WebDAV component ezcGraph component, 171–185 architecture, 173–174 binary data, testing See binary data, testing development history, 171–172 development philosophy, 172 driver mocking, 175–178 overview, 172–173 test requirements, 174 tutorial, 173 ezcMvcDispatcherConfigurable test, 81 ezcUrl class, 74–75 ezcWebdavClientTest test case class, 143 ezcWebdavClientTestSuite, 146–147 F fault tolerance, usability of websites and, 313 feedback on interaction (websites), 311–312 fi le systems, access code testing and, 64–65 fi les (WebDAV), 132 fi lter decorator, 204 Firebug, 137, 314 fi xtures, 29, 168 Flash, binary data testing and, 183–185 flat XML data sets, 199–200 fl ight search engine (swoodoo), 282–284 floating-point numbers, 176, 181 Flood, 324 “Fluent Interfaces in PHP”, 244 fold (on website pages), 311 fonts, website usability and, 304–305, 308 FooServiceTest class extends PHPUnit_ Framework_TestCase, 120 Forgotten Password functionality, 352 formats Action Message Format (AMF), 117 for data sets, 197 XML data set format, 197 forms labels for form elements, 305 testing, 169 forwarding, security and, 347–348 Fowler, Martin, 32, 58, 244, 253, 257 fragile tests, 76–77 frames, eliminating on websites, 308 frameworks, testing (symfony), 154–161 class dependencies, reducing, 159–161 dependency injection and, 158–159 functional vs unit tests, 156 release management process, 154–155 running test suites, 156 singleton design pattern, 156–158 tests vs real code, 155–156 Freeman, Steve, 9, 46 front-end development, website usability and, 301 front-end tests studiVZ, 239 vs unit tests, 235 functional tests basics of, 165–166 browser simulators, 166–168 CSS3 selectors, 168–169 debugging, 169–170 end-to-end tests, 46 fi xtures, 168 testing forms, 169 vs unit tests (symfony), 156 functionality, defi ned, functions function that adds integers, 96–97 software metrics and, 256–258 FURPS quality model, G GD extension, 183 GD library, 172 GET method (WebDAV), 137 getConnection() method, 192–193 getDataSet() method, 196, 197 369 PHPUnit Manual – reporting PHPUnit_Extensions_Database_TestCase class, 192–193 phpunit.XML, 194 test databases, selecting, 192–194 PHPUnit Manual, 37 PHPUnit_Extensions_Database_DataSet_ CompositeDataSet class, 205 PHPUnit_Extensions_Database_DataSet_ CsvDataSet class, 200 PHPUnit_Extensions_Database_DataSet_ DataSetFilter class, 204 PHPUnit_Extensions_Database_DataSet_ FlatXmlDataSet class, 199 PHPUnit_Extensions_Database_DataSet_IDataSet interface, 196 PHPUnit_Extensions_Database_DataSet_ ReplacementDataSet class, 207 PHPUnit_Extensions_Database_DataSet_ XmlDataSet class, 197 PHPUnit_Extensions_Database_DataSet_ YamlDataSet class, 201 PHPUnit_Extensions_Database_DB_ IDatabaseConnection class, 203 PHPUnit_Extensions_Database_DefaultTester class, 218 PHPUnit_Extensions_Database_Operation_ Factory class, 210 PHPUnit_Extensions_Database_TestCase class, 192–193, 215 PHPUnit_Extensions_SeleniumTestCase OProfi le, 333 profi ling tools, 318 Xdebug, 330–331 XHProf, 331–333 programming conventions, 266–268 EXtreme Programming (XP), swoodoo and, 285–286 object-oriented programming (OOP), Digg QA and, 93 pair programming (swoodoo), 290–291 programming tests, vs capture and replay, 240–241 test-fi rst programming, PROPFIND request (WebDAV), 133, 134 PROPPATCH request (WebDAV), 133 protected methods, testing, 63, 66–68 proxies, reverse, 277 Pryce, Nat, 9, 46 PUT request (WebDAV), 133 Pylot, 318, 322–324 Q quality assurance (QA) See also Digg quality assurance; studiVZ quality assurance constructive quality assurance, 7–8 quotes (double and single), delimiting strings and, 202 quotes, delimiting strings and, 202 class, 229 PHPUnit_Framework_TestSuite, 146–147 phpunit.XML fi le, 194 Pichler, Manuel, 14, 249 piece by piece development, 53 pipe characters (| and |-), line breaks and, 202 plugins, Nagios, 295–296 PMD-CPD, 253 pop-ups, 312–313 Potencier, Fabien, 153 pound sign character (#), commenting data sets and, 202 pprof-2calltree command line tool, 329, 330 “Predicting Class Testability using Object-Oriented Metrics”, 10 priority of optimization, performance testing and, 339–340 production vs development environments, 338 profi ling, 324–333 APD, 329–330 basics of, 324–325 Callgrind, 325–328 KCachegrind, 328–329 R radical refactoring, 51 RATS (Rough Auditing Tool for Security), 262–263 reactivity, defi ned, readability of websites, 304–305 redirects, security and, 348 refactoring code clones and, 253–254 defi ned, 5, 253 Digg QA and, 94 vs rewriting, 293–294 swoodoo and, 282, 285, 292 TYPO3 and, 57–58, 61 reflection API, 68 regression testing, 220–222 release management process (symfony), 154–155 reliability of web applications, Remote Procedure Call (RPC) services, 116 REPLACE operation (table setup), 211 replacement decorator, 207–209 reporting, 272–273 373 Software Engineering – symfony development, security and, 344–346 software artifacts, 255 swoodoo and, 285 test code as, 240 Software Engineering — Product quality, software metrics basics of, 10–12, 254–262, 279 classes/interfaces/methods/functions in systems, 256–258 classic metrics, defi ned, 255 Code Rank metrics, 261 Cyclomatic Complexity, 10, 258–259 Distance, 259, 260 Instability and Abstraction, 259–260 Lines of Code (LOC) metric, 255–256 object-oriented metrics, 259–262 RATS, 262–263 software artifacts, 255, 259–260 Software Process Improvement and Capability Determination (SPICE), software quality Clean Code, 8–9 constructive quality assurance, 7–8 developer tools, 12–14 external quality, internal quality, overview, 3–4 software metrics See software metrics technical debt, 5–7 software testing See testing software Software-Qualität: Testen, Analysieren und Verifizieren von Software, Aufl age, SomeServiceTest class extends PHPUnit_ Framework_TestCase, 121 Souders, Steve, 308, 309 source code duplicated (code clones), 12, 253–254 faulty source code, security and, 347 SPICE (Software Process Improvement and Capability Determination), sprites (CSS), website usability and, 309 SQL statements, testing and, 188–189 static analysis, 253–263 classic metrics, 255–259 code clones, 253–254 object-oriented metrics, 259–262 RATS, 262–263 refactoring, 253–254 software metrics basics, 254 static method calls, testing and, 98–100 static test users, 233–234 static tests, 266–271 basics of, 249–250 coding guidelines, 268–269 coding standards, 270–271 legacy code, PEAR standard and, 269–270 programming conventions, 266–268 syntax analysis, 270–271 statistics collection, 335–336 strace, 334–335 structs (ezcGraph component), 177–178 stubs, defi ned, 36 studiVZ quality assurance, 225–247 acceptance tests, 227–228 atomic tests with dynamic test data, 234–235 capture and replay vs programming, 240–241 DSL, creating and testing, 242–246 general functionality or browser compatibility, 236 introduction, 225–226 last-minute features, 239–240 monolithic tests, 232–233 Selenium, 228–230 Selenium tests, 235 stabilizing locators/using IDs, 237–238 static test users, 233–234 studiVZ basics, 226–227 studiVZ technical setup, 230–232 test code is software, 240 test scope, clarity of, 235–236 testers, importance of good, 242 tests, delay in fi xing, 236–237 tests, speed of, 238–239 Subject/Observer pattern, 102–103 Subversion, swoodoo and, 286 Suhosin extension, 343 surfi ng tests, 87–88 SVG (Scalable Vector Graphics), 180–181 swftophp tool, 184–185 swoodoo, 281–298 architecture, 298 basics of, 281 changes in functionality, 291–292 history of, 282–285 incremental changes, 297 KISS mantra, 293, 296 Nagios plugins in PHP, 295–296 naming classes and methods, 287 pair programming, 290–291 planning of new features, 288–289 switch to XP, 285–286 TDD and, 285–286 unnecessary class constraints, 293–294 symfony, testing, 153–170 dependency injection container (symfony 2), 154 frameworks, testing See frameworks, testing (symfony) web applications, testing See web applications, testing 375 Thomas – ViewRenderer class general techniques, 249–250 integration tests, 46, 77, 139 monolithic tests, 232–233 programming tests vs capture and replay, 240–241 vs real code (symfony), 155–156 speed of, 238–239 studiVZ QA, 234–235 surfi ng tests, 87–88 system tests, 17–21, 358 Thomas, Dave, timestamps, usability of websites and, 310–311 TinySVG standard, 180 tag (bookmarks), 307 “Top 10 Web Application Security Risks”, 347 Trac, swoodoo and, 286 transport layer protection, 348–349 transport layer (WebDAV), 134 TRUNCATE command, 209–210 TYPO3 clean code, 56–57 code, developing new, 60–61 code, disposing of old, 63–64 code, extending and modifying, 61 code, optimizing, 61–63 code, readability of, 63 continuous integration (Hudson), 55–56 domain-driven design, 59–60 history of, 49–52 piece by piece development, 53 programming guidelines for, 58–59 refactoring, 57–58 test recipes, 64–69 test-driven development, 53–54 tests as documentation, 54–55 U Ubuntu LTS (Long Term Support), 155–156 unit tests See also obscure tests basics of, 77, 187 code duplication and, 73–74 conditional logic in, 85–86 Digg QA and, 94 eager tests and assertion roulette, 74–76 fragile tests, 76–77 vs front-end tests, 235 vs functional tests (symfony), 156 fundamentals of, 21–25 importance of, 94, 149–150 inadvertently functional, 64 vs integration tests, 77 lying tests, 83–84 mock overkill, 88–90 MVC controller example, 25–29 quality in, 71–72 self-validating tests, 87 skipped tests, 90 slow tests, 84–85 test smells and, 72 web applications, 162–165 web-surfi ng tests, 87–88 UNLOCK request (WebDAV), 133 URL access, security and, 349 usability, defi ned, 4, 301 usability of websites, 301–315 accessibility, 304 alternative texts for images, 307 background image, 307 basics of, 302–303 contrast and, 306 fault tolerance, 313 feedback on interaction, 311–312 fold and, 311 frames, eliminating, 308 front-end development and, 301 good bookmarks, 307–308 guidance for users, 310–311 importance of detail, 302 JavaScript, 310 keyboard navigation, 305–306 labels for form elements, 305 logo links to home page, 307 navigation, 312 performance, 308–310 pop-ups, 312–313 readability, 304–305 scalable fonts, 308 similarity of pages, 313 testing, 313–314 usable print version, 307 visible links, 307 users guidance for website users, 310–311 static test users (studiVZ), 233–234 V Valgrind, 325 van Deursen, Arie, 10 velocity, defi ned, 289 “Version Control for Multiple Agile Teams”, 276 version control systems, 252 vfsStream, 64 ViewRenderer class, 79 377 ... Copy-Paste-Detector (phpcpd) PHP Dead Code Detector (phpdcd) PHP_ Depend (pdepend) PHP Mess Detector (phpmd) PHP_ CodeSniffer (phpcs) bytekit-cli PHP_ CodeBrowser (phpcb) CruiseControl and phpUnderControl... is the creator of PHP quality assurance tools such as PHP Depend,6 PHPMD,7 and phpUnderControl.8 He is a co-founder of Qafoo GmbH, which provides services for high- quality PHP development Sebastian... provides services for high- quality PHP development This includes consulting and training for quality assurance and better programming, as well as technical support for several PHP QA tools In his