Joeri Timmermans
Joeri Timmermans
PHP/Symfony Developer with
a passion for food and drinks
Developer @ Intracto

Testing your Symfony application with behat

Wednesday August 26, 2015 - Permalink - Tags: symfony2, linux, testing, vagrant, setup, behat, selenium

This guide will help you create a basic setup from start to end to test a symfony environment with behat with mink, selenium and phantomjs. I'll be showing you some of the issues I ran into so you don't have to worry about them.

Assumptions

  • You have a working symfony project
  • You know how to work with composer (More info)
  • You have the latest version of Java installed

STEP 1: Composer install

In order to use behat and all it's components you have to add them to your composer.json and install them.

"require-dev": {
    "behat/behat": "^3.0",
    "behat/symfony2-extension": "^2.0",
    "behat/mink": "^1.6",
    "behat/mink-extension": "^2.0",
    "behat/mink-browserkit-driver": "^1.2",
    "behat/mink-goutte-driver": "1.1.0",
    "behat/mink-selenium2-driver": "1.2.0"
}

STEP 2: Create our behat.yml

This file should contain your behat setup information. As a best practice I recommend placing this file in your app/config directory. Here is an example file:

default:
    suites:
        sofia:
            type: symfony_bundle
            bundle: AcmeBundle
            mink_session: selenium2
            contexts:
                - AcmeBundle\Features\Context\FeatureContext
    extensions:
        Behat\Symfony2Extension: ~
        Behat\MinkExtension:
            base_url:  http://www.myproject.dev
            sessions:
                default:
                    symfony2: ~
                goutte:
                    goutte: ~
                selenium2:
                    selenium2: ~

Depending on what server you start you can run this in Selenium with firefox or with PhantomJS headless.

STEP 3: Create our FeatureContext

Folder: AcmeBundle/Features/Context/

In this folder we have to create atleast 1 file named FeatureContext so we have a starting context for our tests. You have to declare these contexts in your suite if you want more then one. See STEP 2 for more info.

Here is an example of a FeatureContext with 1 statement:

<?php

namespace AcmeBundle\Features\Context;

use Behat\MinkExtension\Context\MinkContext;
use Behat\Symfony2Extension\Context\KernelAwareContext;
use Symfony\Component\HttpKernel\KernelInterface;

class FeatureContext extends MinkContext implements KernelAwareContext
{
    private $kernel;

    public function setKernel(KernelInterface $kernel)
    {
        $this->kernel = $kernel;
    }

    protected function getContainer()
    {
        return $this->kernel->getContainer();
    }

    /**
     * @Given /^I wait for (\d+) seconds$/
     */
    public function iWaitForSeconds($seconds)
    {
        $this->getSession()->wait($seconds * 1000);
    }
}

This file or other context files, can be used to declare your own personal checks. In this example we made a statement to let our test sleep for x amount of seconds by calling "Given I wait for 2 seconds"

STEP 4: Writing a feature

Folder: AcmeBundle/Features/

Our features are our actually tests, this file contains your scenarios that have to be tested. Since we're using Mink you have a wide variety of statements at our dispossal. For more info check out the Mink Documentation.

Feature: Login as foo and see if we can logout

Scenario: login and logout with user Foo
    Given I am on "/login"
    When I fill in "_username" with "Foo"
    When I fill in "_password" with "Bar"
    When I press "Login"
    Then I should be on "/profile"
    Then I should see "Hi, Foo"
    When I follow "Logout"
    Then I should be on "/login"

STEP 5: Run our test

To run our tests we need either Selenium or PhantomJS, depending on which of the two we want to use to run our tests. Default we declared to use Selenium so we'll start with that.

STEP 5.1: Run our test with Selenium

5.1.1: Download/Install Selenium server

On Mac with Brew:

brew install selenium-server-standalone

For more info or other OS you can visit the website

5.1.2: Start Selenium server

selenium-server -p 4444

5.1.3: Run tests

vendor/bin/behat --config app/config/behat.yml

5.2: Run our test with PhantomJS

5.2.1: Download/Install PhantomJS

On Mac with Brew:

brew install phantomjs

For more info or other OS you can visit the website

5.2.2: Start PhantomJS

phantomjs --webdriver=4444 

5.2.3: Run tests

vendor/bin/behat --config app/config/behat.yml -p phantomjs

STEP 6: Check your tests

This should be the response after your run your tests:

Feature: Login as foo and see if we can logout

  Scenario: login and logout with user Foo  # AcmeBundle/Features/login.feature:3
    Given I am on "/login"                  # FeatureContext::visit()
    When I fill in "_username" with "Foo"   # FeatureContext::fillField()
    When I fill in "_password" with "Bar"   # FeatureContext::fillField()
    When I press "Login"                    # FeatureContext::pressButton()
    Then I should be on "/profile"          # FeatureContext::assertPageAddress()
    Then I should see "Hi, Foo"             # FeatureContext::assertPageContainsText()
    When I follow "Logout"                  # FeatureContext::clickLink()
    Then I should be on "/login"            # FeatureContext::assertPageAddress()

1 scenario (1 passed)
8 steps (8 passed)
0m23.05s (46.70Mb)
comments powered by Disqus