I have to preface this video by saying that I’m still a bit of a novice when it comes to unit testing (especially in Zend). Also, I feel that I wouldn’t be able to take credit for the whole implementation.
Here are some great resources on unit testing in the Zend Framework to beef up your knowledge.
- Set up a Zend Framework application using Zend_Application (including PHPUnit setup)
- Testing Zend Framework MVC Applications – phly, boy, phly
- Matthew’s pastebin
The trouble with these is that they’re mostly pre-1.8. I’ve taken the approach of using a command line instead of the IDE since this way it doesn’t matter if you’re using Zend Studio for Eclipse.
What’s covered:
- Using phpunit with MAMP
- Unit Testing Models
- Generating Code Coverage Reports
- Unit Testing Controllers
Don’t forget to grab the source code or browse it on google code.

i want to start using phpunit for my web app and i am grateful for this video showing the basic steps. most of the pages in my app require the visitor to login . when i try to run any code via phpunit that is dispatching to the login page, i get error = ‘Zend_session is not marked as readable’.
here is my test method code:
public function testLoginActionPost()
{
$this->getRequest()
->setmethod(‘POST’);
$this->dispatch(“/auth/login”);
$this->assertController(“auth”);
$this->assertAction(“login”);
$this->assertResponseCode(200);
}
and here is the error:
There was 1 error:
1) IndexControllerTest::testLoginActionPost
Zend_Session_Exception: Zend_Session is not marked as readable.
library\Zend\Session\Abstract.php:86
library\Zend\Session\Namespace.php:391
library\Zend\Auth\Storage\Session.php:117
library\Zend\Auth.php:133
application\views\helpers\BuildMenu.php:13
library\Zend\View\Abstract.php:342
application\layouts\layout.phtml:11
library\Zend\View.php:108
library\Zend\View\Abstract.php:833
library\Zend\Layout.php:793
library\Zend\Layout\Controller\Plugin\Layout.php:142
library\Zend\Controller\Plugin\Broker.php:331
library\Zend\Controller\Front.php:957
library\Zend\Test\PHPUnit\ControllerTestCase.php:190
tests\application\controllers\IndexControllerTest.php:45
if i follow the code in my BuildMenu.php, it is merely truying to check
if the user is logged in, when the exception is thrown:
$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity()) { <——— this line causes Zend_Session_Exception: Zend_Session is not marked as readable.
to be thrown.
for melissa (and maybe others), i had a similar issue and got answered in stackoverflow: http://stackoverflow.com/questions/1808148/unit-testing-phpunit-how-to-login
i hope it helps.
cheers
sorry for double posting, i forgot to check the followup notify checkbox…
Hi,
My architecture is quite similar than yours, my problem is after adding that line of code in my ControllerTestCase.php file :
“$this->application->bootstrap();”
I still get the following error : “Zend_Controller_Exception: No default module defined for this application”
except for this simple test :”$this->assertTrue(TRUE);”
Any idea ?
Thanks,
Hi Mike,
I would double-check your application.ini file.
@paul (late but for others who find this via Google as I did)
There doesn’t seem to be a solution for using Xdebug with Zend Server CE 4.0.5. The “official” response is:
“The PHP project only supports VC6 and VC9, and not VC8. Therefore I only
have VC6 and VC9 versions for Xdebug. ”
Source: http://xdebug.org/archives/xdebug-general/1634.html
Thank you very much! Very helpful!! Thanks to your info I managed to add a phpunit to my current project all together with code coverage reports!
So I’ve been trying to follow with this, and I’ve gotten to about minute 21:35. phpunit seems to be running fine, but when i enter in $phpunit –configuration phpunit.xml, it’s doing nothing. it’s just giving me a new command line.
if i add die(‘i’m the bootstrap’) to tests/application/bootstrap.php at the beginning, phpunit is still outputting ‘i’m the bootstrap’
if i insert that die in any of the other methods that have been created to this point in the video, i get nothing as well, so it’s making it really hard to figure out what’s happening.
any suggestions?
Re: Ty Barho
I am having the same issue. It looks like PHPUnit is failing because it can not require the correct resources from Zend_Test_PHPUnit_ControllerTestCase.
It is requiring PHPUnit/Framework/TestCase.php among others.
Because my PHPUnit is installed in:
C:\Program Files\Zend\ZendServer\bin\PEAR\PHPUnit
The required classes are not on the include path.
I have messed about moving the files and changing the include_path but i have not yet got it to work.
PHPUnit is not outputting any Error messages to the CLI (is this Correct?) It just fails to require the needed resource and returns back to the prompt.
Alex
A follow up to the issues that I was having in my previous post.
My System
Zend Server CE 4.0.6
Windows XP
In tests/application/bootstrap.php
add
require_once ‘Zend/Test/PHPUnit/ControllerTestCase.php’;
Im not sure how Jon is loading this but somehow the include path to Zend doesn’t seem to work when running tests on the CLI. (maybe its just me?)
Code Coverage Reports
———————
In order to get the code coverage reports working, I needed to disable zend debugger (I did this via the Zend Server (http://localhost/ZendServer))
Then install xdebug. and worked through the following page which worked 1st time. (I ommitted Step 3 as i didnt have that line in the debugger.ini file
http://forums.zend.com/viewtopic.php?f=8&t=553
I Hope this saves somebody some time, as i have been working on this for way—tooooo–long.
Alex
I’m using Zend Server CE ver 5 (php 5.3.1) on Windows.
As you know, it comnes with Zend Debugger.
For some reason I ignore, phpunit was not working until I removed Zend Debugger and installed Xdebug:
xdebug-2.0.5-5.3-nts-Win32-VC9-x86.dll
I tried xdebug 2.1 with no luck.
Errata:
AS you can see, in minute 18:56, Jon included the line:
require_once ‘Zend/Test/PHPUnit/ControllerTestCase.php’;
But he never mentioned that on the video.
This was giving me a headache until I watched closely and found this issue.
Thanks Jon.
Thank you very much for the time you spent on this video. This does leave one question though and that is how do you test your library files?
For instance if you have
/library/Namespace/Controller/Plugin/MyFront.php
How could you then run tests against things like this? We have a library that consists of many files and I would not want to leave them out of the testing phase.
I have gotten this testing to work outside of Zend Studio but it would be really nice if I could get it to work inside Zend Studio. I also have not followed your video to get the tests working. I plan to go through your video again today or tomorrow and try to implement this and see if it will work for us. I am sure that if we can test our libraries as well as the controllers and models we would be able to adopt this practice.
Except this walkthrough doesn’t match the source, doesn’t work right with *.16 of phpunit, and refuses to call in my StatsTest model (die statement isn’t triggered for a check)
This really needs to be re-done, and actually have the source made in the video be the source online. Doesn’t work? Fix it in the video, don’t upload different source code.
For an abstract idea such as this, having everything 1:1 is necessary, when the video != source code posted, users like myself just can’t get anything to work.
Hi Peter,
I’ll be revisiting the Unit Testing stuff again, especially since MAMP no longer comes with phpunit out of the box. Thanks for the feedback!
Hi Joseph,
to be honest, I gave up on getting Zend_Test to work with Zend Studio 6 months ago and haven’t looked at it since. I prefer NetBeans’ implementation however I ultimately find myself back at the command line at the end of the day. I think we’ll need another year or two to see the IDE’s provide a complete TDD workflow for developers that’s smooth. You should still be able to test your Controller plugins, just initialize an instance of Zend_Controller (if needed) and inject the object your testing inside. I would also suggest reviewing how the Controller plugins that come out of the box are unit tested and see what can be done for your own library.
Jon,
I was not specifically talking about Zend_Test. You can use PHPUnit with Zend Studio and the Zend Framework without using Zend_Test. I have had the unit testing *kinda* working in Zend Studio I believe you just have to follow a specific method.
Jon,
Thank you very much for this video. It enabled me to implement testing of my ZF app and my external libraries. While I cannot do the testing directly in Zend Studio I am satisfied with the ability to test my controllers/models, etc.
Thanks Again!
Hi,
Code coverage is not generated. I have downloaded xdebug and configured php.ini file, but still code coverage is not generated. What could be the reason.
Please help.
Thanks in advance
@Karthik I was having that problem. The thing was that I has two php.ini files, one for apache (used when we are in a web context) and the other inside the php folder (user when we are running in command line mode). I realiced the php.ini I have to edit was the second in order to get code coverage.
This is great, however, I’ve ran into an issue when using resource plugins in Zend_Application, eg:
resources.cachemanager.database.frontend.name = Core
resources.cachemanager.database.frontend.options.caching = true
resources.cachemanager.database.frontend.options.lifetime = 300
resources.cachemanager.database.frontend.options.automatic_serialization = true
resources.cachemanager.database.backend.name = File
resources.cachemanager.database.backend.options.cache_dir = APPLICATION_ROOT “/data/cache”
It does not appear as if the resource plugins are being loaded because in my model that I am testing, I receive the following:
Fatal error: Call to a member function getResource() on a non-object in /path/to/my/app/application/models/MyModel.php on line 34
The line throwing the error is in the Model’s constructor when instantiating the cache from the resource plugin:
$this->cache = Zend_Controller_Front::getInstance()->getParam(‘bootstrap’)->getResource(‘CacheManager’)->getCache(‘database’);
Any ideas on how to set up tests with Resource Plugins?
Hey Jon,
Man, I’m having the same problema as Mike up there….and my structure is almost like yours.
This is it:
“Zend_Controller_Exception: No default module defined for this application”
Cmon, i’m not even using moules! lol
It happens by the time when my test function calls dispatch.
Any idea?
Thanks man!
Hey!
@Küpper: ran into the same problem, make sure your application.ini/configuration is loaded. I’m using modules, but probably this will help you nonetheless.
I’ve also problems with application resources. The plugin files are loaded (tested with a simple echo in that file), but their init method isn’t executed, therefore I’m not able to use the plugins. I’ve already made sure that my application.ini is loaded and contains the necessary configurations for that plugin.
Any help would be appreciated.
Okay, I found the problem.
It’s a little more complicated, short version:
One resource plugin fired an exception, the exception tried to access a resource which wasn’t loaded at that time. That caused an exception which said the resource isn’t loaded yet.
Maybe this will help someone.
Thanks for video. It’s good tutorial.
We are not getting log folder in Testing->tests. we are using windows prompt. So can you say the commands for how to create the log folder in tests…Can you help me………
if you change into the directory with the phpunit.xml (usually [project]/tests) and simply run `phpunit` it detects the phpunit.xml and uses the settings. just define the log options like in the video.
if this doesn’t work for you try
`phpunit –coverage-html “./log/report” –testdox-html “./log/testdox.html”`
a detailed description of how to invoke phpunit can be found here:
http://www.phpunit.de/manual/current/en/textui.html
Brilliant thanks!
I was hassling with a few tutorials since they did not work
with the current release of PHPUnit 3.4.15 i.c.w. Zend Framework 1.10.8.
But your source code works perfectly. Now i can finally start Unit testing my Controller Actions within my projects.
Does xdebug always take some much memory 4096m and time to run? Or am I not configuring is right. I am using
MAMP (PHP 5.3)
Mac OS 10.6.5
Processor 2 x 2.66 GHz 6-Core Intel Xeon
Memory 8 GB 1333 MHz
Thanks
How to display real error message instead just this “failed asserting last controller used was “?
@deerwan, what do you mean a “real error message” ?
Hi jon
I was following your tutorials on PHPUnit and I seem to have run up against a unique problem. Every time I run phpunit (or –configuration phpunit.xml) I seem to automatically run the doctrine CLI too. I am currently trying to trace the problem but I just wanted to ask in case anyone else has run across a similar problem.
please let me know if you have a solution.
kartik
Found a temp solution…
add the following line to phpunit.xml
under phpunit->filter->whitelist->exclude
../application/scripts/
still looking for a better solution…
kartik
I assume he means the same issue I have: My page behaving different when called with phpunit or through the webpage. So I assume the bootstrapping is not quite complete, but have no idea and hint what the issue might be. All I get for this test:
class Admin_IndexControllerTest extends ControllerTestCase {
public function testIndexAction() {
$this->dispatch(“/admin/login/login”);
$this->assertController(“login”);
$this->assertAction(“login”);
$this->assertResponseCode(200);
}
}
is the following output:
>phpunit
PHPUnit 3.5.9 by Sebastian Bergmann.
F
Time: 3 seconds, Memory: 18.00Mb
There was 1 failure:
1) IndexControllerTest::testIndexAction
Failed asserting last controller used was “login”
C:\Program Files\Zend\ZendServer\share\ZendFramework\library\Zend\Test\PHPUnit\C
ontrollerTestCase.php:997
C:\Users\Hanno\Documents\chillifire\trunk\tests\application\modules\admin\contro
llers\IndexControllerTest.php:7
←[37;41m←[2KFAILURES!
←[0m←[37;41m←[2KTests: 1, Assertions: 1, Failures: 1.
←[0m←[2K
Generating code coverage report, this may take a moment.
So I have no idea what is going on here based on the test output. Is there any way we can see the actual error that lead to the call of the error page by the dispatcher?
Can I suggest to replace direct loading of Zend Application and other modules in the test classes with something like:
// Include path
set_include_path(
‘.’
. PATH_SEPARATOR . BASE_PATH . ‘/library’
. PATH_SEPARATOR . ‘application/modules/admin/controllers’
. PATH_SEPARATOR . ‘application/modules/default/controllers’
. PATH_SEPARATOR . get_include_path()
);
/** Zend_Application */
require_once ‘Zend/Loader/Autoloader.php’;
$loader = Zend_Loader_Autoloader::getInstance();
$loader->setFallbackAutoloader(true);
$loader->suppressNotFoundWarnings(false);
//$loader->pushAutoloader(‘helpers’, ‘helpers/’, ‘Helper’);
//$loader->registerNamespace(‘App_’);
then ALL the other require_once statements in all other files can be dropped – even the one for the ControllerTestCase.php
(Note the two commented rows how you can add your own namespace and load additional resources like helpers.)
(Note2: my controllers are in modules, so the include path has to be adapted depending on where the xxxControllerTestCase.php files are actually located, so autoloader can load them.
A lot more elegant and less error error prone, I would have thought.
On my first comment:
Resolved by adding logging to the application.
This was very helpful. This is the only tutorial on the web that actually works. I wasted 2 days with other tutorials. Zend Test documentation should include the link to this tutorial.
Thank!
Hi Jon,
At 18 mins and 53 seconds, did you stop for a break?
I noticed you added a require_once statement… Might be worth mentioning this above the video, because without it I get the error:
“PHP Fatal error: Class ‘Zend_Test_PHPUnit_ControllerTestCase’ not found in /var/www/myapp/trunk/tests/application/ControllerTestCase.php on line 5″
After adding:
require_once ‘Zend/Test/PHPUnit/ControllerTestCase.php’;
We’re all set to go again…
Hi – After completely avoiding unit testing for many years i can now see the benefits!
Thanks for a very clear tutorial
Cheers. G
I wanted to use Phactory to test part of the submit action source as given below: http://awesomescreenshot.com/050a0p2a6
Using Phactory, it is assured that the data is going into DB but the problem is in code coverage as some of the lines are still highlighted in red.
Is it necessary to consider the code coverage?
Hi Jon,
When I run the command “phpunit –configuration phpunit.xml”
I get the error:
PHP Fatal error: Uncaught exception ‘PHPUnit_Framework_Exception’ with message
‘Neither “Application Test Suite.php” nor “Application Test Suite.php” could be
opened.’ in D:\PHP\php5\PEAR\PHPUnit\Util\Skeleton\Test.php:102
Stack trace:
#0 D:\PHP\php5\PEAR\PHPUnit\TextUI\Command.php(157): PHPUnit_Util_Skeleton_Test-
>__construct(‘Application Tes…’, ”)
#1 D:\PHP\php5\PEAR\PHPUnit\TextUI\Command.php(129): PHPUnit_TextUI_Command->run
(Array, true)
#2 D:\PHP\php5\phpunit(53): PHPUnit_TextUI_Command::main()
#3 {main}
thrown in D:\PHP\php5\PEAR\PHPUnit\Util\Skeleton\Test.php on line 102
It brothered me a lot, what is the problem and how could I fix it?
@ratzip: I had the same error. You need to define one real test. I guess this worked in previous versions or PHPUnit, but now there must be a test case. You can grab a simple test from here for example: http://grover.open2space.com/content/unit-testing-zend-framework-111-and-phpunit#initialtest
Cheers, Anton
Yes it helped me.
I downloaded the source code and tried running it on windows using xampp. My phpunit version is 3.6.4. I get this error when i type
phpunit –configuration phpunit.xml
C:\xampp\htdocs\testsample\tests>phpunit –configuration phpunit.xml
PHPUnit 3.6.4 by Sebastian Bergmann.
Configuration read from C:\xampp\htdocs\testsample\tests\phpunit.xml
←[31;1mE←[0m←[31;1mE←[0m..
Time: 0 seconds, Memory: 10.00Mb
There were 2 errors:
1) IndexControllerTest::testIndexWithMessageAction
Declaration of Zend_Test_PHPUnit_Constraint_DomQuery::evaluate() should be compatible with that of PHPUnit_Framework_Constraint::evaluate()
C:\xampp\htdocs\hive\library\Zend\Test\PHPUnit\Constraint\DomQuery.php:40
C:\xampp\htdocs\hive\library\Zend\Test\PHPUnit\ControllerTestCase.php:512
C:\xampp\htdocs\testsample\tests\application\controllers\IndexControllerTest.php
:14
C:\xampp\php\PEAR\PHPUnit\Framework\TestCase.php:925
C:\xampp\php\PEAR\PHPUnit\Framework\TestCase.php:787
C:\xampp\php\PEAR\PHPUnit\Framework\TestResult.php:649
C:\xampp\php\PEAR\PHPUnit\Framework\TestCase.php:734
C:\xampp\php\PEAR\PHPUnit\Framework\TestSuite.php:772
C:\xampp\php\PEAR\PHPUnit\Framework\TestSuite.php:745
C:\xampp\php\PEAR\PHPUnit\Framework\TestSuite.php:705
C:\xampp\php\PEAR\PHPUnit\TextUI\TestRunner.php:325
C:\xampp\php\PEAR\PHPUnit\TextUI\Command.php:187
C:\xampp\php\PEAR\PHPUnit\TextUI\Command.php:125
C:\xampp\php\phpunit:44
2) IndexControllerTest::testIndexNoMessageAction
Declaration of Zend_Test_PHPUnit_Constraint_ResponseHeader::evaluate() should be
compatible with that of PHPUnit_Framework_Constraint::evaluate()
C:\xampp\htdocs\hive\library\Zend\Test\PHPUnit\Constraint\ResponseHeader.php:400
C:\xampp\htdocs\hive\library\Zend\Test\PHPUnit\ControllerTestCase.php:769
C:\xampp\htdocs\hive\library\Zend\Test\PHPUnit\ControllerTestCase.php:769
C:\xampp\htdocs\testsample\tests\application\controllers\IndexControllerTest.php
:22
C:\xampp\php\PEAR\PHPUnit\Framework\TestCase.php:925
C:\xampp\php\PEAR\PHPUnit\Framework\TestCase.php:787
C:\xampp\php\PEAR\PHPUnit\Framework\TestResult.php:649
C:\xampp\php\PEAR\PHPUnit\Framework\TestCase.php:734
C:\xampp\php\PEAR\PHPUnit\Framework\TestSuite.php:772
C:\xampp\php\PEAR\PHPUnit\Framework\TestSuite.php:745
C:\xampp\php\PEAR\PHPUnit\Framework\TestSuite.php:705
C:\xampp\php\PEAR\PHPUnit\TextUI\TestRunner.php:325
C:\xampp\php\PEAR\PHPUnit\TextUI\Command.php:187
C:\xampp\php\PEAR\PHPUnit\TextUI\Command.php:125
C:\xampp\php\phpunit:44
←[37;41m←[2KFAILURES!
←[0m←[37;41m←[2KTests: 4, Assertions: 10, Errors: 2.
←[0m←[2K
Generating code coverage report, this may take a moment.
Great tutorail, Thank you
As I’m just feeling my way in to the field of PHP/Zend based web development, this tutorial has taken my understanding of the use of phpunit forward in a massive leap.
You have saved me so much time & pain with your excellent tutorial.
Thank you so much,
F
@Srivathsa
This is a known issue: http://framework.zend.com/issues/browse/ZF-11828
To quote Matthew Weier O’Phinney:
“… the problem is that PHPUnit has broken BC both from 3.4 to 3.5 and from 3.5 to 3.6.”
I had the same problem. To resolve it, I had to modify some Zend Framework files:
- Zend/PHPUnit/Constraint/DomQuery.php
- Zend/PHPUnit/Constraint/Redirect.php
- Zend/PHPUnit/Constraint/ResponseHeader.php
Here is what I did in each of the above files:
public function evaluate($other, $assertType = null)
changed to
public function evaluate($other, $assertType = null, $returnResult = FALSE)
public function fail($other, $description, $not = false)
changed to
public function fail($other, $description, PHPUnit_Framework_ComparisonFailure $comparisonFailure = NULL)
Although this did enable the tests to work, the downside is I now need to remember to update those files for every project.
Hi, I’m using OSX LION, and PHPUnit 3.6.9
And I ran into a problem:
Declaration of Zend_Test_PHPUnit_Constraint_ResponseHeader::evaluate() should be compatible with that of PHPUnit_Framework_Constraint::evaluate()
Googled it.. Found a solution on StackOverFlow.com
Zend Framework 1 applications currently, and possibly for quite some time, only function properly using PHPUnit 3.5.x
Solution: I Had to downgrade my PHPUnit version to 3.5.15
1) Uninstall current version
sudo pear uninstall phpunit/PHPUnit
sudo pear uninstall phpunit/DbUnit
sudo pear uninstall phpunit/PHP_CodeCoverage
sudo pear uninstall phpunit/File_Iterator
sudo pear uninstall phpunit/PHP_Timer
sudo pear uninstall phpunit/PHPUnit_MockObject
sudo pear uninstall phpunit/Text_Template
sudo pear uninstall phpunit/PHPUnit_Selenium
sudo pear uninstall pear.symfony-project.com/YAML
2) Install version 3.5.15
sudo pear install pear.symfony-project.com/YAML-1.0.2
sudo pear install phpunit/PHPUnit_Selenium-1.0.1
sudo pear install phpunit/PHPUnit_MockObject-1.0.3
sudo pear install phpunit/PHP_Timer-1.0.0
sudo pear install phpunit/File_Iterator-1.2.3
sudo pear install phpunit/PHP_CodeCoverage-1.0.2
sudo pear install phpunit/DbUnit-1.0.3
sudo pear install phpunit/PHPUnit-3.5.15
So far so good, that is I have not run into any problem so far after 2 days using this FIX.
Thanx for ZendCasts 1337!
Ooops forgott this.
Before I did all that I did this…
sudo pear uninstall phpunit/PHP_TokenStream
sudo pear install phpunit/PHP_TokenStream-1.0.1