Search code examples
phpzend-frameworktddbddbehat

Zend Framework integration with Behat BDD


Anyone has been using Behat with Zend Framework? Any examples on how to use both?


Solution

  • I got it working. It works with PHPUnit and Zend_Test so you can use all those nifty assertXYZ() methods. First, make sure you've got behat installed and available in your system $PATH. I did the following:

    sudo pear channel-discover pear.symfony.com
    sudo pear channel-discover pear.behat.org
    sudo pear install behat/behat
    

    Now, create a directory structure like so:

    features
        application
            ControllerTestCase.php
        bootstrap
            FeatureContext.php
        homepage.feature
    

    The features/application/ControllerTestCase.php class is typical of a Zend_Test testing implementation:

    <?php
    require_once 'Zend/Application.php';
    require_once 'Zend/Test/PHPUnit/ControllerTestCase.php';
    
    class ControllerTestCase extends Zend_Test_PHPUnit_ControllerTestCase {
    
        public $application;
    
        public function setUp() {
            $this->application = new Zend_Application(APPLICATION_ENV, APPLICATION_PATH 
                    . '/configs/application.ini');
            $this->bootstrap = array($this, 'appBootstrap');
            parent::setUp();
        }
    
        public function appBootstrap(){
            $this->application->bootstrap();
        }
    }
    

    The features/bootstrap/FeatureContext.php class is what Behat needs to bootstrap itself:

    <?php
    
    use Behat\Behat\Context\ClosuredContextInterface,
        Behat\Behat\Context\TranslatedContextInterface,
        Behat\Behat\Context\BehatContext,
        Behat\Behat\Exception\PendingException;
    use Behat\Gherkin\Node\PyStringNode,
        Behat\Gherkin\Node\TableNode;
    
    require_once 'PHPUnit/Autoload.php';
    require_once 'PHPUnit/Framework/Assert/Functions.php';
    
    define('APPLICATION_ENV', 'testing');
    define('APPLICATION_PATH', dirname(__FILE__) . '/../path/to/your/zf/application');
    
    set_include_path('.' . PATH_SEPARATOR . APPLICATION_PATH . '/../library'
            . PATH_SEPARATOR . get_include_path());
    
    require_once dirname(__FILE__) . '/../application/ControllerTestCase.php';
    
    class FeatureContext extends BehatContext {
    
        protected $app;
    
        /**
         * Initializes context.
         * Every scenario gets it's own context object.
         *
         * @param array $parameters context parameters (set up via behat.yml)
         */
        public function __construct(array $parameters) {
            $this->app = new ControllerTestCase();
            $this->app->setUp();
        }
    
        /**
         * @When /^I load the URL "([^"]*)"$/
         */
        public function iLoadTheURL($url) {
            $this->app->dispatch($url);
        }
    
        /**
         * @Then /^the module should be "([^"]*)"$/
         */
        public function theModuleShouldBe($desiredModule) {
            $this->app->assertModule($desiredModule);
        }
    
        /**
         * @Given /^the controller should be "([^"]*)"$/
         */
        public function theControllerShouldBe($desiredController) {
            $this->app->assertController($desiredController);
        }
    
        /**
         * @Given /^the action should be "([^"]*)"$/
         */
        public function theActionShouldBe($desiredAction) {
            $this->app->assertAction($desiredAction);
        }
    
        /**
         * @Given /^the page should contain a "([^"]*)" tag that contains "([^"]*)"$/
         */
        public function thePageShouldContainATagThatContains($tag, $content) {
            $this->app->assertQueryContentContains($tag, $content);
        }
    
        /**
         * @Given /^the action should not redirect$/
         */
        public function theActionShouldNotRedirect() {
            $this->app->assertNotRedirect();
        }
    
    }
    

    And now you can write features like features/homepage.feature:

    Feature: Homepage
      In order to know ZF works with Behat
      I need to see that the page loads.
    
    Scenario: Check the homepage
      Given I load the URL "/index"
      Then the module should be "default"
      And the controller should be "index"
      And the action should be "index"
      And the action should not redirect
      And the page should contain a "title" tag that contains "My Nifty ZF App"
    

    To run the tests, cd to the directory that contains the features folder, and type behat.

    Good luck!