symfonyautoloadbehatpsr-4psr-0

Behat 3 + Symfony 3 Context with namespace doesn't work, when without works


I have the following catalogs structure:

composer.json
behat.yml
src
|--AppBundle
   |--Features
      |--example.feature
      |--Context
         |--FeatureContext.php

And the following behat.yml

default:
  autoload:
    '': 'src/AppBundle/Features/Context'
  suites:
    default:
      paths: ['src/AppBundle/Features']
      contexts:
        - FeatureContext:
          session: '@session'
    # and extensions standard for Symphony

And FeatureContext.php contains

<?php

//namespace AppBundle\Features\Context;

use Behat\Behat\Context\Context;
use Behat\MinkExtension\Context\MinkContext;

/**
 * Defines application features from the specific context.
 */
class FeatureContext extends MinkContext implements Context
{   ...   }

There is commented namespace. When I run behat, now context is found correctly. When I uncomment namespace there occurs error:

[Behat\Behat\Context\Exception\ContextNotFoundException]
FeatureContext context class not found and can not be used.

How to make it working when namespace in FeatureContext.php is uncommented? I do not know much about PSR-0 and PSR-4, but if problem can be connected with this i append fragment of composer.json.

"autoload": {
    "psr-4": {
        "": "src/"
    },
    "classmap": [
        "app/AppKernel.php",
        "app/AppCache.php"
    ]
},
"autoload-dev": {
    "psr-4": {
        "Tests\\": "tests/"
    }
},

I looking for best practices of coding, so if I am doing something in bad way I vote up for appropriate suggestion.


Solution

  • Have a look at the example below. Full example is here: http://www.inanzzz.com/index.php/post/l41o/testing-a-basic-auth-symfony-api-with-behat3 You can also find more behat examples here: http://www.inanzzz.com/index.php/posts/behat

    Note 1: You can access the session in context files directly so no need to inject it. You might need to use implements KernelAwareContext or implements KernelAwareInterface or implements ContainerAwareInterface. Just check the blog posts above.

    Note 2: You don't need autoload-dev in composer.sjon at all. Get rid of it.

    composer.json

    Note: Use new versions!

    {
        "require-dev": {
            "behat/behat": "3.0.15",
            "behat/symfony2-extension": "2.1.0",
            "behat/mink": "1.7.0",
            "behat/mink-extension": "2.1.0",
            "behat/mink-browserkit-driver": "1.3.0"
        },
    }
    

    behat.yml

    default:
        extensions:
            Behat\Symfony2Extension: ~
            Behat\MinkExtension:
                base_url: http://your_local_app_domain.com/app_test.php/
                sessions:
                    symfony2:
                        symfony2: ~
        suites:
            api:
                type: symfony_bundle
                bundle: ApplicationApiBundle
                mink_session: symfony2
                contexts:
                    - Application\ApiBundle\Features\Context\FeatureContext:
                        param: 'whatever'
    

    FeatureContext.php

    namespace Application\ApiBundle\Features\Context;
    
    use Behat\MinkExtension\Context\MinkContext;
    
    class FeatureContext extends MinkContext
    {
        private $param;
    
        public function __construct($param)
        {
            $this->param = $param;
        }
    
        ......
    }
    

    Test

    $ bin/behat --suite=api @ApplicationApiBundle/YourFeature.feature