Your SlideShare is downloading. ×
0
Best Practices Matthew Weier O'Phinney Zend Framework Lorna Jane Mitchell Ibuildings @lornajane @weierophinney
The Plan <ul><li>Source Control
Coding Standards
Design Patterns
Documentation
Testing
Quality and Continuous Integration
Deployment </li></ul>
Source Control
Source Control Features <ul><li>Version history of all files
Collaboration tool
Authoritative version of a project
Integration point </li></ul>
Using Source Control <ul><li>Create a repository, add project
Check out project
Make changes
Update to get other changes
Commit changes to repo </li></ul>
svn log ------------------------------------------------------------------------ r3 | lornajane | 2010-04-25 10:32:09 +010...
svn diff Index: README.txt =================================================================== --- README.txt  (revision 3...
Source Control Tools <ul><li>Subversion (svn) </li><ul><li>http://subversion.apache.org/ </li></ul><li>Git (git) </li><ul>...
Accessing Source Control <ul><li>IDE Plugins
Trac ( http://trac.edgewall.org/ )
TortoiseSVN </li><ul><li>TortoiseGit
TortoiseBzr
TortoiseHg </li></ul></ul>
Centralised Source Control user repo user user user
Centralised Source Control <ul><li>Single repo (repository)
Always commit to central
Can branch centrally </li></ul>
Repository Structure (Feature Branches)
Repository Structure (Long-Lived Branches)
Repository Structure (Release Branches)
Distributed Source Control repo repo repo repo repo
Distributed Source Control <ul><li>Many repos
Commit to local repo
Share changes between anywhere
No central point </li></ul>
The Changing Landscape <ul><li>Very active development area
Today's conclusions not valid for long! </li></ul>
Bridges <ul><li>git-svn </li><ul><li>http://www.kernel.org/pub/software/scm/git/docs/git-svn.html </li></ul><li>bzr-svn </...
Make as many changes/branches as you like
Push back to SVN </li></ul>
Hosted Solutions GitHub http://github.com/ git Bitbucket http://bitbucket.org/ hg Google Code http://code.google.com/ svn,...
What If I Don't Have Source Control? <ul><li>Get some :)
Install subversion
Use a hosted solution </li></ul>
Resources <ul><li>Talks at TEK-X </li><ul><li>Subversion in a Distributed World, Lorna Mitchell
Getting Git, Travis Swicegood (who literally wrote the book)
Both Wednesday afternoon </li></ul><li>Subversion book </li><ul><li>http://svnbook.red-bean.com/ </li></ul><li>Comparison ...
Coding Standards
You don't have a standard when … <ul><li>You always reformat code you get from others
Code you wrote 6 months ago looks different than what you wrote today
Modifying old code often introduces new syntax errors </li></ul>
Answer the following questions: <ul><li>Can you read your own code?
Can others read your code?
Can you read other's code?
Can you switch between code bases easily? </li></ul>
Analogy &quot;Elements of Style&quot; :: Writing Coding Standard :: Development
In sum, coding standards assist in: <ul><li>Maintainability
Collaboration </li></ul>
How CS aids maintainability: Code is structured predictably
How CS aids collaboration <ul><li>Any developer can pick up and easily read existing code
…   which in turn means they can maintain it
…   which de-centralizes who is responsible for the code
…   which means issues and reature requests are resolved faster
It  democratizes  code maintenance </li></ul>
Two pillars of a Coding Standard: <ul><li>Consistency of  file system  layout
Consistency of  code  layout </li></ul>
Ancillary goal: <ul><li>Consistency in naming </li></ul>
Use Public Standards <ul><li>NIH has no place with CS </li><ul><li>You and your project's needs are not unique
What if you need to consume and potentially help maintain 3rd party libraries?
Benefit from collective knowledge and empirical discoveries </li></ul></ul>
Need more reasons? <ul><li>Objectivity </li><ul><li>Choices are no longer based on subjective preferences, but on empirica...
Choices <ul><li>Horde/PEAR/Zend Framework </li><ul><li>Also: Solar, AdoDB, Doctrine 2, Symfony 2, and more... </li></ul><l...
PHPLIB </li></ul>
Example <?php /** * In Foo/Bar.php */ class   Foo_Bar { const   BAZ   =   'baz' ; protected   $_bat ; public   $bas ; publ...
Resources <ul><li>PEAR </li><ul><li>http://pear.php.net/manual/en/standards.php
http://pear.php.net/manual/en/pear2cs.php </li></ul><li>Zend Framework </li><ul><li>http://framework.zend.com/manual/en/co...
Design Patterns
A Design Pattern Is ... <ul><li>NOT rocket science
A common way to describe a common problem
Shared language
A problem and solution which is repeated many times
Common across programming languages
Heavily OOP </li></ul>
Some Common Patterns <ul><li>Factory
Registry
Adapter
Decorator
Observer </li></ul>
Factory <ul><li>Has methods to create and return objects
May return different objects
May use complex (and maintainable) logic to work out what to do </li></ul>
Factory Example: Hat Types 1  < ?php 2  3  require_once ( 'hat.php' ); 4  5  class   HatFactory   { 6  public   function  ...
Registry <ul><li>Can be a singleton  (but this is not a requirement!)
Register objects here, access from elsewhere
Often a factory/registry combination </li></ul>
Registry Example: Hat Storage 1  < ?php 2  3  class   HatRegistry   { 4  private   $registry ; 5  6  public   function   _...
Adapter <ul><li>Adapts  a specific interface to fit something else; typically, to provide a common API to related classes/...
Allows the class wrapped by the adapter to exist independently from the component consuming the adapter. </li></ul>
Adapter Example: SOAP to REST <ul><li>Real life example
Client project to deliver SOAP </li></ul>
PHP SOAP 1  < ?php 2  3  require_once ( 'lib/myClass.php' ); 4  5  $server   =   new   SoapServer ( null ,  $options ); 6 ...
Adapter Example: SOAP to REST <ul><li>Real life example
Client project to deliver SOAP
Service part-built
Client reads textbook(?)
Client requests REST
Adapter class to the rescue! </li></ul>
Adapter Example: SOAP to REST myClass index.php
Adapter Example: SOAP to REST myClass index.php Adapter
Decorator <ul><li>Wraps another class in order to modify its behavior
Target class doesn't change
Decorating class often implements the same interface(s)
Can be  visually  decorative, not always </li></ul>
Decorator Example 1  < ?php 2  3  interface LabelInterface   { 4  public   function   render (); 5  } 6  7  class   BasicL...
Decorator Example 13  abstract   class   LabelDecorator implements LabelInterface   { 14  public   function   __construct ...
Upcoming SlideShare
Loading in...5
×

Best practices tekx

8,083

Published on

Tutorial delivered by Matthew Weier O'Phinney and Lorna Mitchell at TEK-X in Chicago, May 2010

Published in: Technology
0 Comments
8 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
8,083
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
96
Comments
0
Likes
8
Embeds 0
No embeds

No notes for slide

Transcript of "Best practices tekx"

  1. 1. Best Practices Matthew Weier O'Phinney Zend Framework Lorna Jane Mitchell Ibuildings @lornajane @weierophinney
  2. 2. The Plan <ul><li>Source Control
  3. 3. Coding Standards
  4. 4. Design Patterns
  5. 5. Documentation
  6. 6. Testing
  7. 7. Quality and Continuous Integration
  8. 8. Deployment </li></ul>
  9. 9. Source Control
  10. 10. Source Control Features <ul><li>Version history of all files
  11. 11. Collaboration tool
  12. 12. Authoritative version of a project
  13. 13. Integration point </li></ul>
  14. 14. Using Source Control <ul><li>Create a repository, add project
  15. 15. Check out project
  16. 16. Make changes
  17. 17. Update to get other changes
  18. 18. Commit changes to repo </li></ul>
  19. 19. svn log ------------------------------------------------------------------------ r3 | lornajane | 2010-04-25 10:32:09 +0100 (Sun, 25 Apr 2010) | 1 line adding documentation notes ------------------------------------------------------------------------ r2 | lornajane | 2010-04-22 09:07:56 +0100 (Thu, 22 Apr 2010) | 1 line outlining source control and design patterns sections ------------------------------------------------------------------------ r1 | weierophinney | 2010-03-30 17:37:27 +0100 (Tue, 30 Mar 2010) | 1 line Added readme with outline ------------------------------------------------------------------------
  20. 20. svn diff Index: README.txt =================================================================== --- README.txt (revision 3) +++ README.txt (revision 4) @@ -31,12 +35,20 @@ to share ideas to raise profile to be told you're doing it wrong! + (pulling up examples off our own blogs, if connection allows) Testing (Matthew) QA tools and CI including code analysis, mess detection, etc (Lorna - QA tools; Matthew - CI) + Static analysis + code sniffer + demo examples, find a suitable small codebase (joindin?) + mess detector + demo examples + what else? + Deployment
  21. 21. Source Control Tools <ul><li>Subversion (svn) </li><ul><li>http://subversion.apache.org/ </li></ul><li>Git (git) </li><ul><li>http://git-scm.com/ </li></ul><li>Bazaar (bzr) </li><ul><li>http://bazaar.canonical.com/ </li></ul><li>Mercurial (hg) </li><ul><li>http://mercurial.selenic.com/ </li></ul></ul>
  22. 22. Accessing Source Control <ul><li>IDE Plugins
  23. 23. Trac ( http://trac.edgewall.org/ )
  24. 24. TortoiseSVN </li><ul><li>TortoiseGit
  25. 25. TortoiseBzr
  26. 26. TortoiseHg </li></ul></ul>
  27. 27. Centralised Source Control user repo user user user
  28. 28. Centralised Source Control <ul><li>Single repo (repository)
  29. 29. Always commit to central
  30. 30. Can branch centrally </li></ul>
  31. 31. Repository Structure (Feature Branches)
  32. 32. Repository Structure (Long-Lived Branches)
  33. 33. Repository Structure (Release Branches)
  34. 34. Distributed Source Control repo repo repo repo repo
  35. 35. Distributed Source Control <ul><li>Many repos
  36. 36. Commit to local repo
  37. 37. Share changes between anywhere
  38. 38. No central point </li></ul>
  39. 39. The Changing Landscape <ul><li>Very active development area
  40. 40. Today's conclusions not valid for long! </li></ul>
  41. 41. Bridges <ul><li>git-svn </li><ul><li>http://www.kernel.org/pub/software/scm/git/docs/git-svn.html </li></ul><li>bzr-svn </li><ul><li>https://launchpad.net/bzr-svn </li></ul><li>Check out from SVN to local repo
  42. 42. Make as many changes/branches as you like
  43. 43. Push back to SVN </li></ul>
  44. 44. Hosted Solutions GitHub http://github.com/ git Bitbucket http://bitbucket.org/ hg Google Code http://code.google.com/ svn, hg Launchpad https://launchpad.net/ bzr SourceForge http://sourceforge.net/ svn, bzr, hg, git (and cvs)
  45. 45. What If I Don't Have Source Control? <ul><li>Get some :)
  46. 46. Install subversion
  47. 47. Use a hosted solution </li></ul>
  48. 48. Resources <ul><li>Talks at TEK-X </li><ul><li>Subversion in a Distributed World, Lorna Mitchell
  49. 49. Getting Git, Travis Swicegood (who literally wrote the book)
  50. 50. Both Wednesday afternoon </li></ul><li>Subversion book </li><ul><li>http://svnbook.red-bean.com/ </li></ul><li>Comparison of tools </li><ul><li>http://en.wikipedia.org/wiki/Comparison_of_revision_control_software </li></ul></ul>
  51. 51. Coding Standards
  52. 52. You don't have a standard when … <ul><li>You always reformat code you get from others
  53. 53. Code you wrote 6 months ago looks different than what you wrote today
  54. 54. Modifying old code often introduces new syntax errors </li></ul>
  55. 55. Answer the following questions: <ul><li>Can you read your own code?
  56. 56. Can others read your code?
  57. 57. Can you read other's code?
  58. 58. Can you switch between code bases easily? </li></ul>
  59. 59. Analogy &quot;Elements of Style&quot; :: Writing Coding Standard :: Development
  60. 60. In sum, coding standards assist in: <ul><li>Maintainability
  61. 61. Collaboration </li></ul>
  62. 62. How CS aids maintainability: Code is structured predictably
  63. 63. How CS aids collaboration <ul><li>Any developer can pick up and easily read existing code
  64. 64. … which in turn means they can maintain it
  65. 65. … which de-centralizes who is responsible for the code
  66. 66. … which means issues and reature requests are resolved faster
  67. 67. It democratizes code maintenance </li></ul>
  68. 68. Two pillars of a Coding Standard: <ul><li>Consistency of file system layout
  69. 69. Consistency of code layout </li></ul>
  70. 70. Ancillary goal: <ul><li>Consistency in naming </li></ul>
  71. 71. Use Public Standards <ul><li>NIH has no place with CS </li><ul><li>You and your project's needs are not unique
  72. 72. What if you need to consume and potentially help maintain 3rd party libraries?
  73. 73. Benefit from collective knowledge and empirical discoveries </li></ul></ul>
  74. 74. Need more reasons? <ul><li>Objectivity </li><ul><li>Choices are no longer based on subjective preferences, but on empirical experience. </li></ul><li>Requirement when hiring or outsourcing </li><ul><li>Easily judge the candidate's experience and code quality. </li></ul><li>Compatibility </li><ul><li>Use a standard that follows that of the libraries you use. </li></ul></ul>
  75. 75. Choices <ul><li>Horde/PEAR/Zend Framework </li><ul><li>Also: Solar, AdoDB, Doctrine 2, Symfony 2, and more... </li></ul><li>eZcomponents/ZetaComponents
  76. 76. PHPLIB </li></ul>
  77. 77. Example <?php /** * In Foo/Bar.php */ class Foo_Bar { const BAZ = 'baz' ; protected $_bat ; public $bas ; public function bazBat( $someVar ) { if ( $someVar ) { echo 'Found' ; } } }
  78. 78. Resources <ul><li>PEAR </li><ul><li>http://pear.php.net/manual/en/standards.php
  79. 79. http://pear.php.net/manual/en/pear2cs.php </li></ul><li>Zend Framework </li><ul><li>http://framework.zend.com/manual/en/coding-standard.html </li></ul></ul>
  80. 80. Design Patterns
  81. 81. A Design Pattern Is ... <ul><li>NOT rocket science
  82. 82. A common way to describe a common problem
  83. 83. Shared language
  84. 84. A problem and solution which is repeated many times
  85. 85. Common across programming languages
  86. 86. Heavily OOP </li></ul>
  87. 87. Some Common Patterns <ul><li>Factory
  88. 88. Registry
  89. 89. Adapter
  90. 90. Decorator
  91. 91. Observer </li></ul>
  92. 92. Factory <ul><li>Has methods to create and return objects
  93. 93. May return different objects
  94. 94. May use complex (and maintainable) logic to work out what to do </li></ul>
  95. 95. Factory Example: Hat Types 1 < ?php 2 3 require_once ( 'hat.php' ); 4 5 class HatFactory { 6 public function getHat ( $type = 'woolly' ) { 7 // perform any logic you like here 8 return new Hat ( $type ); 9 } 10 } http://www.flickr.com/photos/91524358@N00/2260054061/
  96. 96. Registry <ul><li>Can be a singleton (but this is not a requirement!)
  97. 97. Register objects here, access from elsewhere
  98. 98. Often a factory/registry combination </li></ul>
  99. 99. Registry Example: Hat Storage 1 < ?php 2 3 class HatRegistry { 4 private $registry ; 5 6 public function __construct () { 7 $this -> registry = array (); 8 } 9 10 public function registerHat ( $key , $hat ) { 11 $this -> registry [ $key ] = $hat ; 12 } 13 14 public function fetchHat ( $key ) { 15 return $this -> registry [ $key ]; 16 } 17 }
  100. 100. Adapter <ul><li>Adapts a specific interface to fit something else; typically, to provide a common API to related classes/components that have divergent APIs.
  101. 101. Allows the class wrapped by the adapter to exist independently from the component consuming the adapter. </li></ul>
  102. 102. Adapter Example: SOAP to REST <ul><li>Real life example
  103. 103. Client project to deliver SOAP </li></ul>
  104. 104. PHP SOAP 1 < ?php 2 3 require_once ( 'lib/myClass.php' ); 4 5 $server = new SoapServer ( null , $options ); 6 $server -> setClass ( &quot;MyClass&quot; ); 7 $server -> handle ();
  105. 105. Adapter Example: SOAP to REST <ul><li>Real life example
  106. 106. Client project to deliver SOAP
  107. 107. Service part-built
  108. 108. Client reads textbook(?)
  109. 109. Client requests REST
  110. 110. Adapter class to the rescue! </li></ul>
  111. 111. Adapter Example: SOAP to REST myClass index.php
  112. 112. Adapter Example: SOAP to REST myClass index.php Adapter
  113. 113. Decorator <ul><li>Wraps another class in order to modify its behavior
  114. 114. Target class doesn't change
  115. 115. Decorating class often implements the same interface(s)
  116. 116. Can be visually decorative, not always </li></ul>
  117. 117. Decorator Example 1 < ?php 2 3 interface LabelInterface { 4 public function render (); 5 } 6 7 class BasicLabel implements LabelInterface { 8 public function render () { 9 return $this -> label ; 10 } 11 }
  118. 118. Decorator Example 13 abstract class LabelDecorator implements LabelInterface { 14 public function __construct ( LabelInterface $label ) { 15 $this -> label = $label ; 16 } 17 } 18 19 class LabelStarDecorator extends LabelDecorator { 20 public function render () { 21 return '** ' . $this -> label -> render () . ' **' ; 22 } 23 } 24 25 class LabelNewLineDecorator extends LabelDecorator { 26 public function render () { 27 return $this -> label -> render () . &quot; &quot; ; 28 } 29 } 30 31 class LabelHyphenDecorator extends LabelDecorator { 32 public function render () { 33 return str_replace ( ' ' , '-' , $this -> label -> render ()); 34 } 35 }
  119. 119. Decorator Example 1 < ?php 2 3 require_once ( 'Label.php' ); 4 5 $basic_label = new BasicLabel (); 6 $basic_label -> label = &quot;Hello World&quot; ; 7 echo $basic_label -> render (); 8 9 $label = new LabelNewLineDecorator ( new LabelStarDecorator ( $basic_label )); 10 $label = new LabelNewLineDecorator ( new LabelStarDecorator ( new LabelHyphenDecorator ( $basic_label ))); 11 $label = new LabelNewLineDecorator ( new LabelHyphenDecorator ( new LabelStarDecorator ( $basic_label )));
  120. 120. Observer <ul><li>Watches for changes in another object
  121. 121. Responds to those changes
  122. 122. Target class is aware, notifies observing classes
  123. 123. Example: a map showing where event attendees are located - needs to update when list updates </li></ul>
  124. 124. Observer Example 3 class AttendeeList { 4 private $attendees ; 5 private $observers ; 6 7 public function addAttendee ( $id , $name ) { 8 $this -> attendees [ $id ] = $name ; 9 $this -> notify (); 10 } 11 12 public function removeAttendee ( $id ) { 13 unset ( $this -> attendees [ $id ]); 14 $this -> notify (); 15 } 16 17 public function notify () { 18 foreach ( $this -> observers as $ob ) { 19 $ob -> update ( $this ); 20 } 21 } 22 23 public function registerObserver ( $observer ) { 24 $this -> observers [] = $observer ; 25 } 26 }
  125. 125. Observer Example AttendeeList Map Invites ...
  126. 126. Resources <ul><li>Books </li><ul><li>Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides (&quot;Gang of Four&quot;)
  127. 127. php|architect’s Guide to PHP Design Patterns by Jason Sweat
  128. 128. Patterns of Enterprise Application Architecture by Martin Fowler (&quot;PoEAA&quot;) </li></ul><li>Jason Sweat speaking on Design Patterns (Friday morning at TEK-X)
  129. 129. http://www.fluffycat.com/PHP-Design-Patterns/ </li></ul>
  130. 130. Documentation
  131. 131. API Docs <ul><li>Documentation generated from source code itself
  132. 132. Follows code structure </li><ul><li>classes
  133. 133. inheritance
  134. 134. methods
  135. 135. parameters </li></ul></ul>
  136. 136. PHPDocumentor
  137. 137. PHPDocumentor <ul><li>PHPDocumentor </li><ul><li>http://www.phpdoc.org/ </li></ul><li>Uses reflection
  138. 138. Comments for additional information
  139. 139. Add descriptions to the documentation </li></ul>
  140. 140. PHPDocumentor Comments 1 < ?php 2 3 class AttendeeList { 4 private $attendees ; 5 private $observers ; 6 7 /** 8 * Add an attendee to the list 9 * 10 * @param integer $id Attendee identifier/array index 11 * @param string $name Full name of the attendee 12 * @access public 13 * @return boolean If attendee was successfully added 14 */ 15 public function addAttendee ( $id , $name ) { 16 $this -> attendees [ $id ] = $name ; 17 $this -> notify (); 18 } 19 20 }
  141. 141. Generating PHPDoc Output <ul><li>Two main interfaces </li><ul><li>Command line, e.g. </li><ul><li>phpdoc -o HTML:frames:earthli -f sample1.php -t docs </li></ul><li>Web Interface </li></ul><li>IDE Plugins </li></ul>
  142. 142. End-User Documentation
  143. 143. Come again? <ul><li>Narrative documentation for developers
  144. 144. Often describes architecture, theory, and design patterns used
  145. 145. Typically includes many example use cases </li></ul>
  146. 146. What should you use? <ul><li>Wikis </li><ul><li>Easy for others to contribute
  147. 147. Typically un-distributable, never mind offer in alternate formats
  148. 148. Difficult to translate
  149. 149. Usually un-versioned </li></ul></ul>
  150. 150. What should you use? <ul><li>HTML </li><ul><li>Easy for people with any web background to contribute
  151. 151. Distributable, but difficult to offer in alternate formats
  152. 152. Can be translated
  153. 153. Can be versioned </li></ul></ul>
  154. 154. What should you use? <ul><li>Docbook XML </li><ul><li>Reasonably easy for people with a web background to contribute; easier if you establish standards
  155. 155. Distributable, and trivial to offer in alternate formats (e.g., HTML, Windows Help files (CHM), PDF, man pages, etc.)
  156. 156. Can be translated
  157. 157. Can be versioned </li></ul></ul>
  158. 158. Docbook Example <?xml version = &quot;1.0&quot; encoding = &quot;UTF-8&quot; ?> <sect1 id = &quot;some.component&quot; > <title> Using Some Component </title> <para> This is a thorougly magical, catch-all component. <ulink url = &quot;http://wikipedia.com/&quot; > Wikipedia </ulink> may have more info. </para>
  159. 159. Docbook Example <example id = &quot;some.component.example&quot; > <title> Example </title> <programlisting lang = &quot;php&quot; > <![CDATA[ $foo = new Component(); ]] ></programlisting> </example>
  160. 160. Docbook Example <sect2 id = &quot;some.component.more-info&quot; > <title> More information </title> <itemizedlist> <listitem><para> Not much! </para></listitem> </itemizedlist> </sect2> </sect1>
  161. 161. Tools You Will Need <ul><li>xsltproc </li><ul><li>http://xmlsoft.org/XSLT/xsltproc2.html </li></ul><li>PhD (PHP Documentor) </li><ul><li>http://doc.php.net/phd/docs/ </li></ul></ul>
  162. 162. Beyond API Docs <ul><li>Tutorials
  163. 163. Installation instructions
  164. 164. Examples
  165. 165. FAQs
  166. 166. Forums
  167. 167. User-contributed </li></ul>
  168. 168. Be a User-Contributor <ul><li>Answer forum questions
  169. 169. Hang out on the IRC channel
  170. 170. Help with official project documentation
  171. 171. Blog </li><ul><li>http://www.lornajane.net
  172. 172. http://weierophinney.net/matthew/ </li></ul></ul>
  173. 173. Testing
  174. 174. Why Test? <ul><li>Makes future maintenance of the code easier </li><ul><li>Defined expectations
  175. 175. Known behaviors
  176. 176. Identify early when changes in code break existing behaviors </li></ul></ul>
  177. 177. Why Test? <ul><li>Quantify the quality of your code </li><ul><li>Code coverage (not the best metric)
  178. 178. Self-documented behaviors via unit tests </li></ul></ul>
  179. 179. Why Test? <ul><li>Warm fuzzy feeling from seeing green </li></ul>
  180. 180. What testing is not: <ul><li>Reloading </li></ul>
  181. 181. What testing is not: <ul><li>var_dump() </li></ul>
  182. 182. Testing is … <ul><li>Reproducible </li></ul>
  183. 183. Testing is … <ul><li>Automatable </li></ul>
  184. 184. Good testing includes … <ul><li>Defined behaviors
  185. 185. Code examples of use cases
  186. 186. Expectations </li></ul>
  187. 187. Testing frameworks <ul><li>PHPT </li><ul><li>Used by PHP project, some PEAR libraries </li></ul><li>SimpleTest </li><ul><li>JUnit style testing framework </li></ul><li>PHPUnit </li><ul><li>JUnit style testing framework; de facto standard </li></ul></ul>
  188. 188. How to test <ul><li>Create a test case class </li><ul><li>Usually named after the unit or class you're testing </li></ul></ul>class Css2XpathTest extends PHPUnit_Framework_TestCase
  189. 189. How to test <ul><li>What is the behavior you're testing? </li><ul><li>State it in your native language &quot;Should Allow Whitespace In Descendent Selector Expressions&quot;
  190. 190. Create a method named after the behavior public function testShouldAllowWhitespaceInDescendentSelectorExpressions()
  191. 191. Capture the code that should create the behavior $test = Css2Xpath::transform('child > leaf');
  192. 192. Create assertions indicating the expected results $this->assertEquals(&quot;//child/leaf&quot;, $test); </li></ul></ul>
  193. 193. How to test <ul><li>Run the tests </li><ul><li>Success? Move on to the next behavior
  194. 194. Failure? </li><ul><li>Check your test assumptions and assertions
  195. 195. Check your code and correct it
  196. 196. Re-run the tests to verify </li></ul></ul></ul>
  197. 197. Other Testing Topics <ul><li>Test Doubles </li><ul><li>Stubs Replacing an object with another so that the system under test can continue down a path.
  198. 198. Mock Objects Replacing an object with another and defining expectations for it. </li></ul></ul>
  199. 199. Other Testing Topics <ul><li>Test Coverage What lines were executed, and how many times?
  200. 200. Conditional tests Testing only when certain environmental conditions are met.
  201. 201. Functional and Integration tests Testing that the systems a unit interacts with all respond as expected. </li></ul>
  202. 202. Adding tests to existing, untested projects <ul><li>Create tests: </li><ul><li>Whenever you introduce new features, for those features
  203. 203. Whenever you attempt to fix a bug </li><ul><li>Capture the desired behavior in a unit test
  204. 204. Fix the bug </li></ul><li>Whenever you refactor </li></ul></ul>
  205. 205. Test-Driven Development <ul><li>Capture behaviors individually and iteratively in unit tests
  206. 206. Write code to make the tests pass
  207. 207. Allows for playing with APIs before you've committed to coding them
  208. 208. Often hard to get into the rhythm; once you do, often hard to quit </li></ul>
  209. 209. Takeaways <ul><li>Testing is easy </li></ul>class Css2XpathTest extends PHPUnit_Framework_TestCase { public function testShouldAllowWSInDescendentSctrExpressions() { $test = Css2Xpath::transform( 'child > leaf' ); $this ->assertEquals( &quot;//child/leaf&quot; , $test ); } }
  210. 210. Takeaways <ul><li>Test whenever you can -- preferably ALWAYS
  211. 211. Automate your test suite (next topic!) </li></ul>
  212. 212. Quality and CI
  213. 213. Static Analysis <ul><li>Analysing code without execution
  214. 214. Evaluating code properties and patterns
  215. 215. Common tools </li><ul><li>Lines of code ( http://github.com/sebastianbergmann/phploc )
  216. 216. Code sniffer ( http://pear.php.net/PHP_CodeSniffer )
  217. 217. Mess detector ( http://phpmd.org/ ) </li></ul></ul>
  218. 218. Lines of Code <ul><li>Born from PHPUnit
  219. 219. Available via PHPUnit's PEAR channel
  220. 220. Shows lots of stats about a codebase
  221. 221. Methods, lines per method
  222. 222. Cyclomatic complexity: a measure of branching points in code
  223. 223. E.g. when applied to wordpress: </li></ul>
  224. 224. Lines of Code Example * phploc 1.3.2 by Sebastian Bergmann. Directories: 29 Files: 295 Lines of Code (LOC): 138661 Cyclomatic Complexity / Lines of Code: 0.19 Comment Lines of Code (CLOC): 43498 Non-Comment Lines of Code (NCLOC): 95163 * example from http://techportal.ibuildings.com/2010/01/28/phploc-php-lines-of-code/
  225. 225. Lines of Code Example Interfaces: 0 Classes: 168 Abstract: 0 (0.00%) Concrete: 168 (100.00%) Lines of Code / Number of Classes: 377 Methods: 1973 Scope: Non-Static: 1972 (99.95%) Static: 1 (0.05%) Visibility: Public: 1964 (99.54%) Non-Public: 9 (0.46%) Lines of Code / Number of Methods: 32 Cyclomatic Complexity / Number of Methods: 5.44 Functions: 1599 Constants: 272 Global constants: 272 Class constants: 0
  226. 226. Code Sniffer <ul><li>Associated with coding standards
  227. 227. Configurable &quot;sniffs&quot; to look for different properties </li></ul>
  228. 228. Code Sniffer Example * 1 < ?php 2 3 class recipe 4 { 5 6 protected $_id ; 7 8 public $name ; 9 10 public $prep_time ; 11 12 function getIngredients () { 13 $ingredients = Ingredients :: fetchAllById ( $this -> _id ); 14 return $ingredients ; 15 } 16 } * example from http://techportal.ibuildings.com/2009/10/12/usphp_code_sniffer/
  229. 229. Code Sniffer Example FILE: /home/lorna/phpcs/recipe.php ------------------------------------------------------------------- FOUND 8 ERROR(S) AND 0 WARNING(S) AFFECTING 5 LINE(S) ------------------------------------------------------------------- 2 | ERROR | Missing file doc comment 3 | ERROR | Class name must begin with a capital letter 3 | ERROR | Missing class doc comment 6 | ERROR | Protected member variable &quot;_id&quot; must not be prefixed | | with an underscore 12 | ERROR | Missing function doc comment 12 | ERROR | Opening brace should be on a new line 13 | ERROR | Line indented incorrectly; expected at least 8 | | spaces, found 1 13 | ERROR | Spaces must be used to indent lines; tabs are not | | allowed ------------------------------------------------------------------- output of running recipe.php through PEAR sniffs
  230. 230. Mess Detector <ul><li>Uses some &quot;rule of thumb&quot; metrics
  231. 231. Tells you about the codebase, at a macro level
  232. 232. Can catch </li><ul><li>long class/method names and parametere lists
  233. 233. complex code
  234. 234. classes with too many public methods
  235. 235. other &quot;bad smells&quot; </li></ul><li>Under development </li></ul>
  236. 236. Continuous Integration (CI)
  237. 237. Continu … what? <ul><li>Originally, automated build systems for compiled languages
  238. 238. Used in PHP to run unit tests, build documentation, etc.
  239. 239. Basically, any documentation or QA tool we've talked about can and should be automated </li></ul>
  240. 240. Basics <ul><li>System typically monitors commits </li><ul><li>Have a post-receive/commit hook trigger a build
  241. 241. Have cron/sleep processes that periodically wake up and check for new commits </li></ul><li>A PHP Build … </li><ul><li>Runs tests,
  242. 242. Runs QA tools (mess detection, etc.),
  243. 243. Builds documentation </li></ul></ul>
  244. 244. Solutions <ul><li>Ant: http://ant.apache.org/ </li><ul><li>Not CI by itself, but a build system </li></ul></ul><?xml version = &quot;1.0&quot; encoding = &quot;UTF-8&quot; ?> <project name = &quot;zend_framework_current&quot; default = &quot;build&quot; basedir = &quot;.&quot; > <property name = &quot;output.dir&quot; value = &quot;${basedir}/build&quot; /> <target name = &quot;build&quot; depends = &quot;clean, checkout, apidoc, test&quot; /> <target name = &quot;checkout&quot; > <exec executable = &quot;svn&quot; dir = &quot;${basedir}&quot; > <arg line = &quot;co http://framework.zend.com/svn/framework/branch/release-1.10 source&quot; /> </exec> </target> <!-- ... --> </project>
  245. 245. Solutions <ul><li>Phing: http://phing.info/trac/ </li><ul><li>PHP Ant clone; again, not CI, but a build tool </li></ul></ul><?xml version = &quot;1.0&quot; encoding = &quot;UTF-8&quot; ?> <project name = &quot;tekx&quot; basedir = &quot;.&quot; > <property file = &quot;build.properties&quot; /> <target name = &quot;default&quot; > <echo message = &quot;Hello, attendees!&quot; /> </target> </project>
  246. 246. Solutions <ul><li>CruiseControl: http://cruisecontrol.sourceforge.net/ </li><ul><li>Uses Ant under the hood </li></ul></ul><cruisecontrol> <project name = &quot;zend_framework_current&quot; <schedule interval = &quot;86400&quot; > <ant anthome = &quot;apache-ant-1.7.0&quot; buildfile = &quot;projects/${proje </schedule> <modificationset quietperiod = &quot;0&quot; > <svn LocalWorkingCopy = &quot;projects </modificationset>
  247. 247. Solutions <ul><li>CruiseControl </li></ul>
  248. 248. Solutions <ul><li>phpUnderControl: http://www.phpundercontrol.org/ </li><ul><li>Superset of CruiseControl with built-in support for PHPUnit, CodeSniffer, and more. </li></ul></ul>
  249. 249. Solutions <ul><li>Hudson: http://hudson-ci.org/ </li><ul><li>Oracle OSS project, written in Java, under active development.
  250. 250. Also uses Ant for build configuration
  251. 251. PHPUnit support via a generic xUnit plugin
  252. 252. Support for other PHP tasks via a Phing plugin </li></ul></ul>
  253. 253. Solutions <ul><li>Bamboo: http://www.atlassian.com/software/bamboo/ </li><ul><li>Commercial Java CI solution
  254. 254. Can use Ant or Maven
  255. 255. Most PHP QA tools export logs to formats compatible with equivalent Java tools; Bamboo simply uses these logs. </li></ul></ul>
  256. 256. Takeaways <ul><li>Automate your QA tasks </li><ul><li>Find issues early
  257. 257. Fix them before deployment </li></ul><li>Use continuous integration solutions to perform the automation </li></ul>
  258. 258. Resources <ul><li>Sebastian Bergmann's talk &quot;The State of QA Tools in PHP&quot;
  259. 259. http://phpqatools.org
  260. 260. http://phpqabook.com </li></ul>
  261. 261. Deployment
  262. 262. Why You Need A Process <ul><li>Many steps for live deploy
  263. 263. Wrap into one step, you won't miss anything
  264. 264. It'll be done the same way by everyone
  265. 265. You can roll back </li><ul><li>(if you build that into your process) </li></ul></ul>
  266. 266. Deployment Tools <ul><li>Hand-spun scripts
  267. 267. Phing </li><ul><li>http://phing.info/trac/ </li></ul><li>Capistrano (Ruby) </li><ul><li>http://www.capify.org/index.php/Capistrano </li></ul></ul>
  268. 268. Further Reading <ul><li>http://phpdeveloper.org
  269. 269. http://devzone.zend.com
  270. 270. http://techportal.ibuildings.com </li></ul>
  271. 271. Thanks <ul><li>http://joind.in/1563 </li></ul>
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×