SlideShare a Scribd company logo
© All rights reserved. Zend Technologies, Inc.
Testing Your Zend
Framework MVC Application
Matthew Weier O'Phinney
Project Lead
Zend Framework
© All rights reserved. Zend Technologies, Inc.
What we'll cover
●
Unit Testing basics
●
Basic functional testing in ZF
●
Several “Advanced” ZF testing topics
© All rights reserved. Zend Technologies, Inc.
Why test?
© All rights reserved. Zend Technologies, Inc.
Simplify maintenance
●
Testing defines expectations
●
Testing describes behaviors identified by the
application
●
Testing tells us when new changes break
existing code and behaviors
© All rights reserved. Zend Technologies, Inc.
Quantify code quality
●
Code coverage exercised by unit tests
●
Test methods document behaviors code should
define
6 © All rights reserved. Zend Technologies, Inc.
Psychological benefits
Warm fuzzy feeling
from seeing green
7 © All rights reserved. Zend Technologies, Inc.
Testing is not… reloading
8 © All rights reserved. Zend Technologies, Inc.
Testing is not… var_dump()
9 © All rights reserved. Zend Technologies, Inc.
Testing is… reproducible
10 © All rights reserved. Zend Technologies, Inc.
Testing is… automatable
© All rights reserved. Zend Technologies, Inc.
Good testing includes…
●
Defined behaviors
●
Code examples of use cases
●
Expectations
© All rights reserved. Zend Technologies, Inc.
PHP testing frameworks
●
PHPT
▶ Used by PHP, and some PEAR and independent
libraries
● SimpleTest
▶ JUnit-style testing framework
●
PHPUnit
▶ JUnit-style testing framework
▶ De facto industry standard
13 © All rights reserved. Zend Technologies, Inc.
Testing Basics
© All rights reserved. Zend Technologies, Inc.
Writing unit tests
●
Create a test class
●
Create one or more methods describing
behaviors
▶ State the behaviors in natural language
● Write code that creates the behavior(s)
▶ Write code exercising the API
●
Write assertions indicating expectations
© All rights reserved. Zend Technologies, Inc.
Create a test class
●
Usually, named after the Unit Under Test
class EntryTest
extends PHPUnit_Framework_TestCase
{
}
class EntryTest
extends PHPUnit_Framework_TestCase
{
}
© All rights reserved. Zend Technologies, Inc.
Write a method describing a behavior
●
Prefix with “test”
class EntryTest
extends PHPUnit_Framework_TestCase
{
public function testMaySetTimestampWithString()
{
}
}
class EntryTest
extends PHPUnit_Framework_TestCase
{
public function testMaySetTimestampWithString()
{
}
}
© All rights reserved. Zend Technologies, Inc.
Write code creating the behavior
class EntryTest
extends PHPUnit_Framework_TestCase
{
public function testMaySetTimestampWithString()
{
$string = 'Fri, 7 May 2010 09:26:03 -0700';
$ts = strtotime($string);
$this->entry->setTimestamp($string);
$setValue = $this->entry->getTimestamp();
}
}
class EntryTest
extends PHPUnit_Framework_TestCase
{
public function testMaySetTimestampWithString()
{
$string = 'Fri, 7 May 2010 09:26:03 -0700';
$ts = strtotime($string);
$this->entry->setTimestamp($string);
$setValue = $this->entry->getTimestamp();
}
}
© All rights reserved. Zend Technologies, Inc.
Write assertions of expectations
class EntryTest
extends PHPUnit_Framework_TestCase
{
public function testMaySetTimestampWithString()
{
$string = 'Fri, 7 May 2010 09:26:03 -0700';
$ts = strtotime($string);
$this->entry->setTimestamp($string);
$setValue = $this->entry->getTimestamp();
$this->assertSame($ts, $setValue);
}
}
class EntryTest
extends PHPUnit_Framework_TestCase
{
public function testMaySetTimestampWithString()
{
$string = 'Fri, 7 May 2010 09:26:03 -0700';
$ts = strtotime($string);
$this->entry->setTimestamp($string);
$setValue = $this->entry->getTimestamp();
$this->assertSame($ts, $setValue);
}
}
© All rights reserved. Zend Technologies, Inc.
Run the tests
●
Failure?
▶ Check your tests and assertions for potential
typos or usage errors
▶ Check the Unit Under Test for errors
▶ Make corrections and re-run the tests
● Success?
▶ Move on to the next behavior or feature!
20 © All rights reserved. Zend Technologies, Inc.
Some testing terminology
© All rights reserved. Zend Technologies, Inc.
Test scaffolding
●
Make sure your environment is free of
assumptions
●
Initialize any dependencies necessary prior to
testing
●
Usually done in the “setUp()” method
© All rights reserved. Zend Technologies, Inc.
Test doubles
●
Stubs
Replacing an object with another so that the
system under test can continue down a path.
●
Mock Objects
Replacing an object with another and defining
expectations for it.
© All rights reserved. Zend Technologies, Inc.
Additional testing types
●
Conditional testing
Testing only when certain environmental
conditions are met.
●
Functional and Integration tests
Testing that the systems as a whole behaves as
expected; testing that the units interact as
exected.
24 © All rights reserved. Zend Technologies, Inc.
Quasi-Functional testing
in Zend Framework
© All rights reserved. Zend Technologies, Inc.
Overview
●
Setup the phpunit environment
●
Create a TestCase based on ControllerTestCase
●
Bootstrap the application
●
Create and dispatch a request
● Perform assertions on the response
© All rights reserved. Zend Technologies, Inc.
The PHPUnit environment
●
Directory structure
tests
|-- application
| `-- controllers
|-- Bootstrap.php
|-- library
| `-- Custom
`-- phpunit.xml
4 directories, 2 files
tests
|-- application
| `-- controllers
|-- Bootstrap.php
|-- library
| `-- Custom
`-- phpunit.xml
4 directories, 2 files
© All rights reserved. Zend Technologies, Inc.
The PHPUnit environment
●
phpunit.xml
<phpunit bootstrap="./Bootstrap.php">
<testsuite name="Test Suite">
<directory>./</directory>
</testsuite>
<filter>
<whitelist>
<directory
suffix=".php">../library/</directory>
<directory
suffix=".php">../application/</directory>
<exclude>
<directory
suffix=".phtml">../application/</directory>
</exclude>
</whitelist>
</filter>
</phpunit>
<phpunit bootstrap="./Bootstrap.php">
<testsuite name="Test Suite">
<directory>./</directory>
</testsuite>
<filter>
<whitelist>
<directory
suffix=".php">../library/</directory>
<directory
suffix=".php">../application/</directory>
<exclude>
<directory
suffix=".phtml">../application/</directory>
</exclude>
</whitelist>
</filter>
</phpunit>
© All rights reserved. Zend Technologies, Inc.
The PHPUnit environment
●
Bootstrap.php
$rootPath = realpath(dirname(__DIR__));
if (!defined('APPLICATION_PATH')) {
define('APPLICATION_PATH',
$rootPath . '/application');
}
if (!defined('APPLICATION_ENV')) {
define('APPLICATION_ENV', 'testing');
}
set_include_path(implode(PATH_SEPARATOR, array(
'.',
$rootPath . '/library',
get_include_path(),
)));
require_once 'Zend/Loader/Autoloader.php';
$loader = Zend_Loader_Autoloader::getInstance();
$loader->registerNamespace('Custom_');
$rootPath = realpath(dirname(__DIR__));
if (!defined('APPLICATION_PATH')) {
define('APPLICATION_PATH',
$rootPath . '/application');
}
if (!defined('APPLICATION_ENV')) {
define('APPLICATION_ENV', 'testing');
}
set_include_path(implode(PATH_SEPARATOR, array(
'.',
$rootPath . '/library',
get_include_path(),
)));
require_once 'Zend/Loader/Autoloader.php';
$loader = Zend_Loader_Autoloader::getInstance();
$loader->registerNamespace('Custom_');
© All rights reserved. Zend Technologies, Inc.
Create a test case class
●
Extend Zend_Test_PHPUnit_ControllerTestCase
class ExampleControllerTest
extends Zend_Test_PHPUnit_ControllerTestCase
{
}
class ExampleControllerTest
extends Zend_Test_PHPUnit_ControllerTestCase
{
}
© All rights reserved. Zend Technologies, Inc.
Bootstrap the application
●
Create a Zend_Application instance, and
reference it in your setUp()
class ExampleControllerTest
extends Zend_Test_PHPUnit_ControllerTestCase
{
public function setUp()
{
$this->bootstrap = new Zend_Application(
APPLICATION_ENV,
APPLICATION_PATH
. '/configs/application.ini'
);
parent::setUp();
}
}
class ExampleControllerTest
extends Zend_Test_PHPUnit_ControllerTestCase
{
public function setUp()
{
$this->bootstrap = new Zend_Application(
APPLICATION_ENV,
APPLICATION_PATH
. '/configs/application.ini'
);
parent::setUp();
}
}
© All rights reserved. Zend Technologies, Inc.
Create and dispatch a request
●
Simple method: dispatch a “url”
class ExampleControllerTest
extends Zend_Test_PHPUnit_ControllerTestCase
{
// ...
public function testStaticPageHasGoodStructure()
{
$this->dispatch('/example/page');
// ...
}
}
class ExampleControllerTest
extends Zend_Test_PHPUnit_ControllerTestCase
{
// ...
public function testStaticPageHasGoodStructure()
{
$this->dispatch('/example/page');
// ...
}
}
© All rights reserved. Zend Technologies, Inc.
Create and dispatch a request
●
More advanced: customize the request object
prior to dispatching
class ExampleControllerTest
extends Zend_Test_PHPUnit_ControllerTestCase
{
// ...
public function testXhrRequestReturnsJson()
{
$this->getRequest()
->setHeader('X-Requested-With',
'XMLHttpRequest')
->setQuery('format', 'json');
$this->dispatch('/example/xhr-endpoint');
// ...
}
}
class ExampleControllerTest
extends Zend_Test_PHPUnit_ControllerTestCase
{
// ...
public function testXhrRequestReturnsJson()
{
$this->getRequest()
->setHeader('X-Requested-With',
'XMLHttpRequest')
->setQuery('format', 'json');
$this->dispatch('/example/xhr-endpoint');
// ...
}
}
© All rights reserved. Zend Technologies, Inc.
Create assertions
●
Typical assertions are for:
▶ Structure of response markup
Using either CSS selectors or
XPath assertions.
▶ HTTP response headers and status code
▶ Request and/or Response object artifacts
© All rights reserved. Zend Technologies, Inc.
CSS Selector assertions
● assertQuery($path, $message = '')
●
assertQueryContentContains(
$path, $match, $message = '')
●
assertQueryContentRegex(
$path, $pattern, $message = '')
●
assertQueryCount($path, $count, $message = '')
● assertQueryCountMin($path, $count, $message = '')
●
assertQueryCountMax($path, $count, $message = '')
●
each has a "Not" variant
© All rights reserved. Zend Technologies, Inc.
XPath Selector assertions
● assertXpath($path, $message = '')
●
assertXpathContentContains(
$path, $match, $message = '')
●
assertXpathContentRegex(
$path, $pattern, $message = '')
●
assertXpathCount($path, $count, $message = '')
● assertXpathCountMin($path, $count, $message = '')
●
assertXpathCountMax($path, $count, $message = '')
●
each has a "Not" variant
© All rights reserved. Zend Technologies, Inc.
Redirect assertions
● assertRedirect($message = '')
●
assertRedirectTo($url, $message = '')
●
assertRedirectRegex($pattern, $message = '')
●
each has a "Not" variant
© All rights reserved. Zend Technologies, Inc.
Response assertions
● assertResponseCode($code, $message = '')
●
assertHeader($header, $message = '')
●
assertHeaderContains($header, $match, $message = '')
●
assertHeaderRegex($header, $pattern, $message = '')
● each has a "Not" variant
© All rights reserved. Zend Technologies, Inc.
Request assertions
● assertModule($module, $message = '')
●
assertController($controller, $message = '')
●
assertAction($action, $message = '')
●
assertRoute($route, $message = '')
● each has a "Not" variant
© All rights reserved. Zend Technologies, Inc.
Assertion examples
public function testSomeStaticPageHasGoodStructure()
{
$this->dispatch('/example/page');
$this->assertResponseCode(200);
$this->assertQuery('div#content p');
$this->assertQueryCount('div#sidebar ul li', 3);
}
public function testSomeStaticPageHasGoodStructure()
{
$this->dispatch('/example/page');
$this->assertResponseCode(200);
$this->assertQuery('div#content p');
$this->assertQueryCount('div#sidebar ul li', 3);
}
© All rights reserved. Zend Technologies, Inc.
Assertion examples
public function testXhrRequestReturnsJson()
{
// ...
$this->assertNotRedirect();
$this->assertHeaderContains(
'Content-Type', 'application/json');
}
public function testXhrRequestReturnsJson()
{
// ...
$this->assertNotRedirect();
$this->assertHeaderContains(
'Content-Type', 'application/json');
}
41 © All rights reserved. Zend Technologies, Inc.
Advanced Topics
or: real world use cases
© All rights reserved. Zend Technologies, Inc.
Testing models and resources
●
The Problem:
These classes cannot be autoloaded with the
standard autoloader.
●
The Solution:
Use Zend_Application to bootstrap the
“modules” resource during setUp()
© All rights reserved. Zend Technologies, Inc.
Testing models and resources
class Blog_Model_EntryTest
extends PHPUnit_Framework_TestCase
{
public function setUp()
{
$this->bootstrap = new Zend_Application(
APPLICATION_ENV,
APPLICATION_PATH
. '/configs/application.ini'
);
$this->bootstrap->bootstrap('modules');
$this->model = new Blog_Model_Entry();
}
}
class Blog_Model_EntryTest
extends PHPUnit_Framework_TestCase
{
public function setUp()
{
$this->bootstrap = new Zend_Application(
APPLICATION_ENV,
APPLICATION_PATH
. '/configs/application.ini'
);
$this->bootstrap->bootstrap('modules');
$this->model = new Blog_Model_Entry();
}
}
© All rights reserved. Zend Technologies, Inc.
Testing actions requiring authentication
●
The Problem:
Some actions may require an authenticated
user; how can you emulate this?
●
The Solution:
Manually authenticate against Zend_Auth
prior to calling dispatch().
© All rights reserved. Zend Technologies, Inc.
Authenticating a test user
class ExampleControllerTest
extends Zend_Test_PHPUnit_ControllerTestCase
{
// ...
public function loginUser($user)
{
$params = array('user' => $user);
$adapter = new Custom_Auth_TestAdapter(
$params);
$auth = Zend_Auth::getInstance();
$auth->authenticate($adapter);
$this->assertTrue($auth->hasIdentity());
}
}
class ExampleControllerTest
extends Zend_Test_PHPUnit_ControllerTestCase
{
// ...
public function loginUser($user)
{
$params = array('user' => $user);
$adapter = new Custom_Auth_TestAdapter(
$params);
$auth = Zend_Auth::getInstance();
$auth->authenticate($adapter);
$this->assertTrue($auth->hasIdentity());
}
}
© All rights reserved. Zend Technologies, Inc.
Authenticating and dispatching
class ExampleControllerTest
extends Zend_Test_PHPUnit_ControllerTestCase
{
// ...
public function testAdminUserCanAccessAdmin()
{
$this->loginUser('admin');
$this->dispatch('/example/admin');
$this->assertQuery('div#content.admin');
}
class ExampleControllerTest
extends Zend_Test_PHPUnit_ControllerTestCase
{
// ...
public function testAdminUserCanAccessAdmin()
{
$this->loginUser('admin');
$this->dispatch('/example/admin');
$this->assertQuery('div#content.admin');
}
© All rights reserved. Zend Technologies, Inc.
Testing pages dependent on prior actions
●
The Problem:
Some actions are dependent on others; e.g.,
retrieving a page with content highlighted
based on a search string.
● The Solution:
Dispatch twice, resetting the request and
response between calls.
© All rights reserved. Zend Technologies, Inc.
Testing pages dependent on prior actions
class ExampleControllerTest
extends Zend_Test_PHPUnit_ControllerTestCase
{
// ...
public function testHighlightedTextAfterSearch()
{
$this->getRequest()->setQuery(
'search', 'foobar');
$this->dispatch('/search');
$this->resetRequest();
$this->resetResponse();
$this->dispatch('/example/page');
$this->assertQueryContains(
'span.highlight', 'foobar');
}
class ExampleControllerTest
extends Zend_Test_PHPUnit_ControllerTestCase
{
// ...
public function testHighlightedTextAfterSearch()
{
$this->getRequest()->setQuery(
'search', 'foobar');
$this->dispatch('/search');
$this->resetRequest();
$this->resetResponse();
$this->dispatch('/example/page');
$this->assertQueryContains(
'span.highlight', 'foobar');
}
49 © All rights reserved. Zend Technologies, Inc.
Conclusions
© All rights reserved. Zend Technologies, Inc.
Test Always!
●
Unit test your models, service layers, etc.
●
Do functional/acceptance testing to test
workflows, page structure, etc.
© All rights reserved. Zend Technologies, Inc.
Zend Framework Training & Certification
●
Zend Framework: Fundamentals
This course combines teaching ZF with the
introduction of the Model-View-Controller
(MVC) design pattern, to ensure you learn
current best practices in PHP development.
Next Class: August 16, 17, 18, 19 20, 23, 24, 25
& 26 from 9am-11am Pacific
© All rights reserved. Zend Technologies, Inc.
Zend Framework Training & Certification
●
Zend Framework: Advanced
The Zend Framework: Advanced course is
designed to teach PHP developers already
working with Zend Framework how to apply
best practices when building and configuring
applications for scalability, interactivity, and
high performance.
Next Class: Sept. 7, 8, 9, 10, 13, 14, 15, 16 &
17 from 8:30am-10:30am Pacific
© All rights reserved. Zend Technologies, Inc.
Zend Framework Training & Certification
●
Test Prep: Zend Framework Certification
The Test Prep: Zend Framework Certification
course prepares experienced developers who
design and build PHP applications using ZF for
the challenge of passing the certification exam
and achieving the status of Zend Certified
Engineer in Zend Framework(ZCE-ZF).
●
Free Study Guide
http://www.zend.com/en/download/173
© All rights reserved. Zend Technologies, Inc.
ZendCon 2010!
●
1—4 November 2010
●
http://www.zendcon.com/

More Related Content

What's hot

PHPUnit
PHPUnitPHPUnit
PhpUnit Best Practices
PhpUnit Best PracticesPhpUnit Best Practices
PhpUnit Best Practices
Edorian
 
PHPUnit best practices presentation
PHPUnit best practices presentationPHPUnit best practices presentation
PHPUnit best practices presentation
Thanh Robi
 
Test in action week 4
Test in action   week 4Test in action   week 4
Test in action week 4
Yi-Huan Chan
 
Advanced PHPUnit Testing
Advanced PHPUnit TestingAdvanced PHPUnit Testing
Advanced PHPUnit Testing
Mike Lively
 
New Features PHPUnit 3.3 - Sebastian Bergmann
New Features PHPUnit 3.3 - Sebastian BergmannNew Features PHPUnit 3.3 - Sebastian Bergmann
New Features PHPUnit 3.3 - Sebastian Bergmann
dpc
 
Test in action week 3
Test in action   week 3Test in action   week 3
Test in action week 3
Yi-Huan Chan
 
Test driven node.js
Test driven node.jsTest driven node.js
Test driven node.js
Jay Harris
 
Unit Testing using PHPUnit
Unit Testing using  PHPUnitUnit Testing using  PHPUnit
Unit Testing using PHPUnit
varuntaliyan
 
Test your code like a pro - PHPUnit in practice
Test your code like a pro - PHPUnit in practiceTest your code like a pro - PHPUnit in practice
Test your code like a pro - PHPUnit in practice
Sebastian Marek
 
Test driven development_for_php
Test driven development_for_phpTest driven development_for_php
Test driven development_for_php
Lean Teams Consultancy
 
Testing Code and Assuring Quality
Testing Code and Assuring QualityTesting Code and Assuring Quality
Testing Code and Assuring Quality
Kent Cowgill
 
Unit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDDUnit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDD
Paweł Michalik
 
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
kwatch
 
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur PurnamaEPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
Enterprise PHP Center
 
PHPUnit testing to Zend_Test
PHPUnit testing to Zend_TestPHPUnit testing to Zend_Test
PHPUnit testing to Zend_Test
Michelangelo van Dam
 
Python testing using mock and pytest
Python testing using mock and pytestPython testing using mock and pytest
Python testing using mock and pytest
Suraj Deshmukh
 
Unit Testng with PHP Unit - A Step by Step Training
Unit Testng with PHP Unit - A Step by Step TrainingUnit Testng with PHP Unit - A Step by Step Training
Unit Testng with PHP Unit - A Step by Step Training
Ram Awadh Prasad, PMP
 
Test in action – week 1
Test in action – week 1Test in action – week 1
Test in action – week 1
Yi-Huan Chan
 
Testing the frontend
Testing the frontendTesting the frontend
Testing the frontend
Heiko Hardt
 

What's hot (20)

PHPUnit
PHPUnitPHPUnit
PHPUnit
 
PhpUnit Best Practices
PhpUnit Best PracticesPhpUnit Best Practices
PhpUnit Best Practices
 
PHPUnit best practices presentation
PHPUnit best practices presentationPHPUnit best practices presentation
PHPUnit best practices presentation
 
Test in action week 4
Test in action   week 4Test in action   week 4
Test in action week 4
 
Advanced PHPUnit Testing
Advanced PHPUnit TestingAdvanced PHPUnit Testing
Advanced PHPUnit Testing
 
New Features PHPUnit 3.3 - Sebastian Bergmann
New Features PHPUnit 3.3 - Sebastian BergmannNew Features PHPUnit 3.3 - Sebastian Bergmann
New Features PHPUnit 3.3 - Sebastian Bergmann
 
Test in action week 3
Test in action   week 3Test in action   week 3
Test in action week 3
 
Test driven node.js
Test driven node.jsTest driven node.js
Test driven node.js
 
Unit Testing using PHPUnit
Unit Testing using  PHPUnitUnit Testing using  PHPUnit
Unit Testing using PHPUnit
 
Test your code like a pro - PHPUnit in practice
Test your code like a pro - PHPUnit in practiceTest your code like a pro - PHPUnit in practice
Test your code like a pro - PHPUnit in practice
 
Test driven development_for_php
Test driven development_for_phpTest driven development_for_php
Test driven development_for_php
 
Testing Code and Assuring Quality
Testing Code and Assuring QualityTesting Code and Assuring Quality
Testing Code and Assuring Quality
 
Unit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDDUnit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDD
 
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
 
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur PurnamaEPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
 
PHPUnit testing to Zend_Test
PHPUnit testing to Zend_TestPHPUnit testing to Zend_Test
PHPUnit testing to Zend_Test
 
Python testing using mock and pytest
Python testing using mock and pytestPython testing using mock and pytest
Python testing using mock and pytest
 
Unit Testng with PHP Unit - A Step by Step Training
Unit Testng with PHP Unit - A Step by Step TrainingUnit Testng with PHP Unit - A Step by Step Training
Unit Testng with PHP Unit - A Step by Step Training
 
Test in action – week 1
Test in action – week 1Test in action – week 1
Test in action – week 1
 
Testing the frontend
Testing the frontendTesting the frontend
Testing the frontend
 

Viewers also liked

Brevarex
Brevarex Brevarex
Brevarex
Brevarex_Ukraine
 
Brevarex Ukraine
Brevarex UkraineBrevarex Ukraine
Brevarex Ukraine
Brevarex_Ukraine
 
Brevarex
BrevarexBrevarex
Demo for moodle
Demo for moodleDemo for moodle
Demo for moodle
jbuttery
 
YooMee - геосоциальная сеть с играми в дополненной реальности
YooMee - геосоциальная сеть с играми в дополненной реальностиYooMee - геосоциальная сеть с играми в дополненной реальности
YooMee - геосоциальная сеть с играми в дополненной реальности
Марина Иванова
 
Seo slideshow
Seo slideshowSeo slideshow
Seo slideshow
adamyax
 
Ergonomi
ErgonomiErgonomi
Ergonomi
zoezoepratama
 
Brevarex for medi
Brevarex for mediBrevarex for medi
Brevarex for medi
Brevarex_Ukraine
 
Demo for moodle
Demo for moodleDemo for moodle
Demo for moodlejbuttery
 
Fire safety pp
Fire safety ppFire safety pp
Fire safety pp
jbuttery
 
Les chaînes de valeur de la Télévision Mobile Personnelle
Les chaînes de valeur de la Télévision Mobile Personnelle Les chaînes de valeur de la Télévision Mobile Personnelle
Les chaînes de valeur de la Télévision Mobile Personnelle
mchevalier
 
Japans tsunami
Japans tsunamiJapans tsunami
Japans tsunami
mkk1313
 
Case Study Notes
Case Study NotesCase Study Notes
Case Study Notes
mkk1313
 
Editing Process
Editing ProcessEditing Process
Editing Process
mkk1313
 
The marketing of meatloaf
The marketing of meatloafThe marketing of meatloaf
The marketing of meatloaf
mkk1313
 
Question 6
Question 6Question 6
Question 6
mkk1313
 
Info College Lp
Info College LpInfo College Lp
Info College Lp
leloux
 
Questionnaire results
Questionnaire resultsQuestionnaire results
Questionnaire results
mkk1313
 
Paris Web
Paris WebParis Web
Paris Web
cyrildoussin
 

Viewers also liked (20)

Brevarex
Brevarex Brevarex
Brevarex
 
Brevarex Ukraine
Brevarex UkraineBrevarex Ukraine
Brevarex Ukraine
 
Brevarex
BrevarexBrevarex
Brevarex
 
Demo for moodle
Demo for moodleDemo for moodle
Demo for moodle
 
YooMee - геосоциальная сеть с играми в дополненной реальности
YooMee - геосоциальная сеть с играми в дополненной реальностиYooMee - геосоциальная сеть с играми в дополненной реальности
YooMee - геосоциальная сеть с играми в дополненной реальности
 
Seo slideshow
Seo slideshowSeo slideshow
Seo slideshow
 
Ergonomi
ErgonomiErgonomi
Ergonomi
 
Brevarex for medi
Brevarex for mediBrevarex for medi
Brevarex for medi
 
Demo for moodle
Demo for moodleDemo for moodle
Demo for moodle
 
Fire safety pp
Fire safety ppFire safety pp
Fire safety pp
 
Les chaînes de valeur de la Télévision Mobile Personnelle
Les chaînes de valeur de la Télévision Mobile Personnelle Les chaînes de valeur de la Télévision Mobile Personnelle
Les chaînes de valeur de la Télévision Mobile Personnelle
 
Japans tsunami
Japans tsunamiJapans tsunami
Japans tsunami
 
Case Study Notes
Case Study NotesCase Study Notes
Case Study Notes
 
Editing Process
Editing ProcessEditing Process
Editing Process
 
The marketing of meatloaf
The marketing of meatloafThe marketing of meatloaf
The marketing of meatloaf
 
Question 6
Question 6Question 6
Question 6
 
Info College Lp
Info College LpInfo College Lp
Info College Lp
 
Questionnaire results
Questionnaire resultsQuestionnaire results
Questionnaire results
 
Lemur
LemurLemur
Lemur
 
Paris Web
Paris WebParis Web
Paris Web
 

Similar to 2010 07-28-testing-zf-apps

Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
Michelangelo van Dam
 
Automated Unit Testing
Automated Unit TestingAutomated Unit Testing
Automated Unit Testing
Mike Lively
 
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
 
Leveling Up With Unit Testing - php[tek] 2023
Leveling Up With Unit Testing - php[tek] 2023Leveling Up With Unit Testing - php[tek] 2023
Leveling Up With Unit Testing - php[tek] 2023
Mark Niebergall
 
Leveling Up With Unit Testing - LonghornPHP 2022
Leveling Up With Unit Testing - LonghornPHP 2022Leveling Up With Unit Testing - LonghornPHP 2022
Leveling Up With Unit Testing - LonghornPHP 2022
Mark Niebergall
 
Testing with VS2010 - A Bugs Life
Testing with VS2010 - A Bugs LifeTesting with VS2010 - A Bugs Life
Testing with VS2010 - A Bugs Life
Peter Gfader
 
Php tests tips
Php tests tipsPhp tests tips
Php tests tips
Damian Sromek
 
Php unit (eng)
Php unit (eng)Php unit (eng)
Php unit (eng)
Anatoliy Okhotnikov
 
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
Michelangelo van Dam
 
Zend Framework 2 Patterns
Zend Framework 2 PatternsZend Framework 2 Patterns
Zend Framework 2 Patterns
Zend by Rogue Wave Software
 
Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013
Michelangelo van Dam
 
Mastering Test Automation: How To Use Selenium Successfully
Mastering Test Automation: How To Use Selenium SuccessfullyMastering Test Automation: How To Use Selenium Successfully
Mastering Test Automation: How To Use Selenium Successfully
SpringPeople
 
Unit testing php-unit - phing - selenium_v2
Unit testing   php-unit - phing - selenium_v2Unit testing   php-unit - phing - selenium_v2
Unit testing php-unit - phing - selenium_v2
Tricode (part of Dept)
 
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
Michelangelo van Dam
 
PHP Unit Testing in Yii
PHP Unit Testing in YiiPHP Unit Testing in Yii
PHP Unit Testing in Yii
IlPeach
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
Michelangelo van Dam
 
Test Driven Development with Sql Server
Test Driven Development with Sql ServerTest Driven Development with Sql Server
Test Driven Development with Sql Server
David P. Moore
 
Unit testing
Unit testingUnit testing
Unit testing
Prabhat Kumar
 
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
Michelangelo van Dam
 
Strategy-driven Test Generation with Open Source Frameworks
Strategy-driven Test Generation with Open Source FrameworksStrategy-driven Test Generation with Open Source Frameworks
Strategy-driven Test Generation with Open Source Frameworks
Dimitry Polivaev
 

Similar to 2010 07-28-testing-zf-apps (20)

Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
 
Automated Unit Testing
Automated Unit TestingAutomated Unit Testing
Automated Unit Testing
 
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
 
Leveling Up With Unit Testing - php[tek] 2023
Leveling Up With Unit Testing - php[tek] 2023Leveling Up With Unit Testing - php[tek] 2023
Leveling Up With Unit Testing - php[tek] 2023
 
Leveling Up With Unit Testing - LonghornPHP 2022
Leveling Up With Unit Testing - LonghornPHP 2022Leveling Up With Unit Testing - LonghornPHP 2022
Leveling Up With Unit Testing - LonghornPHP 2022
 
Testing with VS2010 - A Bugs Life
Testing with VS2010 - A Bugs LifeTesting with VS2010 - A Bugs Life
Testing with VS2010 - A Bugs Life
 
Php tests tips
Php tests tipsPhp tests tips
Php tests tips
 
Php unit (eng)
Php unit (eng)Php unit (eng)
Php unit (eng)
 
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 2 Patterns
Zend Framework 2 PatternsZend Framework 2 Patterns
Zend Framework 2 Patterns
 
Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013
 
Mastering Test Automation: How To Use Selenium Successfully
Mastering Test Automation: How To Use Selenium SuccessfullyMastering Test Automation: How To Use Selenium Successfully
Mastering Test Automation: How To Use Selenium Successfully
 
Unit testing php-unit - phing - selenium_v2
Unit testing   php-unit - phing - selenium_v2Unit testing   php-unit - phing - selenium_v2
Unit testing php-unit - phing - selenium_v2
 
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
 
PHP Unit Testing in Yii
PHP Unit Testing in YiiPHP Unit Testing in Yii
PHP Unit Testing in Yii
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
Test Driven Development with Sql Server
Test Driven Development with Sql ServerTest Driven Development with Sql Server
Test Driven Development with Sql Server
 
Unit testing
Unit testingUnit testing
Unit testing
 
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
 
Strategy-driven Test Generation with Open Source Frameworks
Strategy-driven Test Generation with Open Source FrameworksStrategy-driven Test Generation with Open Source Frameworks
Strategy-driven Test Generation with Open Source Frameworks
 

Recently uploaded

World environment day ppt For 5 June 2024
World environment day ppt For 5 June 2024World environment day ppt For 5 June 2024
World environment day ppt For 5 June 2024
ak6969907
 
PIMS Job Advertisement 2024.pdf Islamabad
PIMS Job Advertisement 2024.pdf IslamabadPIMS Job Advertisement 2024.pdf Islamabad
PIMS Job Advertisement 2024.pdf Islamabad
AyyanKhan40
 
BÀI TẬP BỔ TRỢ TIẾNG ANH 8 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2023-2024 (CÓ FI...
BÀI TẬP BỔ TRỢ TIẾNG ANH 8 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2023-2024 (CÓ FI...BÀI TẬP BỔ TRỢ TIẾNG ANH 8 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2023-2024 (CÓ FI...
BÀI TẬP BỔ TRỢ TIẾNG ANH 8 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2023-2024 (CÓ FI...
Nguyen Thanh Tu Collection
 
Executive Directors Chat Leveraging AI for Diversity, Equity, and Inclusion
Executive Directors Chat  Leveraging AI for Diversity, Equity, and InclusionExecutive Directors Chat  Leveraging AI for Diversity, Equity, and Inclusion
Executive Directors Chat Leveraging AI for Diversity, Equity, and Inclusion
TechSoup
 
writing about opinions about Australia the movie
writing about opinions about Australia the moviewriting about opinions about Australia the movie
writing about opinions about Australia the movie
Nicholas Montgomery
 
Main Java[All of the Base Concepts}.docx
Main Java[All of the Base Concepts}.docxMain Java[All of the Base Concepts}.docx
Main Java[All of the Base Concepts}.docx
adhitya5119
 
The basics of sentences session 5pptx.pptx
The basics of sentences session 5pptx.pptxThe basics of sentences session 5pptx.pptx
The basics of sentences session 5pptx.pptx
heathfieldcps1
 
Exploiting Artificial Intelligence for Empowering Researchers and Faculty, In...
Exploiting Artificial Intelligence for Empowering Researchers and Faculty, In...Exploiting Artificial Intelligence for Empowering Researchers and Faculty, In...
Exploiting Artificial Intelligence for Empowering Researchers and Faculty, In...
Dr. Vinod Kumar Kanvaria
 
The History of Stoke Newington Street Names
The History of Stoke Newington Street NamesThe History of Stoke Newington Street Names
The History of Stoke Newington Street Names
History of Stoke Newington
 
ANATOMY AND BIOMECHANICS OF HIP JOINT.pdf
ANATOMY AND BIOMECHANICS OF HIP JOINT.pdfANATOMY AND BIOMECHANICS OF HIP JOINT.pdf
ANATOMY AND BIOMECHANICS OF HIP JOINT.pdf
Priyankaranawat4
 
Introduction to AI for Nonprofits with Tapp Network
Introduction to AI for Nonprofits with Tapp NetworkIntroduction to AI for Nonprofits with Tapp Network
Introduction to AI for Nonprofits with Tapp Network
TechSoup
 
MARY JANE WILSON, A “BOA MÃE” .
MARY JANE WILSON, A “BOA MÃE”           .MARY JANE WILSON, A “BOA MÃE”           .
MARY JANE WILSON, A “BOA MÃE” .
Colégio Santa Teresinha
 
Your Skill Boost Masterclass: Strategies for Effective Upskilling
Your Skill Boost Masterclass: Strategies for Effective UpskillingYour Skill Boost Masterclass: Strategies for Effective Upskilling
Your Skill Boost Masterclass: Strategies for Effective Upskilling
Excellence Foundation for South Sudan
 
DRUGS AND ITS classification slide share
DRUGS AND ITS classification slide shareDRUGS AND ITS classification slide share
DRUGS AND ITS classification slide share
taiba qazi
 
Life upper-Intermediate B2 Workbook for student
Life upper-Intermediate B2 Workbook for studentLife upper-Intermediate B2 Workbook for student
Life upper-Intermediate B2 Workbook for student
NgcHiNguyn25
 
clinical examination of hip joint (1).pdf
clinical examination of hip joint (1).pdfclinical examination of hip joint (1).pdf
clinical examination of hip joint (1).pdf
Priyankaranawat4
 
How to Build a Module in Odoo 17 Using the Scaffold Method
How to Build a Module in Odoo 17 Using the Scaffold MethodHow to Build a Module in Odoo 17 Using the Scaffold Method
How to Build a Module in Odoo 17 Using the Scaffold Method
Celine George
 
Lapbook sobre os Regimes Totalitários.pdf
Lapbook sobre os Regimes Totalitários.pdfLapbook sobre os Regimes Totalitários.pdf
Lapbook sobre os Regimes Totalitários.pdf
Jean Carlos Nunes Paixão
 
Types of Herbal Cosmetics its standardization.
Types of Herbal Cosmetics its standardization.Types of Herbal Cosmetics its standardization.
Types of Herbal Cosmetics its standardization.
Ashokrao Mane college of Pharmacy Peth-Vadgaon
 
A Strategic Approach: GenAI in Education
A Strategic Approach: GenAI in EducationA Strategic Approach: GenAI in Education
A Strategic Approach: GenAI in Education
Peter Windle
 

Recently uploaded (20)

World environment day ppt For 5 June 2024
World environment day ppt For 5 June 2024World environment day ppt For 5 June 2024
World environment day ppt For 5 June 2024
 
PIMS Job Advertisement 2024.pdf Islamabad
PIMS Job Advertisement 2024.pdf IslamabadPIMS Job Advertisement 2024.pdf Islamabad
PIMS Job Advertisement 2024.pdf Islamabad
 
BÀI TẬP BỔ TRỢ TIẾNG ANH 8 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2023-2024 (CÓ FI...
BÀI TẬP BỔ TRỢ TIẾNG ANH 8 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2023-2024 (CÓ FI...BÀI TẬP BỔ TRỢ TIẾNG ANH 8 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2023-2024 (CÓ FI...
BÀI TẬP BỔ TRỢ TIẾNG ANH 8 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2023-2024 (CÓ FI...
 
Executive Directors Chat Leveraging AI for Diversity, Equity, and Inclusion
Executive Directors Chat  Leveraging AI for Diversity, Equity, and InclusionExecutive Directors Chat  Leveraging AI for Diversity, Equity, and Inclusion
Executive Directors Chat Leveraging AI for Diversity, Equity, and Inclusion
 
writing about opinions about Australia the movie
writing about opinions about Australia the moviewriting about opinions about Australia the movie
writing about opinions about Australia the movie
 
Main Java[All of the Base Concepts}.docx
Main Java[All of the Base Concepts}.docxMain Java[All of the Base Concepts}.docx
Main Java[All of the Base Concepts}.docx
 
The basics of sentences session 5pptx.pptx
The basics of sentences session 5pptx.pptxThe basics of sentences session 5pptx.pptx
The basics of sentences session 5pptx.pptx
 
Exploiting Artificial Intelligence for Empowering Researchers and Faculty, In...
Exploiting Artificial Intelligence for Empowering Researchers and Faculty, In...Exploiting Artificial Intelligence for Empowering Researchers and Faculty, In...
Exploiting Artificial Intelligence for Empowering Researchers and Faculty, In...
 
The History of Stoke Newington Street Names
The History of Stoke Newington Street NamesThe History of Stoke Newington Street Names
The History of Stoke Newington Street Names
 
ANATOMY AND BIOMECHANICS OF HIP JOINT.pdf
ANATOMY AND BIOMECHANICS OF HIP JOINT.pdfANATOMY AND BIOMECHANICS OF HIP JOINT.pdf
ANATOMY AND BIOMECHANICS OF HIP JOINT.pdf
 
Introduction to AI for Nonprofits with Tapp Network
Introduction to AI for Nonprofits with Tapp NetworkIntroduction to AI for Nonprofits with Tapp Network
Introduction to AI for Nonprofits with Tapp Network
 
MARY JANE WILSON, A “BOA MÃE” .
MARY JANE WILSON, A “BOA MÃE”           .MARY JANE WILSON, A “BOA MÃE”           .
MARY JANE WILSON, A “BOA MÃE” .
 
Your Skill Boost Masterclass: Strategies for Effective Upskilling
Your Skill Boost Masterclass: Strategies for Effective UpskillingYour Skill Boost Masterclass: Strategies for Effective Upskilling
Your Skill Boost Masterclass: Strategies for Effective Upskilling
 
DRUGS AND ITS classification slide share
DRUGS AND ITS classification slide shareDRUGS AND ITS classification slide share
DRUGS AND ITS classification slide share
 
Life upper-Intermediate B2 Workbook for student
Life upper-Intermediate B2 Workbook for studentLife upper-Intermediate B2 Workbook for student
Life upper-Intermediate B2 Workbook for student
 
clinical examination of hip joint (1).pdf
clinical examination of hip joint (1).pdfclinical examination of hip joint (1).pdf
clinical examination of hip joint (1).pdf
 
How to Build a Module in Odoo 17 Using the Scaffold Method
How to Build a Module in Odoo 17 Using the Scaffold MethodHow to Build a Module in Odoo 17 Using the Scaffold Method
How to Build a Module in Odoo 17 Using the Scaffold Method
 
Lapbook sobre os Regimes Totalitários.pdf
Lapbook sobre os Regimes Totalitários.pdfLapbook sobre os Regimes Totalitários.pdf
Lapbook sobre os Regimes Totalitários.pdf
 
Types of Herbal Cosmetics its standardization.
Types of Herbal Cosmetics its standardization.Types of Herbal Cosmetics its standardization.
Types of Herbal Cosmetics its standardization.
 
A Strategic Approach: GenAI in Education
A Strategic Approach: GenAI in EducationA Strategic Approach: GenAI in Education
A Strategic Approach: GenAI in Education
 

2010 07-28-testing-zf-apps

  • 1. © All rights reserved. Zend Technologies, Inc. Testing Your Zend Framework MVC Application Matthew Weier O'Phinney Project Lead Zend Framework
  • 2. © All rights reserved. Zend Technologies, Inc. What we'll cover ● Unit Testing basics ● Basic functional testing in ZF ● Several “Advanced” ZF testing topics
  • 3. © All rights reserved. Zend Technologies, Inc. Why test?
  • 4. © All rights reserved. Zend Technologies, Inc. Simplify maintenance ● Testing defines expectations ● Testing describes behaviors identified by the application ● Testing tells us when new changes break existing code and behaviors
  • 5. © All rights reserved. Zend Technologies, Inc. Quantify code quality ● Code coverage exercised by unit tests ● Test methods document behaviors code should define
  • 6. 6 © All rights reserved. Zend Technologies, Inc. Psychological benefits Warm fuzzy feeling from seeing green
  • 7. 7 © All rights reserved. Zend Technologies, Inc. Testing is not… reloading
  • 8. 8 © All rights reserved. Zend Technologies, Inc. Testing is not… var_dump()
  • 9. 9 © All rights reserved. Zend Technologies, Inc. Testing is… reproducible
  • 10. 10 © All rights reserved. Zend Technologies, Inc. Testing is… automatable
  • 11. © All rights reserved. Zend Technologies, Inc. Good testing includes… ● Defined behaviors ● Code examples of use cases ● Expectations
  • 12. © All rights reserved. Zend Technologies, Inc. PHP testing frameworks ● PHPT ▶ Used by PHP, and some PEAR and independent libraries ● SimpleTest ▶ JUnit-style testing framework ● PHPUnit ▶ JUnit-style testing framework ▶ De facto industry standard
  • 13. 13 © All rights reserved. Zend Technologies, Inc. Testing Basics
  • 14. © All rights reserved. Zend Technologies, Inc. Writing unit tests ● Create a test class ● Create one or more methods describing behaviors ▶ State the behaviors in natural language ● Write code that creates the behavior(s) ▶ Write code exercising the API ● Write assertions indicating expectations
  • 15. © All rights reserved. Zend Technologies, Inc. Create a test class ● Usually, named after the Unit Under Test class EntryTest extends PHPUnit_Framework_TestCase { } class EntryTest extends PHPUnit_Framework_TestCase { }
  • 16. © All rights reserved. Zend Technologies, Inc. Write a method describing a behavior ● Prefix with “test” class EntryTest extends PHPUnit_Framework_TestCase { public function testMaySetTimestampWithString() { } } class EntryTest extends PHPUnit_Framework_TestCase { public function testMaySetTimestampWithString() { } }
  • 17. © All rights reserved. Zend Technologies, Inc. Write code creating the behavior class EntryTest extends PHPUnit_Framework_TestCase { public function testMaySetTimestampWithString() { $string = 'Fri, 7 May 2010 09:26:03 -0700'; $ts = strtotime($string); $this->entry->setTimestamp($string); $setValue = $this->entry->getTimestamp(); } } class EntryTest extends PHPUnit_Framework_TestCase { public function testMaySetTimestampWithString() { $string = 'Fri, 7 May 2010 09:26:03 -0700'; $ts = strtotime($string); $this->entry->setTimestamp($string); $setValue = $this->entry->getTimestamp(); } }
  • 18. © All rights reserved. Zend Technologies, Inc. Write assertions of expectations class EntryTest extends PHPUnit_Framework_TestCase { public function testMaySetTimestampWithString() { $string = 'Fri, 7 May 2010 09:26:03 -0700'; $ts = strtotime($string); $this->entry->setTimestamp($string); $setValue = $this->entry->getTimestamp(); $this->assertSame($ts, $setValue); } } class EntryTest extends PHPUnit_Framework_TestCase { public function testMaySetTimestampWithString() { $string = 'Fri, 7 May 2010 09:26:03 -0700'; $ts = strtotime($string); $this->entry->setTimestamp($string); $setValue = $this->entry->getTimestamp(); $this->assertSame($ts, $setValue); } }
  • 19. © All rights reserved. Zend Technologies, Inc. Run the tests ● Failure? ▶ Check your tests and assertions for potential typos or usage errors ▶ Check the Unit Under Test for errors ▶ Make corrections and re-run the tests ● Success? ▶ Move on to the next behavior or feature!
  • 20. 20 © All rights reserved. Zend Technologies, Inc. Some testing terminology
  • 21. © All rights reserved. Zend Technologies, Inc. Test scaffolding ● Make sure your environment is free of assumptions ● Initialize any dependencies necessary prior to testing ● Usually done in the “setUp()” method
  • 22. © All rights reserved. Zend Technologies, Inc. Test doubles ● Stubs Replacing an object with another so that the system under test can continue down a path. ● Mock Objects Replacing an object with another and defining expectations for it.
  • 23. © All rights reserved. Zend Technologies, Inc. Additional testing types ● Conditional testing Testing only when certain environmental conditions are met. ● Functional and Integration tests Testing that the systems as a whole behaves as expected; testing that the units interact as exected.
  • 24. 24 © All rights reserved. Zend Technologies, Inc. Quasi-Functional testing in Zend Framework
  • 25. © All rights reserved. Zend Technologies, Inc. Overview ● Setup the phpunit environment ● Create a TestCase based on ControllerTestCase ● Bootstrap the application ● Create and dispatch a request ● Perform assertions on the response
  • 26. © All rights reserved. Zend Technologies, Inc. The PHPUnit environment ● Directory structure tests |-- application | `-- controllers |-- Bootstrap.php |-- library | `-- Custom `-- phpunit.xml 4 directories, 2 files tests |-- application | `-- controllers |-- Bootstrap.php |-- library | `-- Custom `-- phpunit.xml 4 directories, 2 files
  • 27. © All rights reserved. Zend Technologies, Inc. The PHPUnit environment ● phpunit.xml <phpunit bootstrap="./Bootstrap.php"> <testsuite name="Test Suite"> <directory>./</directory> </testsuite> <filter> <whitelist> <directory suffix=".php">../library/</directory> <directory suffix=".php">../application/</directory> <exclude> <directory suffix=".phtml">../application/</directory> </exclude> </whitelist> </filter> </phpunit> <phpunit bootstrap="./Bootstrap.php"> <testsuite name="Test Suite"> <directory>./</directory> </testsuite> <filter> <whitelist> <directory suffix=".php">../library/</directory> <directory suffix=".php">../application/</directory> <exclude> <directory suffix=".phtml">../application/</directory> </exclude> </whitelist> </filter> </phpunit>
  • 28. © All rights reserved. Zend Technologies, Inc. The PHPUnit environment ● Bootstrap.php $rootPath = realpath(dirname(__DIR__)); if (!defined('APPLICATION_PATH')) { define('APPLICATION_PATH', $rootPath . '/application'); } if (!defined('APPLICATION_ENV')) { define('APPLICATION_ENV', 'testing'); } set_include_path(implode(PATH_SEPARATOR, array( '.', $rootPath . '/library', get_include_path(), ))); require_once 'Zend/Loader/Autoloader.php'; $loader = Zend_Loader_Autoloader::getInstance(); $loader->registerNamespace('Custom_'); $rootPath = realpath(dirname(__DIR__)); if (!defined('APPLICATION_PATH')) { define('APPLICATION_PATH', $rootPath . '/application'); } if (!defined('APPLICATION_ENV')) { define('APPLICATION_ENV', 'testing'); } set_include_path(implode(PATH_SEPARATOR, array( '.', $rootPath . '/library', get_include_path(), ))); require_once 'Zend/Loader/Autoloader.php'; $loader = Zend_Loader_Autoloader::getInstance(); $loader->registerNamespace('Custom_');
  • 29. © All rights reserved. Zend Technologies, Inc. Create a test case class ● Extend Zend_Test_PHPUnit_ControllerTestCase class ExampleControllerTest extends Zend_Test_PHPUnit_ControllerTestCase { } class ExampleControllerTest extends Zend_Test_PHPUnit_ControllerTestCase { }
  • 30. © All rights reserved. Zend Technologies, Inc. Bootstrap the application ● Create a Zend_Application instance, and reference it in your setUp() class ExampleControllerTest extends Zend_Test_PHPUnit_ControllerTestCase { public function setUp() { $this->bootstrap = new Zend_Application( APPLICATION_ENV, APPLICATION_PATH . '/configs/application.ini' ); parent::setUp(); } } class ExampleControllerTest extends Zend_Test_PHPUnit_ControllerTestCase { public function setUp() { $this->bootstrap = new Zend_Application( APPLICATION_ENV, APPLICATION_PATH . '/configs/application.ini' ); parent::setUp(); } }
  • 31. © All rights reserved. Zend Technologies, Inc. Create and dispatch a request ● Simple method: dispatch a “url” class ExampleControllerTest extends Zend_Test_PHPUnit_ControllerTestCase { // ... public function testStaticPageHasGoodStructure() { $this->dispatch('/example/page'); // ... } } class ExampleControllerTest extends Zend_Test_PHPUnit_ControllerTestCase { // ... public function testStaticPageHasGoodStructure() { $this->dispatch('/example/page'); // ... } }
  • 32. © All rights reserved. Zend Technologies, Inc. Create and dispatch a request ● More advanced: customize the request object prior to dispatching class ExampleControllerTest extends Zend_Test_PHPUnit_ControllerTestCase { // ... public function testXhrRequestReturnsJson() { $this->getRequest() ->setHeader('X-Requested-With', 'XMLHttpRequest') ->setQuery('format', 'json'); $this->dispatch('/example/xhr-endpoint'); // ... } } class ExampleControllerTest extends Zend_Test_PHPUnit_ControllerTestCase { // ... public function testXhrRequestReturnsJson() { $this->getRequest() ->setHeader('X-Requested-With', 'XMLHttpRequest') ->setQuery('format', 'json'); $this->dispatch('/example/xhr-endpoint'); // ... } }
  • 33. © All rights reserved. Zend Technologies, Inc. Create assertions ● Typical assertions are for: ▶ Structure of response markup Using either CSS selectors or XPath assertions. ▶ HTTP response headers and status code ▶ Request and/or Response object artifacts
  • 34. © All rights reserved. Zend Technologies, Inc. CSS Selector assertions ● assertQuery($path, $message = '') ● assertQueryContentContains( $path, $match, $message = '') ● assertQueryContentRegex( $path, $pattern, $message = '') ● assertQueryCount($path, $count, $message = '') ● assertQueryCountMin($path, $count, $message = '') ● assertQueryCountMax($path, $count, $message = '') ● each has a "Not" variant
  • 35. © All rights reserved. Zend Technologies, Inc. XPath Selector assertions ● assertXpath($path, $message = '') ● assertXpathContentContains( $path, $match, $message = '') ● assertXpathContentRegex( $path, $pattern, $message = '') ● assertXpathCount($path, $count, $message = '') ● assertXpathCountMin($path, $count, $message = '') ● assertXpathCountMax($path, $count, $message = '') ● each has a "Not" variant
  • 36. © All rights reserved. Zend Technologies, Inc. Redirect assertions ● assertRedirect($message = '') ● assertRedirectTo($url, $message = '') ● assertRedirectRegex($pattern, $message = '') ● each has a "Not" variant
  • 37. © All rights reserved. Zend Technologies, Inc. Response assertions ● assertResponseCode($code, $message = '') ● assertHeader($header, $message = '') ● assertHeaderContains($header, $match, $message = '') ● assertHeaderRegex($header, $pattern, $message = '') ● each has a "Not" variant
  • 38. © All rights reserved. Zend Technologies, Inc. Request assertions ● assertModule($module, $message = '') ● assertController($controller, $message = '') ● assertAction($action, $message = '') ● assertRoute($route, $message = '') ● each has a "Not" variant
  • 39. © All rights reserved. Zend Technologies, Inc. Assertion examples public function testSomeStaticPageHasGoodStructure() { $this->dispatch('/example/page'); $this->assertResponseCode(200); $this->assertQuery('div#content p'); $this->assertQueryCount('div#sidebar ul li', 3); } public function testSomeStaticPageHasGoodStructure() { $this->dispatch('/example/page'); $this->assertResponseCode(200); $this->assertQuery('div#content p'); $this->assertQueryCount('div#sidebar ul li', 3); }
  • 40. © All rights reserved. Zend Technologies, Inc. Assertion examples public function testXhrRequestReturnsJson() { // ... $this->assertNotRedirect(); $this->assertHeaderContains( 'Content-Type', 'application/json'); } public function testXhrRequestReturnsJson() { // ... $this->assertNotRedirect(); $this->assertHeaderContains( 'Content-Type', 'application/json'); }
  • 41. 41 © All rights reserved. Zend Technologies, Inc. Advanced Topics or: real world use cases
  • 42. © All rights reserved. Zend Technologies, Inc. Testing models and resources ● The Problem: These classes cannot be autoloaded with the standard autoloader. ● The Solution: Use Zend_Application to bootstrap the “modules” resource during setUp()
  • 43. © All rights reserved. Zend Technologies, Inc. Testing models and resources class Blog_Model_EntryTest extends PHPUnit_Framework_TestCase { public function setUp() { $this->bootstrap = new Zend_Application( APPLICATION_ENV, APPLICATION_PATH . '/configs/application.ini' ); $this->bootstrap->bootstrap('modules'); $this->model = new Blog_Model_Entry(); } } class Blog_Model_EntryTest extends PHPUnit_Framework_TestCase { public function setUp() { $this->bootstrap = new Zend_Application( APPLICATION_ENV, APPLICATION_PATH . '/configs/application.ini' ); $this->bootstrap->bootstrap('modules'); $this->model = new Blog_Model_Entry(); } }
  • 44. © All rights reserved. Zend Technologies, Inc. Testing actions requiring authentication ● The Problem: Some actions may require an authenticated user; how can you emulate this? ● The Solution: Manually authenticate against Zend_Auth prior to calling dispatch().
  • 45. © All rights reserved. Zend Technologies, Inc. Authenticating a test user class ExampleControllerTest extends Zend_Test_PHPUnit_ControllerTestCase { // ... public function loginUser($user) { $params = array('user' => $user); $adapter = new Custom_Auth_TestAdapter( $params); $auth = Zend_Auth::getInstance(); $auth->authenticate($adapter); $this->assertTrue($auth->hasIdentity()); } } class ExampleControllerTest extends Zend_Test_PHPUnit_ControllerTestCase { // ... public function loginUser($user) { $params = array('user' => $user); $adapter = new Custom_Auth_TestAdapter( $params); $auth = Zend_Auth::getInstance(); $auth->authenticate($adapter); $this->assertTrue($auth->hasIdentity()); } }
  • 46. © All rights reserved. Zend Technologies, Inc. Authenticating and dispatching class ExampleControllerTest extends Zend_Test_PHPUnit_ControllerTestCase { // ... public function testAdminUserCanAccessAdmin() { $this->loginUser('admin'); $this->dispatch('/example/admin'); $this->assertQuery('div#content.admin'); } class ExampleControllerTest extends Zend_Test_PHPUnit_ControllerTestCase { // ... public function testAdminUserCanAccessAdmin() { $this->loginUser('admin'); $this->dispatch('/example/admin'); $this->assertQuery('div#content.admin'); }
  • 47. © All rights reserved. Zend Technologies, Inc. Testing pages dependent on prior actions ● The Problem: Some actions are dependent on others; e.g., retrieving a page with content highlighted based on a search string. ● The Solution: Dispatch twice, resetting the request and response between calls.
  • 48. © All rights reserved. Zend Technologies, Inc. Testing pages dependent on prior actions class ExampleControllerTest extends Zend_Test_PHPUnit_ControllerTestCase { // ... public function testHighlightedTextAfterSearch() { $this->getRequest()->setQuery( 'search', 'foobar'); $this->dispatch('/search'); $this->resetRequest(); $this->resetResponse(); $this->dispatch('/example/page'); $this->assertQueryContains( 'span.highlight', 'foobar'); } class ExampleControllerTest extends Zend_Test_PHPUnit_ControllerTestCase { // ... public function testHighlightedTextAfterSearch() { $this->getRequest()->setQuery( 'search', 'foobar'); $this->dispatch('/search'); $this->resetRequest(); $this->resetResponse(); $this->dispatch('/example/page'); $this->assertQueryContains( 'span.highlight', 'foobar'); }
  • 49. 49 © All rights reserved. Zend Technologies, Inc. Conclusions
  • 50. © All rights reserved. Zend Technologies, Inc. Test Always! ● Unit test your models, service layers, etc. ● Do functional/acceptance testing to test workflows, page structure, etc.
  • 51. © All rights reserved. Zend Technologies, Inc. Zend Framework Training & Certification ● Zend Framework: Fundamentals This course combines teaching ZF with the introduction of the Model-View-Controller (MVC) design pattern, to ensure you learn current best practices in PHP development. Next Class: August 16, 17, 18, 19 20, 23, 24, 25 & 26 from 9am-11am Pacific
  • 52. © All rights reserved. Zend Technologies, Inc. Zend Framework Training & Certification ● Zend Framework: Advanced The Zend Framework: Advanced course is designed to teach PHP developers already working with Zend Framework how to apply best practices when building and configuring applications for scalability, interactivity, and high performance. Next Class: Sept. 7, 8, 9, 10, 13, 14, 15, 16 & 17 from 8:30am-10:30am Pacific
  • 53. © All rights reserved. Zend Technologies, Inc. Zend Framework Training & Certification ● Test Prep: Zend Framework Certification The Test Prep: Zend Framework Certification course prepares experienced developers who design and build PHP applications using ZF for the challenge of passing the certification exam and achieving the status of Zend Certified Engineer in Zend Framework(ZCE-ZF). ● Free Study Guide http://www.zend.com/en/download/173
  • 54. © All rights reserved. Zend Technologies, Inc. ZendCon 2010! ● 1—4 November 2010 ● http://www.zendcon.com/