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)