Improving QA on PHP projects Michelangelo van Dam ZendCon2010, Santa Clara, CA (USA)
Jan 29, 2015
Improving QA on PHP projects
Michelangelo van DamZendCon2010, Santa Clara, CA (USA)
Michelangelo van Dam• Independent Consultant
• Zend Certified Engineer (ZCE)
• President of PHPBenelux
What’s the benefit of QA?
• early detection of issues• cleaner & consistent code• knowledge about the codebase• increase of confidence
Sebastian Bergmann
• QA expert
• wrote the tools
• speaker and inspirer
Usual Suspects
PHP_CodeSniffer
Example Code
• Zend Framework QuickStart app- http://framework.zend.com/manual/en/learning.quickstart.intro.html
<VirtualHost *:80> DocumentRoot /srv/www/quickstart/public ServerName quickstart.local ServerAdmin root@localhost <Directory /srv/www/quickstart/public> Options Indexes FollowSymlinks AllowOverride All Order allow,deny Allow from all DirectoryIndex index.php </Directory> Alias /reports /srv/www/quickstart/reports <Directory /srv/www/quickstart/reports> Options Indexes FollowSymlinks AllowOverride All Order allow,deny Allow from all DirectoryIndex index.php index.html </Directory></VirtualHost>
VirtualHost Settings
Showtime
Syntax Checking
• PHPLint- comes with PHP binary- validates code for syntax errors• Website- http://www.icosaedro.it/phplint/
Demo PHPLint
Code Documentation
• PHPDocumentator- creates automated API documentation- based on inline code blocks• Installation- pear install PhpDocumentor• Website- http://www.phpdoc.org
Demo PHPDoc
Output PHPDoc
Coding Standards
• PHP_CodeSniffer- sniffs for coding standard violations- ensures code is clean and consistent- using standard and custom coding standards• Installation- pear install PHP_CodeSniffer• Website- http://pear.php.net/package/PHP_CodeSniffer
Demo PHP_CodeSniffer
PHPCPD
• PHP Copy/Paste Detector- detects code duplication• Installation- pear channel-discover pear.phpunit.de- pear channel-discover components.ez.no- pear install --alldeps phpunit/phpcpd• Website- http://github.com/sebastianbergmann/phpcpd
Demo PHPCPD
Output
Mess Detection
• PDepend & PHPMD- detects code mess• Installation- pear channel-discover pear.pdepend.org- pear install pdepend/PHP_Depend- pear channel-discover pear.phpmd.org- pear install phpmd/PHP_PMD• Websites- http://www.pdepend.org- http://www.phpmd.org
Demo detecting mess
Output codesize
Output unused code
Unit Testing
• PHPUnit- tests code on unit level- includes database tests- integrates well with many PHP frameworks• Installation- pear channel-discover pear.phpunit.de- pear install phpunit/PHPUnit• Website- http://www.phpunit.de
See other presentation
http://slideshare.net/DragonBe/unit-testing-after-zf-18
Packaging
• Phar- PHP Archive (equivalent of Java jar)- compresses and collects like- included in PHP build (as of PHP 5.3.0)• Installation (before PHP 5.3.0)- pecl install phar• Website:- http://php.net/phar
Code example<?php
include_once ‘phar://MyApp.phar/path/to/Class.php’;
$application = new Class;$application->run();
Usage
• libraries• modules• images• plugins• deployment
Automated builds
• Phing- automated build tool- like Apache Ant- integrates well with other PHP tools• Installation- pear channel-discover pear.phing.info- pear install phing/phing• Website- http://phing.info
build.xml<?xml version="1.0"?>
<project name="zfqs" description="Zend Framework QuickStart" default="build" > <target name="version"> <version releasetype="Bugfix" file="build.version" property="version.number"/> </target>
<target name="phplint"> <mkdir dir="./reports/phplint" /> <phplint file="./application/models" haltonfailure="false" tofile="./reports/phplint/errors.txt"/> </target>
<target name="pdepend"> <mkdir dir="./reports/pdepend" /> <copy file="./build_pdepend.html" tofile="./reports/pdepend/index.html" overwrite="true" /> <exec command="/usr/bin/pdepend --summary-xml=./reports/pdepend/summary.xml --jdepend-chart=./reports/pdepend/jdepend.svg --overview-pyramid=./reports/pdepend/pyramid.svg ./application/models" dir="./" /> </target>
<target name="phpmd"> <mkdir dir="./reports/phpmd" /> <exec command="/usr/bin/phpmd ./application/models html codesize --reportfile ./reports/phpmd/codesize.html" dir="./" /> <exec command="/usr/bin/phpmd ./application/models html unusedcode --reportfile ./reports/phpmd/unusedcode.html" dir="./" /> </target>
<target name="phpcs"> <mkdir dir="./reports/phpcs" /> <exec command="/usr/bin/phpcs -n --standard=Zend --report=summary ./application/models > ./reports/phpcs/summary.txt" dir="./" /> <exec command="/usr/bin/phpcs -n --standard=Zend --report=source ./application/models > ./reports/phpcs/source.txt" dir="./" /> <exec command="/usr/bin/phpcs -n --standard=Zend --report=checkstyle ./application/models > ./reports/phpcs/checkstyle.xml" dir="./" /> </target>
<target name="phpcpd"> <mkdir dir="./reports/phpcpd" /> <exec command="/usr/bin/phpcpd --log-pmd ./reports/phpcpd/pmd-cpd.xml ./application/models" dir="./" /> </target>
<target name="phpdoc"> <mkdir dir="./reports/phpdoc" /> <exec command="phpdoc -d ./application/models -q -t ./reports/phpdoc -o HTML:frames:earthli" dir="./" /> </target>
<target name="build" depends="version,phplint,pdepend,phpmd,phpcs,phpcpd,phpdoc"> <echo msg="Finishing build process ${version.number}" /> </target></project>
project definition<?xml version="1.0"?>
<project name="zfqs" description="Zend Framework QuickStart" default="build" >…</project>
target version<target name="version"> <version releasetype="Bugfix" file="build.version" property="version.number"/></target>
In file “build.version” we have the version number as the following sequence:
MAJOR.MINOR.BUGFIX (starting at 0.0.0)
target phplint<target name="phplint"> <mkdir dir="./reports/phplint" /> <phplint file="./application/models" haltonfailure="false" tofile="./reports/phplint/errors.txt"/></target>
target pdepend<target name="pdepend"> <mkdir dir="./reports/pdepend" /> <copy file="./build_pdepend.html" tofile="./reports/pdepend/index.html" overwrite="true" /> <exec command="/usr/bin/pdepend --summary-xml=./reports/pdepend/summary.xml --jdepend-chart=./reports/pdepend/jdepend.svg --overview-pyramid=./reports/pdepend/pyramid.svg ./application/models" dir="./" /></target>
target phpmd<target name="phpmd"> <mkdir dir="./reports/phpmd" /> <exec command="/usr/bin/phpmd ./application/models html codesize --reportfile ./reports/phpmd/codesize.html" dir="./" /> <exec command="/usr/bin/phpmd ./application/models html unusedcode --reportfile ./reports/phpmd/unusedcode.html" dir="./" /></target>
target phpcs<target name="phpcs"> <mkdir dir="./reports/phpcs" /> <exec command="/usr/bin/phpcs -n --standard=Zend --report=summary ./application/models > ./reports/phpcs/summary.txt" dir="./" /> <exec command="/usr/bin/phpcs -n --standard=Zend --report=source ./application/models > ./reports/phpcs/source.txt" dir="./" /> <exec command="/usr/bin/phpcs -n --standard=Zend --report=checkstyle ./application/models > ./reports/phpcs/checkstyle.xml" dir="./" /></target>
target phpcpd<target name="phpcpd"> <mkdir dir="./reports/phpcpd" /> <exec command="/usr/bin/phpcpd --log-pmd ./reports/phpcpd/pmd-cpd.xml ./application/models" dir="./" /></target>
target phpdoc<target name="phpdoc"> <mkdir dir="./reports/phpdoc" /> <exec command="phpdoc -d ./application/models -q -t ./reports/phpdoc -o HTML:frames:earthli" dir="./" /></target>
target build<target name="build" depends="version,phplint,pdepend,phpmd,phpcs,phpcpd,phpdoc"> <echo msg="Finishing build process ${version.number}" /></target>
Demo building all
Demo building target
Our reports section
Summary
PHP offers lots of toolsmore consistent and clean code
automated process
• http://slideshare.net/DragonBe/improving-qa-on-php-projects
• http://twitter.com/DragonBe• http://facebook.com/DragonBe
• http://joind.in/2279
Questions