Introduction

Welcome to another mage casts io. All of the previous MageCasts have focused on Behat in normal projects. we have seen how to set it up and configure it. Now lets take a look at how it can be used within Magento.

Now for Magento there is a special version of Behat called behatMage its exactly the same as Behat in fact it is behat this is just a plugin for Behat that allows behat to know about Magento. Its got some basic step definitions pre built as well as fixtures to allow easy creation of products orders and more.

So during this MageCast you will see how to install and configure BehatMage for Magento a look at some of the step definitions and we will write our first scenario for adding a product to the cart.

Getting started

I have already setup Magento 1.9.0.1 but we will cover how to setup a base box in Vagrant in a up and coming lesson. Now there is nothing special that I have done other than install the sample data. When we installed Behat previously we added it to our composer.json file and even though we are now working in Magento this is no different. We need to create a composer.json file in the root of our project.

If you head over to BehatMage on github ( https://github.com/MageTest/BehatMage ) there is a detailed ReadMe for how to get started with setup and a good scenario to get you started. Its worth pointing out that currently the develop branch is using Behat 2 now there is nothing wrong with Behat 2 however I like to use Behat 3 as it has some pretty cool features that we will be looking at in future lessons so instead of defining dev-develop or a version in our composer file we will want to add feature/Behat3 branch that has been upgraded to work with Behat 3.

Now there are a few things we need to do in out composer file. Require-dev obviously needs the behat information.

{
  "require-dev": {
  "magetest/magento-behat-extension": "dev-feature/Behat3",
    "bossa/phpspec2-expect": "~1.0",
    "peridot-php/webdriver-manager": "dev-master",
    "behat/mink": "~1.6.0",
     "behat/mink-extension": "~2.0.0",
     "behat/mink-goutte-driver": "~1.1.0",
     "behat/mink-selenium2-driver": "*"
  }
}

Lets make sure that all the bin files get put in a root dir:

"config": {  "bin-dir": "bin"},

Finally we need to configure some PSR autoloading so that the Behat extension can find Magento.

"autoload": {
     "psr-0": {    "": [
          "public/app/code/local",
          "public/app/code/community",
          "public/app/code/core",
          "public/app",
          "public/lib"    ]
      }
}

Next up we need to configure Behat to know about the plugin. Lets create a Behat.yml file with the following contents

default:

   suites:

      default:

         paths:

             features: features/site

             contexts:

                  - SiteContext

        system:

             paths:

                features: features/system

                contexts:

                    - SystemContext

    extensions:

        SensioLabs\Behat\PageObjectExtension:
             namespaces:
        page: [Page]
        MageTest\MagentoExtension\Extension: ~

        Behat\MinkExtension:

            base_url: 'http://magecastsio.dev/'
            selenium2:

               wd_host: http://127.0.0.1:4444/wd/hub
               browser: firefox

Now if we try and run Behat from out host machine were going to get an error message about the connection to redis. This is nothing to worry about its because Behat is trying to connect using Mage.php so we have to remember that we need to connect to the virtual box before running behat.

Notes: If you have X-Debug installed there is a potential that you might see the following error when running behat:

PHP Error: Maximum function nesting level of '100' reached, aborting

If you do don't panic. The fix is simple we just need to edit the x-debug.ini file on my centos machine its in /etc/php.d/xdebug.ini but the path may vary depending on your system. The fix is just as simple as adding:

xdebug.maxnestinglevel = 200 to the file.

Now because I'm running Behat Selenium and Magento all from within my VM there are some additional packages and settings that are required:

apt-get -y install openjdk-7-jre-headless firefox xvfb unzip

This installs' all of the required application dependencies java for selenium, firefox as the browser xvfb as the window manager and unzip for you know what.

We then need to tell the OS that we are running applications in a headless mode:

DISPLAY=:1 xvfb-run --server-args="-screen 0 1280x1024x8" java -jar selenium-server-standalone-2.40.0.jar

What this does is sets the display variable 1, and then starts xvfb with a new screen at 1280 resolution and then we finally start selenium and run it in the background.

Once we have all of these then we are ready to start running all of our scenarios.

Magento Behat

Lets recap where we are. So our VM is all ready and we have magento running. Were still developing on our local host as its Vagrant but because MageBehat has hard dependencies on Magento and its bootstrap we are going to be running Behat from within the vm.

Lets initialise behat for the first time as we have seen previously ./bin/behat --init just so we have some folders and a base feature context to work from.

As we know from last time this creates us all of the required folder dependencies. However as we installed the Magento extension for plugin we need to make some amends to the FeatureContext. We need to

use MageTest\MagentoExtension\Context\MagentoContext;

And ensure we extend from MagentoContext

Lets take a look at what the Magento extension gives us. [ Open up MagentoContext ] so we as well see there are several pre defined step definitions already in place for logging into the admin as different people. Logging into the admin section. We also have access to Mage:: in our contexts so we can load data from the database as part of our assertions.

Lets write a scenario just to validate that our install is working and that we have behat configured as we expect.

Feature: Testing that behat and magento are working together

  In order to continue working on Magento

  As a magento developer
  I need to be able to configure behat and magento



Scenario: Base URL is configured in the database

  Given there is a base_url configuration option set

  Then I should see the value being "http://magecastsio.dev/"

Lets run this so that we can append our snippets to the feature context. Now its not a scenario that we are going to be running over and over again but at least we know that Mage is accessible for us.

<?php
use MageTest\MagentoExtension\Context\MagentoContext;



class SystemContext extends MagentoContext implements Context, SnippetAcceptingContext{

private $baseUrl;


/**

* @Given there is a base_url configuration option set

*/
public function thereIsABaseUrlConfigurationOptionSet()   {
  $this->baseUrl = Mage::getBaseUrl();
}



/**

* @Then I should see the value being :url

*/
public function iShouldSeeTheValueBeing($url)    {
   expect($this->baseUrl)->toBe($url);
}
}

Now lets run behat and make sure that the database has the correct value for the store URL that we want.

Great, we have Behat and Magento configured and working together, Lets get back to writing a scenario that actually interacts with Magento. I think a good starting point will be to see how we can add an item to the cart. Under the Site suite lets add a new feature file with the following

Feature: Visitor can add items to the cart and shop

  In order to make a purchase

  As a visitor to the site
  I need to be able to see the product page and add the item to the cart



Scenario: Adding the item to the cart

  Given I am on a product page

  When I add the item to the cart

  Then I should see that the total items in my basket is "1"

From here we can run behat to append our snippets ./bin/behat --suite=default --append-snippets

<?php


use Behat\Behat\Tester\Exception\PendingException;
use Behat\Behat\Context\Context;
use Behat\Behat\Context\SnippetAcceptingContext;


use MageTest\MagentoExtension\Context\MagentoContext;

class SiteContext extends MagentoContext implements Context, SnippetAcceptingContext{


/**

* @Given I am on a product page

*/
public function iAmOnAProductPage()    {
   $this->getSession()->visit("http://magecastsio.dev/accessories/eyewear/aviator-sunglasses.html");
}



/**

* @When I add the item to the cart

*/
public function iAddTheItemToTheCart()    {
   $this->getSession()->getPage()->find('css', '.btn-cart')->click();
}



/**

* @Then I should see that the total items in my basket is :total

*/
public function iShouldSeeThatTheTotalItemsInMyBasketIs($total)    {
   $pageTotal = $this->getSession()->getPage()->find('css', '.count')->getText();
    expect($pageTotal)->toBe($total);


 }
}

Now lets run only the default suite ./bin/behat --suite=default and this time we should see all green as were adding the item to cart, magento redirects us to the checkout page and there is a min basket at the top with the count of the products in the basket.

Whats great here is that its not taken that much effort to get all of this working together. Most of it has been configuration on the VM and of the applications. Yet you can see how powerful this type of testing can be when working on Magento or any application for that matter. Imagine running this in CI or on each iteration of a TDD cycle. The only negatives


comments powered by Disqus
Comment Permalink