Skip to content

Instantly share code, notes, and snippets.

@jonathaningram
Created June 19, 2012 08:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jonathaningram/2952919 to your computer and use it in GitHub Desktop.
Save jonathaningram/2952919 to your computer and use it in GitHub Desktop.
default:
extensions:
Behat\Symfony2Extension\Extension: ~
Behat\MinkExtension\Extension:
base_url: 'http://localadmin.example.com'
selenium2: ~
sahi: ~
goutte: ~
default_session: goutte
javascript_session: sahi
<?php
use Behat\Behat\Context\ClosuredContextInterface;
use Behat\Behat\Context\TranslatedContextInterface;
use Behat\Behat\Context\BehatContext;
use Behat\Behat\Context\Step;
use Behat\Behat\Exception\PendingException;
use Behat\Gherkin\Node\PyStringNode;
use Behat\Mink\Mink;
use Behat\MinkExtension\Context\MinkContext;
use Behat\MinkExtension\Context\MinkAwareInterface;
use Behat\Symfony2Extension\Context\KernelAwareInterface;
use Behat\CommonContexts\SymfonyDoctrineContext;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
require_once 'PHPUnit/Autoload.php';
require_once 'PHPUnit/Framework/Assert/Functions.php';
/**
* Features context.
*/
class FeatureContext extends BehatContext implements MinkAwareInterface, KernelAwareInterface
{
private $mink;
private $minkParameters;
/**
* @var KernelInterface $kernel
*/
private $kernel;
/**
* Initializes context.
*/
public function __construct()
{
$this->useContext('symfony_doctrine', new SymfonyDoctrineContext());
$this->useContext('mink', new MinkContext());
}
/**
* {@inheritdoc}
*/
public function setMink(Mink $mink)
{
$this->mink = $mink;
}
/**
* {@inheritdoc}
*/
public function setMinkParameters(array $parameters)
{
$this->minkParameters = $parameters;
}
/**
* {@inheritdoc}
*/
public function setKernel(KernelInterface $kernel)
{
$this->kernel = $kernel;
}
/**
* Returns the kernel's service container.
*
* @return ContainerInterface
*/
public function getContainer()
{
return $this->kernel->getContainer();
}
}
@everzet
Copy link

everzet commented Jun 19, 2012

Where you put your FeatureContext ? :)

@jonathaningram
Copy link
Author

@everzet it's in /features/bootstrap/FeatureContext.php

Also:

$ tree features/
features/
├── bootstrap
│   └── FeatureContext.php

@jonathaningram
Copy link
Author

@everzet if it helps, here's the relevant composer.json entries:

{
        "php": ">=5.3.10",
        "symfony/symfony": "2.1.*",
        "behat/behat": "2.4.*",
        "behat/symfony2-extension": "dev-master",
        "behat/mink-extension":          "*",
        "behat/mink-browserkit-driver":  "*",
        "behat/mink-goutte-driver":     "*",
        "behat/mink-selenium2-driver":  "*",
        "behat/mink-sahi-driver":  "*",
        "behat/common-contexts": "*"
}

@everzet
Copy link

everzet commented Jun 19, 2012

@jonathaningram here's a problem:

You're using Symfony2Extension, which assumes that you have proper autoloading and disables Behat's own autoloading (bootstrap/ requiring). So here's what's happening:

  1. Behat tryes to check existense of FeatureContext class (default) with PredefinedClassGuesser and obviously can't
  2. Behat tries another guessers with lower priorities.
  3. There is one defined by MinkExtension, which gets matched and tells Behat to use Behat\MinkExtension\Context\MinkContext as context class.

So, your subcontexts aren't initialized, because your FeatureContext isn't used really. Behat\MinkExtension\Context\MinkContext used instead :)

To fix this, you just need to put your context inside path/namespace, where it will be discoverable by Behat/Symfony2. Also, Symfony2Extension operates on bundles level, so you could just put suite into appropriate bundle. So you have 2 options:

  1. (common one): put your feature suite inside bundle src/PROJECT_NAMESPACE/Bundle/ProjectBundle/Features/. In this case, you'll have context class PROJECT_NAMESPACE\Bundle\ProjectBundle\Features\Context\FeatureContext. And it will be used by Behat automatically when you'll call:

    $> behat src/PROJECT_NAMESPACE/Bundle/ProjectBundle

    or

    $> behat src/PROJECT_NAMESPACE/Bundle/ProjectBundle/Features/specific.feature

    or

    $> behat @SHORT_BUNDLE_NAME

    or

    $> behat @SHORT_BUNDLE_NAME/specific.feature
  2. Another option is to put context class into loadable path with proper namespace (f.e.: PROJECT_NAMESPACE\BehatContext\FeatureContext) and tell Behat about it through config:

    # behat.yml
    default:
        context:
            class: 'PROJECT_NAMESPACE\BehatContext\FeatureContext'

Hope it helps ;)

@jonathaningram
Copy link
Author

@everzet wow that's such a comprehensive reply! Thanks! Hopefully you can transform it into a doc article or cookbook entry.

  1. I suppose it's common for a Symfony2 application to put it in a bundle, however, I am trying to avoid having too much code in a bundle (remember your tweet about difference between Components, Bundles and Bridges) so I might try and go with 2.

Just tried it out and 2. seems to be working, so thanks very much for your time!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment