SlideShare a Scribd company logo
1 of 65
Download to read offline
QA	
  for	
  PHP	
  projects
using	
  PHPStorm
JetBrains	
  Webinar,	
  April	
  25	
  2013
2
Michelangelo	
  van	
  Dam
Goals
3
• improve	
  QA	
  in	
  your	
  PHP	
  projects
• deliver	
  higher	
  quality	
  of	
  applicaIons
• become	
  familiarized	
  with	
  available	
  tools
Our	
  host	
  for	
  this	
  webinar
4
Why	
  Quality	
  Assurance
5
6
Safeguarding	
  code
7
Detect	
  bugs	
  early
8
Observe	
  behaviour
9
Prevent	
  accidents
10
Tracking	
  progress
Let’s	
  get	
  our	
  hands	
  dirty
11
Revision	
  Control
12
13
FTP
Advantages of SCM
• team development possible
• tracking multi-versions of source code
• moving back and forth in history
• tagging of milestones
• backup of source code
• accessible from
- command line
- native apps
- IDE’s like JetBrain’s IDE
- analytical tools
TIP:	
  hooks	
  for	
  tools
PHP	
  Lint
15
PHP	
  Lint
16
• checks the syntax of code
• build in PHP core
• is used per file
- pre-commit hook for version control system
- batch processing of files
• can provide reports
- but if something fails -> the build fails
TIP:	
  pre-­‐commit	
  hook
Running	
  on	
  command	
  line
17
SCM	
  commit	
  hook
18
#!/bin/sh
#
# Pre-commit hook to validate syntax of incoming PHP files, if no failures it
# accepts the commit, otherwise it fails and blocks the commit
REPOS="$1"
TXN="$2"
# modify these system executables to match your system
PHP=/usr/bin/php
AWK=/usr/bin/awk
GREP=/bin/grep
SVNLOOK=/usr/bin/svnlook
# PHP Syntax checking with PHP Lint
# originally from Joe Stump at Digg
# https://gist.github.com/53225
#
for i in `$SVNLOOK changed -t "$TXN" "$REPOS" | $AWK '{print $2}'`
do
if [ ${i##*.} == php ]; then
CHECK=`$SVNLOOK cat -t "$TXN" "$REPOS" $i | $PHP -d html_errors=off -l || echo $i`
RETURN=`echo $CHECK | $GREP "^No syntax" > /dev/null && echo TRUE || echo FALSE`
if [ $RETURN = 'FALSE' ]; then
echo $CHECK 1>&2;
exit 1
fi
fi
done
No	
  syntax	
  failures
19
PHPStorm	
  syntax	
  checking
20
DocumentaIon
21
Why	
  documenIng?
22
• new	
  members	
  in	
  the	
  team
• working	
  with	
  remote	
  workers
• analyzing	
  improvements
• think	
  before	
  doing
• used	
  by	
  IDE’s	
  and	
  editors	
  for	
  code	
  hinIng	
  ;-­‐)
PHPDocumentor2
23
Class	
  details
24
Uses	
  docblock	
  in	
  code
25
Class	
  graphs
26
Debugging
27
The	
  art	
  of	
  finding	
  a	
  bug
28
• Debugging	
  allows	
  you	
  to	
  walk	
  step-­‐by-­‐step	
  
through	
  your	
  code	
  base	
  unIl	
  you	
  reach	
  the	
  
point	
  of	
  failure.
XDebug	
  php.ini	
  se`ngs
[xdebug]
zend_extension=/usr/lib/php/extensions/xdebug.so
xdebug.default_enable=1
xdebug.cli_color=1
xdebug.remote_enable=on
xdebug.remote_connect_back=1
xdebug.remote_handler=dbgp
xdebug.remote_host=127.0.0.1
xdebug.remote_port=9000
xdebug.scream=1
29
Debugging	
  in	
  PHPStorm
30
TesIng
31
Most	
  common	
  excuses
32
• no	
  Ime
• not	
  within	
  budget
• development	
  team	
  does	
  not	
  know	
  how
• tests	
  are	
  provided	
  aaer	
  delivery
• …
NO	
  EXCUSE!
33
Benefits	
  of	
  tesIng
34
• beder	
  code	
  with	
  smaller	
  footprint
• allows	
  refactoring
• detects	
  bugs	
  in	
  an	
  early	
  stage
• saves	
  Ime	
  in	
  maintenance	
  stage
Se`ng	
  things	
  up
35
ConfiguraIon:	
  phpunit.xml
36
<phpunit bootstrap="./Bootstrap.php">
<testsuite name="Unit test suite">
<directory>./</directory>
</testsuite>
<filter>
<whitelist>
<directory suffix=".php">../application/</directory>
<directory suffix=".php">../library/</directory>
</whitelist>
</filter>
</phpunit>
Bootstrapping	
  app
<?php
// set our app paths and environments
define('BASE_PATH', realpath(dirname(__FILE__) . '/../'));
define('APPLICATION_PATH', BASE_PATH . '/application');
define('TEST_PATH', BASE_PATH . '/tests');
define('APPLICATION_ENV', 'testing');
// Include path
set_include_path(
. PATH_SEPARATOR . BASE_PATH . '/library'
. PATH_SEPARATOR . get_include_path()
);
// Set the default timezone !!!
date_default_timezone_set('Europe/Brussels');
// We wanna catch all errors en strict warnings
error_reporting(E_ALL|E_STRICT);
require_once 'Zend/Application.php';
$application = new Zend_Application(
APPLICATION_ENV,
APPLICATION_PATH . '/configs/application.ini'
);
$application->bootstrap();
37
WriIng	
  tests
38
TesIng	
  a	
  class
39
WriIng	
  a	
  test
40
<?php
class Application_Model_CommentTest extends PHPUnit_Framework_TestCase
{
protected $_comment;
protected function setUp()
{
$this->_comment = new Application_Model_Comment();
parent::setUp();
}
protected function tearDown()
{
parent::tearDown();
$this->_comment = null;
}
public function testModelIsEmptyAtConstruct()
{
$this->assertSame(0, $this->_comment->getId());
$this->assertNull($this->_comment->getFullName());
$this->assertNull($this->_comment->getEmailAddress());
$this->assertNull($this->_comment->getWebsite());
$this->assertNull($this->_comment->getComment());
}
}
WriIng	
  the	
  class
<?php
class Application_Model_Comment
{
protected $_id = 0; protected $_fullName; protected $_emailAddress;
protected $_website; protected $_comment;
public function setId($id) { $this->_id = (int) $id; return $this; }
public function getId() { return $this->_id; }
public function setFullName($fullName) { $this->_fullName = (string) $fullName; return $this; }
public function getFullName() { return $this->_fullName; }
public function setEmailAddress($emailAddress) { $this->_emailAddress = (string) $emailAddress; return $this; }
public function getEmailAddress() { return $this->_emailAddress; }
public function setWebsite($website) { $this->_website = (string) $website; return $this; }
public function getWebsite() { return $this->_website; }
public function setComment($comment) { $this->_comment = (string) $comment; return $this; }
public function getComment() { return $this->_comment; }
public function populate($row) {
if (is_array($row)) {
$row = new ArrayObject($row, ArrayObject::ARRAY_AS_PROPS);
}
if (isset ($row->id)) $this->setId($row->id);
if (isset ($row->fullName)) $this->setFullName($row->fullName);
if (isset ($row->emailAddress)) $this->setEmailAddress($row->emailAddress);
if (isset ($row->website)) $this->setWebsite($row->website);
if (isset ($row->comment)) $this->setComment($row->comment);
}
public function toArray() {
return array (
'id' => $this->getId(),
'fullName' => $this->getFullName(),
'emailAddress' => $this->getEmailAddress(),
'website' => $this->getWebsite(),
'comment' => $this->getComment(),
);
}
}
41
Adding	
  validaIon
protected $_filters;
protected $_validators;
public function __construct($params = null)
{
$this->_filters = array (
'id' => array ('Int'),
'fullName' => array ('StringTrim', 'StripTags', new Zend_Filter_Alnum(true)),
'emailAddress' => array ('StringTrim', 'StripTags', 'StringToLower'),
'website' => array ('StringTrim', 'StripTags', 'StringToLower'),
'comment' => array ('StringTrim', 'StripTags'),
);
$this->_validators = array (
'id' => array ('Int'),
'fullName' => array (
new Zftest_Validate_Mwop(),
new Zend_Validate_StringLength(array ('min' => 4, 'max' => 50)),
),
'emailAddress' => array (
'EmailAddress',
new Zend_Validate_StringLength(array ('min' => 4, 'max' => 50)),
),
'website' => array (
new Zend_Validate_Callback(array('Zend_Uri', 'check')),
new Zend_Validate_StringLength(array ('min' => 4, 'max' => 50)),
),
'comment' => array (
new Zftest_Validate_TextBox(),
new Zend_Validate_StringLength(array ('max' => 5000)),
),
);
if (null !== $params) { $this->populate($params); }
}
42
Modify	
  seders	
  &	
  geders
public function setId($id)
{
$input = new Zend_Filter_Input($this->_filters, $this->_validators);
$input->setData(array ('id' => $id));
if (!$input->isValid('id')) {
throw new Zend_Exception('Invalid ID provided');
}
$this->_id = (int) $input->id;
return $this;
}
public function setFullName($fullName)
{
$input = new Zend_Filter_Input($this->_filters, $this->_validators);
$input->setData(array ('fullName' => $fullName));
if (!$input->isValid('fullName')) {
throw new Zend_Exception('Invalid fullName provided');
}
$this->_fullName = (string) $input->fullName;
return $this;
}
43
Modify	
  seders	
  &	
  geders	
  2
public function setEmailAddress($emailAddress)
{
$input = new Zend_Filter_Input($this->_filters, $this->_validators);
$input->setData(array ('emailAddress' => $emailAddress));
if (!$input->isValid('emailAddress')) {
throw new Zend_Exception('Invalid emailAddress provided');
}
$this->_emailAddress = (string) $input->emailAddress;
return $this;
}
public function setWebsite($website)
{
$input = new Zend_Filter_Input($this->_filters, $this->_validators);
$input->setData(array ('website' => $website));
if (!$input->isValid('website')) {
throw new Zend_Exception('Invalid website provided');
}
$this->_website = (string) $input->website;
return $this;
}
44
Modify	
  geders	
  &	
  seders	
  3
public function setComment($comment)
{
$input = new Zend_Filter_Input($this->_filters, $this->_validators);
$input->setData(array ('comment' => $comment));
if (!$input->isValid('comment')) {
throw new Zend_Exception('Invalid comment provided');
}
$this->_comment = (string) $input->comment;
return $this;
}
45
Running	
  tests
46
Or	
  in	
  PHPStorm
47
Mess	
  DetecIon
48
Mess	
  DetecIon
49
• code	
  smells
• possible	
  bugs
• sub-­‐opImal	
  code
• over	
  complicated	
  expressions
• unused	
  parameters,	
  methods	
  and	
  properIes
• wrongly	
  named	
  parameters,	
  methods	
  or	
  
properIes
Running	
  on	
  command	
  line
50
Running	
  in	
  PHPStorm
51
AutomaIon
52
Key	
  reason
53
“computers are great at doing repetitive tasks very well”
AutomaIon
54
• Limit	
  risk	
  of	
  human	
  error
• Will	
  always	
  be	
  executed	
  in	
  same	
  order
• Can	
  be	
  shared	
  amongst	
  team	
  members
• Allows	
  to	
  fine-­‐tune	
  and	
  improve	
  features
55
AutomaIon	
  with	
  Phing
Running	
  Phing	
  on	
  CLI
56
Running	
  in	
  PHPStorm
57
Summary
58
Overview	
  of	
  tools
59
• SCM	
  (SVN,	
  GIT,	
  …)
• PHP	
  Lint
• PHP	
  Document	
  Generator
• Debugging
• PHPUnit	
  TesIng
• PHP	
  Mess	
  detecIon
• Phing	
  automaIon
}
Quality	
  Assurance
• is	
  part	
  of	
  development	
  process
• will	
  only	
  work	
  if	
  the	
  tools	
  are	
  available
• and	
  developers	
  see	
  the	
  benefits	
  of	
  QA
60
PHPStorm	
  IDE
61
Contact
62
Michelangelo van Dam
Zend Certified Engineer
email: michelangelo@in2it.be
skype: michelangelovandam
twitter: @DragonBe
tel EU: +32 15 34 52 90
tel US: 202 559-7401
www.in2it.be
facebook.com/in2itvof | @in2itvof
Contact us for
Consultancy - Training - QA - Webdesign
Credits
I’d like to thank the following people for sharing their creative commons pictures
michelangelo: http://www.flickr.com/photos/dasprid/5148937451
birds: http://www.flickr.com/photos/andyofne/4633356197
safeguarding: http://www.flickr.com/photos/infidelic/4306205887/
bugs: http://www.flickr.com/photos/goingslo/4523034319
behaviour: http://www.flickr.com/photos/yuan2003/1812881370
prevention: http://www.flickr.com/photos/robertelyov/5159801170
progress: http://www.flickr.com/photos/dingatx/4115844000
file cabinet: http://www.flickr.com/photos/manc/1427691715
documentation: http://www.flickr.com/photos/dennis_matheson/3269442687
exam: http://www.flickr.com/photos/albertogp123/5843577306
dead roach: http://www.flickr.com/photos/stevensnodgrass/7504408776
garbage: http://www.flickr.com/photos/amstersam/4608512202
gears: http://www.flickr.com/photos/freefoto/5982549938
elephpant: http://www.flickr.com/photos/drewm/3191872515
Fork	
  this	
  code
http://github.com/DragonBe/zftest
64
Thank	
  you
65

More Related Content

What's hot

Beginning PHPUnit
Beginning PHPUnitBeginning PHPUnit
Beginning PHPUnit
Jace Ju
 

What's hot (20)

UA testing with Selenium and PHPUnit - PFCongres 2013
UA testing with Selenium and PHPUnit - PFCongres 2013UA testing with Selenium and PHPUnit - PFCongres 2013
UA testing with Selenium and PHPUnit - PFCongres 2013
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applications
 
Dependency Injection in PHP
Dependency Injection in PHPDependency Injection in PHP
Dependency Injection in PHP
 
PHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the testsPHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the tests
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 
TDC2016SP - Trilha Developing for Business
TDC2016SP - Trilha Developing for BusinessTDC2016SP - Trilha Developing for Business
TDC2016SP - Trilha Developing for Business
 
Developing for Business
Developing for BusinessDeveloping for Business
Developing for Business
 
PHP 7 Crash Course
PHP 7 Crash CoursePHP 7 Crash Course
PHP 7 Crash Course
 
Forget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers CracowForget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers Cracow
 
Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8
 
PHP security audits
PHP security auditsPHP security audits
PHP security audits
 
Back to basics - PHP_Codesniffer
Back to basics - PHP_CodesnifferBack to basics - PHP_Codesniffer
Back to basics - PHP_Codesniffer
 
Building a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing StrategiesBuilding a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing Strategies
 
PHPunit and you
PHPunit and youPHPunit and you
PHPunit and you
 
QA for PHP projects
QA for PHP projectsQA for PHP projects
QA for PHP projects
 
Beginning PHPUnit
Beginning PHPUnitBeginning PHPUnit
Beginning PHPUnit
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
Building Maintainable Applications in Apex
Building Maintainable Applications in ApexBuilding Maintainable Applications in Apex
Building Maintainable Applications in Apex
 
Dependency Injection Smells
Dependency Injection SmellsDependency Injection Smells
Dependency Injection Smells
 

Similar to Quality assurance for php projects with PHPStorm

Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012
Michelangelo van Dam
 
Dealing with Legacy PHP Applications
Dealing with Legacy PHP ApplicationsDealing with Legacy PHP Applications
Dealing with Legacy PHP Applications
Clinton Dreisbach
 
symfony on action - WebTech 207
symfony on action - WebTech 207symfony on action - WebTech 207
symfony on action - WebTech 207
patter
 

Similar to Quality assurance for php projects with PHPStorm (20)

Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012
 
Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2
 
Becoming a better WordPress Developer
Becoming a better WordPress DeveloperBecoming a better WordPress Developer
Becoming a better WordPress Developer
 
Workshop quality assurance for php projects - phpbelfast
Workshop quality assurance for php projects - phpbelfastWorkshop quality assurance for php projects - phpbelfast
Workshop quality assurance for php projects - phpbelfast
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
 
Workshop quality assurance for php projects - phpdublin
Workshop quality assurance for php projects - phpdublinWorkshop quality assurance for php projects - phpdublin
Workshop quality assurance for php projects - phpdublin
 
Zend Framework
Zend FrameworkZend Framework
Zend Framework
 
Fatc
FatcFatc
Fatc
 
Review unknown code with static analysis Zend con 2017
Review unknown code with static analysis  Zend con 2017Review unknown code with static analysis  Zend con 2017
Review unknown code with static analysis Zend con 2017
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
Dealing with Legacy PHP Applications
Dealing with Legacy PHP ApplicationsDealing with Legacy PHP Applications
Dealing with Legacy PHP Applications
 
Zend Certification PHP 5 Sample Questions
Zend Certification PHP 5 Sample QuestionsZend Certification PHP 5 Sample Questions
Zend Certification PHP 5 Sample Questions
 
OOP Is More Than Cars and Dogs
OOP Is More Than Cars and DogsOOP Is More Than Cars and Dogs
OOP Is More Than Cars and Dogs
 
Ch ch-changes cake php2
Ch ch-changes cake php2Ch ch-changes cake php2
Ch ch-changes cake php2
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy Code
 
PHPSpec BDD for PHP
PHPSpec BDD for PHPPHPSpec BDD for PHP
PHPSpec BDD for PHP
 
symfony on action - WebTech 207
symfony on action - WebTech 207symfony on action - WebTech 207
symfony on action - WebTech 207
 
Php on the desktop and php gtk2
Php on the desktop and php gtk2Php on the desktop and php gtk2
Php on the desktop and php gtk2
 
My Development Story
My Development StoryMy Development Story
My Development Story
 

More from Michelangelo van Dam

Zf2 how arrays will save your project
Zf2   how arrays will save your projectZf2   how arrays will save your project
Zf2 how arrays will save your project
Michelangelo van Dam
 

More from Michelangelo van Dam (20)

GDPR Art. 25 - Privacy by design and default
GDPR Art. 25 - Privacy by design and defaultGDPR Art. 25 - Privacy by design and default
GDPR Art. 25 - Privacy by design and default
 
Moving from app services to azure functions
Moving from app services to azure functionsMoving from app services to azure functions
Moving from app services to azure functions
 
Privacy by design
Privacy by designPrivacy by design
Privacy by design
 
DevOps or DevSecOps
DevOps or DevSecOpsDevOps or DevSecOps
DevOps or DevSecOps
 
Privacy by design
Privacy by designPrivacy by design
Privacy by design
 
Continuous deployment 2.0
Continuous deployment 2.0Continuous deployment 2.0
Continuous deployment 2.0
 
Let your tests drive your code
Let your tests drive your codeLet your tests drive your code
Let your tests drive your code
 
General Data Protection Regulation, a developer's story
General Data Protection Regulation, a developer's storyGeneral Data Protection Regulation, a developer's story
General Data Protection Regulation, a developer's story
 
Leveraging a distributed architecture to your advantage
Leveraging a distributed architecture to your advantageLeveraging a distributed architecture to your advantage
Leveraging a distributed architecture to your advantage
 
The road to php 7.1
The road to php 7.1The road to php 7.1
The road to php 7.1
 
Open source for a successful business
Open source for a successful businessOpen source for a successful business
Open source for a successful business
 
Decouple your framework now, thank me later
Decouple your framework now, thank me laterDecouple your framework now, thank me later
Decouple your framework now, thank me later
 
Deploy to azure in less then 15 minutes
Deploy to azure in less then 15 minutesDeploy to azure in less then 15 minutes
Deploy to azure in less then 15 minutes
 
Azure and OSS, a match made in heaven
Azure and OSS, a match made in heavenAzure and OSS, a match made in heaven
Azure and OSS, a match made in heaven
 
Getting hands dirty with php7
Getting hands dirty with php7Getting hands dirty with php7
Getting hands dirty with php7
 
Zf2 how arrays will save your project
Zf2   how arrays will save your projectZf2   how arrays will save your project
Zf2 how arrays will save your project
 
Create, test, secure, repeat
Create, test, secure, repeatCreate, test, secure, repeat
Create, test, secure, repeat
 
The Continuous PHP Pipeline
The Continuous PHP PipelineThe Continuous PHP Pipeline
The Continuous PHP Pipeline
 
Easily extend your existing php app with an api
Easily extend your existing php app with an apiEasily extend your existing php app with an api
Easily extend your existing php app with an api
 
Your code are my tests
Your code are my testsYour code are my tests
Your code are my tests
 

Recently uploaded

Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 

Recently uploaded (20)

How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 

Quality assurance for php projects with PHPStorm

  • 1. QA  for  PHP  projects using  PHPStorm JetBrains  Webinar,  April  25  2013
  • 3. Goals 3 • improve  QA  in  your  PHP  projects • deliver  higher  quality  of  applicaIons • become  familiarized  with  available  tools
  • 4. Our  host  for  this  webinar 4
  • 11. Let’s  get  our  hands  dirty 11
  • 14. Advantages of SCM • team development possible • tracking multi-versions of source code • moving back and forth in history • tagging of milestones • backup of source code • accessible from - command line - native apps - IDE’s like JetBrain’s IDE - analytical tools TIP:  hooks  for  tools
  • 16. PHP  Lint 16 • checks the syntax of code • build in PHP core • is used per file - pre-commit hook for version control system - batch processing of files • can provide reports - but if something fails -> the build fails TIP:  pre-­‐commit  hook
  • 18. SCM  commit  hook 18 #!/bin/sh # # Pre-commit hook to validate syntax of incoming PHP files, if no failures it # accepts the commit, otherwise it fails and blocks the commit REPOS="$1" TXN="$2" # modify these system executables to match your system PHP=/usr/bin/php AWK=/usr/bin/awk GREP=/bin/grep SVNLOOK=/usr/bin/svnlook # PHP Syntax checking with PHP Lint # originally from Joe Stump at Digg # https://gist.github.com/53225 # for i in `$SVNLOOK changed -t "$TXN" "$REPOS" | $AWK '{print $2}'` do if [ ${i##*.} == php ]; then CHECK=`$SVNLOOK cat -t "$TXN" "$REPOS" $i | $PHP -d html_errors=off -l || echo $i` RETURN=`echo $CHECK | $GREP "^No syntax" > /dev/null && echo TRUE || echo FALSE` if [ $RETURN = 'FALSE' ]; then echo $CHECK 1>&2; exit 1 fi fi done
  • 22. Why  documenIng? 22 • new  members  in  the  team • working  with  remote  workers • analyzing  improvements • think  before  doing • used  by  IDE’s  and  editors  for  code  hinIng  ;-­‐)
  • 25. Uses  docblock  in  code 25
  • 28. The  art  of  finding  a  bug 28 • Debugging  allows  you  to  walk  step-­‐by-­‐step   through  your  code  base  unIl  you  reach  the   point  of  failure.
  • 32. Most  common  excuses 32 • no  Ime • not  within  budget • development  team  does  not  know  how • tests  are  provided  aaer  delivery • …
  • 34. Benefits  of  tesIng 34 • beder  code  with  smaller  footprint • allows  refactoring • detects  bugs  in  an  early  stage • saves  Ime  in  maintenance  stage
  • 36. ConfiguraIon:  phpunit.xml 36 <phpunit bootstrap="./Bootstrap.php"> <testsuite name="Unit test suite"> <directory>./</directory> </testsuite> <filter> <whitelist> <directory suffix=".php">../application/</directory> <directory suffix=".php">../library/</directory> </whitelist> </filter> </phpunit>
  • 37. Bootstrapping  app <?php // set our app paths and environments define('BASE_PATH', realpath(dirname(__FILE__) . '/../')); define('APPLICATION_PATH', BASE_PATH . '/application'); define('TEST_PATH', BASE_PATH . '/tests'); define('APPLICATION_ENV', 'testing'); // Include path set_include_path( . PATH_SEPARATOR . BASE_PATH . '/library' . PATH_SEPARATOR . get_include_path() ); // Set the default timezone !!! date_default_timezone_set('Europe/Brussels'); // We wanna catch all errors en strict warnings error_reporting(E_ALL|E_STRICT); require_once 'Zend/Application.php'; $application = new Zend_Application( APPLICATION_ENV, APPLICATION_PATH . '/configs/application.ini' ); $application->bootstrap(); 37
  • 40. WriIng  a  test 40 <?php class Application_Model_CommentTest extends PHPUnit_Framework_TestCase { protected $_comment; protected function setUp() { $this->_comment = new Application_Model_Comment(); parent::setUp(); } protected function tearDown() { parent::tearDown(); $this->_comment = null; } public function testModelIsEmptyAtConstruct() { $this->assertSame(0, $this->_comment->getId()); $this->assertNull($this->_comment->getFullName()); $this->assertNull($this->_comment->getEmailAddress()); $this->assertNull($this->_comment->getWebsite()); $this->assertNull($this->_comment->getComment()); } }
  • 41. WriIng  the  class <?php class Application_Model_Comment { protected $_id = 0; protected $_fullName; protected $_emailAddress; protected $_website; protected $_comment; public function setId($id) { $this->_id = (int) $id; return $this; } public function getId() { return $this->_id; } public function setFullName($fullName) { $this->_fullName = (string) $fullName; return $this; } public function getFullName() { return $this->_fullName; } public function setEmailAddress($emailAddress) { $this->_emailAddress = (string) $emailAddress; return $this; } public function getEmailAddress() { return $this->_emailAddress; } public function setWebsite($website) { $this->_website = (string) $website; return $this; } public function getWebsite() { return $this->_website; } public function setComment($comment) { $this->_comment = (string) $comment; return $this; } public function getComment() { return $this->_comment; } public function populate($row) { if (is_array($row)) { $row = new ArrayObject($row, ArrayObject::ARRAY_AS_PROPS); } if (isset ($row->id)) $this->setId($row->id); if (isset ($row->fullName)) $this->setFullName($row->fullName); if (isset ($row->emailAddress)) $this->setEmailAddress($row->emailAddress); if (isset ($row->website)) $this->setWebsite($row->website); if (isset ($row->comment)) $this->setComment($row->comment); } public function toArray() { return array ( 'id' => $this->getId(), 'fullName' => $this->getFullName(), 'emailAddress' => $this->getEmailAddress(), 'website' => $this->getWebsite(), 'comment' => $this->getComment(), ); } } 41
  • 42. Adding  validaIon protected $_filters; protected $_validators; public function __construct($params = null) { $this->_filters = array ( 'id' => array ('Int'), 'fullName' => array ('StringTrim', 'StripTags', new Zend_Filter_Alnum(true)), 'emailAddress' => array ('StringTrim', 'StripTags', 'StringToLower'), 'website' => array ('StringTrim', 'StripTags', 'StringToLower'), 'comment' => array ('StringTrim', 'StripTags'), ); $this->_validators = array ( 'id' => array ('Int'), 'fullName' => array ( new Zftest_Validate_Mwop(), new Zend_Validate_StringLength(array ('min' => 4, 'max' => 50)), ), 'emailAddress' => array ( 'EmailAddress', new Zend_Validate_StringLength(array ('min' => 4, 'max' => 50)), ), 'website' => array ( new Zend_Validate_Callback(array('Zend_Uri', 'check')), new Zend_Validate_StringLength(array ('min' => 4, 'max' => 50)), ), 'comment' => array ( new Zftest_Validate_TextBox(), new Zend_Validate_StringLength(array ('max' => 5000)), ), ); if (null !== $params) { $this->populate($params); } } 42
  • 43. Modify  seders  &  geders public function setId($id) { $input = new Zend_Filter_Input($this->_filters, $this->_validators); $input->setData(array ('id' => $id)); if (!$input->isValid('id')) { throw new Zend_Exception('Invalid ID provided'); } $this->_id = (int) $input->id; return $this; } public function setFullName($fullName) { $input = new Zend_Filter_Input($this->_filters, $this->_validators); $input->setData(array ('fullName' => $fullName)); if (!$input->isValid('fullName')) { throw new Zend_Exception('Invalid fullName provided'); } $this->_fullName = (string) $input->fullName; return $this; } 43
  • 44. Modify  seders  &  geders  2 public function setEmailAddress($emailAddress) { $input = new Zend_Filter_Input($this->_filters, $this->_validators); $input->setData(array ('emailAddress' => $emailAddress)); if (!$input->isValid('emailAddress')) { throw new Zend_Exception('Invalid emailAddress provided'); } $this->_emailAddress = (string) $input->emailAddress; return $this; } public function setWebsite($website) { $input = new Zend_Filter_Input($this->_filters, $this->_validators); $input->setData(array ('website' => $website)); if (!$input->isValid('website')) { throw new Zend_Exception('Invalid website provided'); } $this->_website = (string) $input->website; return $this; } 44
  • 45. Modify  geders  &  seders  3 public function setComment($comment) { $input = new Zend_Filter_Input($this->_filters, $this->_validators); $input->setData(array ('comment' => $comment)); if (!$input->isValid('comment')) { throw new Zend_Exception('Invalid comment provided'); } $this->_comment = (string) $input->comment; return $this; } 45
  • 49. Mess  DetecIon 49 • code  smells • possible  bugs • sub-­‐opImal  code • over  complicated  expressions • unused  parameters,  methods  and  properIes • wrongly  named  parameters,  methods  or   properIes
  • 53. Key  reason 53 “computers are great at doing repetitive tasks very well”
  • 54. AutomaIon 54 • Limit  risk  of  human  error • Will  always  be  executed  in  same  order • Can  be  shared  amongst  team  members • Allows  to  fine-­‐tune  and  improve  features
  • 59. Overview  of  tools 59 • SCM  (SVN,  GIT,  …) • PHP  Lint • PHP  Document  Generator • Debugging • PHPUnit  TesIng • PHP  Mess  detecIon • Phing  automaIon }
  • 60. Quality  Assurance • is  part  of  development  process • will  only  work  if  the  tools  are  available • and  developers  see  the  benefits  of  QA 60
  • 62. Contact 62 Michelangelo van Dam Zend Certified Engineer email: michelangelo@in2it.be skype: michelangelovandam twitter: @DragonBe tel EU: +32 15 34 52 90 tel US: 202 559-7401 www.in2it.be facebook.com/in2itvof | @in2itvof Contact us for Consultancy - Training - QA - Webdesign
  • 63. Credits I’d like to thank the following people for sharing their creative commons pictures michelangelo: http://www.flickr.com/photos/dasprid/5148937451 birds: http://www.flickr.com/photos/andyofne/4633356197 safeguarding: http://www.flickr.com/photos/infidelic/4306205887/ bugs: http://www.flickr.com/photos/goingslo/4523034319 behaviour: http://www.flickr.com/photos/yuan2003/1812881370 prevention: http://www.flickr.com/photos/robertelyov/5159801170 progress: http://www.flickr.com/photos/dingatx/4115844000 file cabinet: http://www.flickr.com/photos/manc/1427691715 documentation: http://www.flickr.com/photos/dennis_matheson/3269442687 exam: http://www.flickr.com/photos/albertogp123/5843577306 dead roach: http://www.flickr.com/photos/stevensnodgrass/7504408776 garbage: http://www.flickr.com/photos/amstersam/4608512202 gears: http://www.flickr.com/photos/freefoto/5982549938 elephpant: http://www.flickr.com/photos/drewm/3191872515