Unit Testing with the Zend Framework with Zend_Test and PHPUnit

June 11th, 2009

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.

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.

 

65 Responses to “Unit Testing with the Zend Framework with Zend_Test and PHPUnit”

  1. Juan Felipe Alvarez Saldarriaga says:

    Great video!, what about Zend_Application with modules bootstraping ?

    Thx!

  2. jon says:

    Thanks for the feedback Juan :)

    I think I covered that a couple videos ago (using Zend_Tool)… or are you referring to something else?

  3. Phil says:

    Your website is fantastic.

    If you need french help.. z-f.fr

  4. Silone says:

    Very nice video Jon, you are the greatest :)

    Just wanted to drop a question,
    in your model test you write

    foreach ( $this->stats->getCountries() as $country )
    {
    if ( $country == $defaultCountry )
    $this->assertEquals($country, $defaultCountry);
    }

    the thing is, i don’t like this if, it already answers the assertion and therefore “overiterates” the testing.
    Maybe i just didn’t get the point of this test, if so tell me i’m eager to hear your reasoning :)

    Just to finish my thought:

    $isCountryAdded = in_array($defaultCountry, $this->stats->getCountries());
    $this->assertTrue($isCountryAdded);

    This seems to be an way to dismiss the if and therefore always have the assertion take place.

    Greetings and many many thanks again for all the help with the setup & configuration of phpunit :) )

  5. Silone!

    That’s a much cleaner way of doing the assertion. Thank you!

  6. Nick says:

    Just wondering how you would go about testing a AsyncController like the one in a previous video? I can’t seem to figure it out.

    Thanks for the videos. Keep it up.

  7. Nick says:

    RE:Comment 6

    Worked it out… my code was misleading me ;-)

  8. Tom says:

    Hi Jon,
    I have found your website very helpful. I tried this tutorial and everything worked fina but when I run the test the test-coverage report is not created. I tried to use your source code but the same problem occure. Do you have any clue what could be possibly wrong? Thx

  9. jon says:

    Hi Tom,

    its possible that the phpunit.xml was mis-configured… another possibility is that you may not have permissions set to write to those particular folders. Hope that helps,
    -
    Jon

  10. Tom says:

    Hi Jon,
    I found out that my xdebug was not installed :-D Now everything is working fine :-)

  11. Dave Kennedy says:

    Hi Jon,
    Excellent website which has been a excellent resource for me. I’m struggling a bit testing models which extend Zend_Db_Table_Abstract. I know this is all to do with the bootstrapping.

    The application can access, store data etc. to the DB but it appears I have not to have been able to set up the DB correctly for my test suite.

    Could you provide any assistance?

  12. jon says:

    Hi Dave,
    do you have a test database? or at least a database setup in your application.ini file under the ‘testing’ heading? That might be the only problem. Can you paste your exception information?

  13. Dave Kennedy says:

    Hi Jon, thanks for getting back to me, yeah I have a test DB and it correctly setup under [testing : production] in my application.ini.

    phpunit comes back with “Fatal error: Class ‘Zend_Db_Table_Abstract’ not found”

    I kinda expected it would as autoloading is setup in my applications bootstrap (not test bootstrap) using

    class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
    {
    protected function _initAutoload()
    {
    $autoloader = new Zend_Application_Module_Autoloader(array(
    ‘namespace’ => ”,
    ‘basePath’ => dirname(__FILE__),
    ));
    return $autoloader;
    }
    }
    , I just was not clear how to do this under the setup you described.

    Thanks in advance

    Dave

  14. Jon says:

    Ah… you might need to explicitly include it in the array which is passed into set_include_paths.. since Model_ might not be loaded by convention through the unit tests…

  15. Dave Kennedy says:

    Thanks for the reply Jon, Model_ is loaded by convention, but not initializing a DB such as…

    protected function _initDatabase()
    {
    $resource = $this->getPluginResource(‘db’);
    $db = $resource->getDbAdapter();
    Zend_Db_Table_Abstract::setDefaultAdapter($db);

    I had a look at Matthew’s blog and frigged a similar method, only difference being in the setup method of every test cases I call the applications bootstrap (not test bootstrap file that is created with Zend Tool)but suppose I could extend a class similar to what you have here.

  16. Joe Devon says:

    Excellent screencast, Jon. Many thanks! It was very useful.

  17. UJ says:

    Very helpfull. Thanks!

  18. Martin says:

    Hi,

    why is Model_StatsTest extending ControllerTestCase?

  19. jon says:

    Hi Martin,
    ControllerTestCase is a bit of a misnomer since its not only a class that helps with setting up Zend_Test_* classes, but also helps you bootstrap your application and make it run with the same include paths etc… that you would expect if you were running the app in dev/staging/production environments. I could extend a class that would be similar that didn’t have the ability to start the front controller however it would require a more complex design for my testing framework. As long as the developer is disciplined and doesn’t run non Model-specific unit tests in StatsTest, I don’t see a problem. What do you think?

  20. [...] bootstrap not working in windows July 8, 2009 While following this tutorial and trying to set up phpunit to work with the Zend Framework, I couldn’t for the life of me [...]

  21. [...] Скрин-каст: Unit Testing with the Zend Framework with Zend_Test and PHPUnit [...]

  22. Alex says:

    Hi question.
    I downloaded MAMP but i don’t have phpunit in that directory. How can i get it?

  23. jon says:

    Hi Alex,

    I think things have changed since I downloaded my copy of MAMP. Here are two articles about grabbing phpunit with MAMP:
    http://mark-kirby.co.uk/2009/installing-phpunit-with-mamp/

    http://www.typeoneerror.com/installing-phpunit-with-mamp/

    hope that helps,
    -
    Jon

  24. Lee says:

    I am having trouble getting my classes to auto load. Also, why is the application Bootstrap.php a class but the Zend_Test bootstrap.php is not a class. In my application Bootstrap.php file I have a function named _initAutoload() like this:

    class Bootstrap extends Zend_Application_Bootstrap_Bootstrap {

    protected function _initAutoload() {
    $moduleLoader = new Zend_Application_Module_Autoloader(array(‘namespace’ => ”, ‘basePath’ => APPLICATION_PATH));
    }

    }

    But since my Zend_Test bootstrap.php file is not a class, I’m not sure how to get the autoloading to work.

    Great screencast!

  25. jon says:

    Hi Lee,

    bootstrap.php if a procedurally-written file that is run via the phpunit.xml file. The Bootstrap.php file is specifically part of the Zend framework’s bootstrap. This includes configuration and other business that is uniform across the test and dev/test instances of your application.

  26. Lee says:

    I’m new to testing this way with the Zend Framework. Excellent point about the boostrap.php file being run by the phpunit XML config file. So I put this line in my appBootstrap() function in the ControllerTestCase class:

    Zend_Application_Module_Autoloader(array(‘namespace’ => ”, ‘basePath’ => APPLICATION_PATH));

    Now I’m trying to figure out how to get my default database adapter set up.

  27. Kanaran says:

    I tried unit testing on my vista machine and i didn’t get the coverage report. testdox is there, but no coverage. phpunit version is 3.3.9.
    i did the test as vista-admin. no error messages – no report :(

    any hints?

    p.s.: sorry for my english, i’m not a nativ speaker.

  28. Dave Kennedy says:

    You need xdebug for the coverage reports

  29. Alex says:

    @john:
    Thanks for the links. PHPUnit and Xdebug is now running. But i have a problem. I wanted to test it and created a standart project with zend_tool and copied the tests folder from your example.
    But when i now run phpunit it seems that it does nothing. No code coverage, now test and so on.

    But if i try it with your example it works.

  30. Jaime says:

    Great!!
    Thanks jon

  31. [...] un primer TestUnitario. Ref: “Unit testing with ZF” by [...]

  32. yiyi says:

    this video is excellent!! i really grateful for your share,but i want to know! how can i download it? i am looking forward to your replying!

  33. alexander says:

    Now I have some kind of idea about unit testing! Thanks a lot!

  34. iceangel89 says:

    how was it that you set up unit testing for netbeans i am kind of lost …

  35. jon says:

    hey iceangel89,

    I wrote a mini tutorial about my setup on my blog — http://lebensold.net/development/unit-testing-within-the-netbeans-6-7-1-ui

  36. shashi says:

    Thanks Jon,

    very informative !
    U the man :)

  37. iceangel89 says:

    i cant seem to get pear/phpunit working correctly on my windows 7.

    when i run “pear” i get “syntax error, unexpected ‘(‘ in Unknown on line 14″ tho the help stuff comes out.

    when i run “phpunit”, i get “‘”"C:\Program’ is not recognized as an internal or external command,
    operable program or batch file.” tho the tests run.

  38. Kevin says:

    Hmm can somebody tell me what i did wrong i have mamp followed the tutorials..but when i type phpunit nothing happens i dont get to see the parameters..

    Thanks for your answer!

  39. Alexey says:

    I tried to follow this video, but on windows.
    I install phpunit and made a phpunit.xml file.
    Then I executed phpunit –configuration phpunit.xml, but it displayed nothing.
    Then I executed phpunit –bootstrap application\bootstrap.php and it displayed a die(…) message.
    So, I understood, that phpunit ignored my phpunit.xml

    Ok, then I started to change a bootstrap file, as I saw in video and executed phpunit –bootstrap application\bootstrap.php again.
    But that moment it displaay nothing. But in video it displayed some information. (
    I don’t understand a phpunit behaviour on windows. ((

  40. Jason says:

    Loved the tutorial. I had a bit of trouble installing xdebug at first because I was using the latest version of zend server… however, once that was all taken care of, the video was extremely helpful. Thanks!!

  41. [...] Unit Testing width the Zend Framework – 3 Screencasts [...]

  42. Ian Munday says:

    Great video, but I’m having the following problem:

    I can use most assertion methods such as assertModule(), assertController(), assertAction() and assertResponseCode(), but when I try to use methods such as assertQueryContentContains() or assertXpathContentContains(), I get the following exception:

    Zend_Dom_Exception: Error parsing document (type == docXml)

    Has anyone else encountered this, or have clues as to how to fix?

    Regards,

    Ian

  43. Ian Munday says:

    My error was due to having the following at the top of my response:

    As my document was not in fact valid XML, removing this solved my problem.

    Also see http://www.nabble.com/PHPUnit-testing-generating-Zend_Dom_Exception-td25522644.html

    Regards,

    Ian

  44. Sandor says:

    Hi There,

    for all who tries it with ZF 1.9.x and PHHUnit 3.3.17 or greater the following would help to solve some issues:
    -> asserting Xpath only accept valid xpath e.g.
    assertContentContains(“id(‘message’)”,”default”) becomes
    $this->assertXpathContentContains(“//h2[@id='message']“,”default” );

    and somehow even xdebug is set the logging doesn’t work on my mac

    r. Sandor

  45. Sudheer says:

    Thanks for the screen cast. I figured with the help of fw-general ML, how to test models and library classes without extending Zend_Test_PHPUnit_ControllerTestCase.

    Fix the session related testing issues:
    In tests/bootstrap.php have this line of code

    require_once ‘Zend/Session.php’;
    Zend_Session::$_unitTestEnabled = true;

    In the tests/bootstrap.php script initialize and bootstrap your application.

    $application = new Zend_Application(
    APPLICATION_ENV,
    APPLICATION_PATH . ‘/configs/application.ini’
    );
    $application->bootstrap();

    Note, we are not running the application, just bootstrapping. Your model classes can now extend PHPUnit_Framework_TestCase instead of Zend_Test_PHPUnit_ControllerTestCase.

  46. jon says:

    thanks for mentioning this sudheer!

  47. Russ says:

    After running the sudo ln -s command, phpunit is not moved to my home directory. Any ideas?

  48. Karl Purkhardt says:

    Hi, first of all, great screencast. However I have a problem, when I run my tests phpunit always fails when I have 2 or more tests (1 test is fine). I’ve tracked this down to the $application->bootstrap() call, basically the 2nd call causes phpunit to “break”, but I get no output, just a single “.” and then the test ends (I don’t even get the 1 test run etc. output). Do you have any idea why this is? If I limit the bootstrap() to only get called once then it works, but obviously I shouldn’t have to as you didn’t in your example. Thanks Karl.

  49. paul says:

    Hi, great screencast.
    I know that I need XDebug for Code Coverage. I downloaded this http://www.xdebug.org/files/php_xdebug-2.0.5-5.3-vc9-nts.dll and I am using Zend Server 4.0.5 for Windows Vista (32bit). I activated XDebug in php.ini and disabled Zend Optimizer+, Zend Debugger.
    For testing I used the code frome screencast (downloaded).

    Now my problem: phpunit says that I am using a wrong version of XDebug (VC9 instead of VC8), but there is no VC8 to download. And I can not find xdebug 2.1.0-dev for download, like in the screencast.

    How can I solve the problem?

Leave a Reply

Desktop RSS feed iPhone + iPod