Behat 3.0.4 parameter definition under Contexts

Created on 1 May 2014  路  15Comments  路  Source: Behat/Behat

Hi,

Since updating from a beta version of Behat v3 to v3.0.4, I've been having issues with specifying parameters under my Contexts within the behat.yml file.

The context.feature example shows the following format:

    Given a file named "behat.yml" with:
      """
      default:
        suites:
          default:
            contexts:
              - FeatureContext:
                  parameter1: val_one
      """

My behat.yml is as follows:

default:
  autoload:
    '': %paths.base%/library
  suites:
    default:
      contexts:
        - FeatureContext:
            url:
              google:    'https://www.google.co.uk'
              bbc:         'https://www.bbc.co.uk'
            key2:         'val2'

This fails as my FeatureContext is passed NULL for the parameters. If I wrap all my parameters within FeatureContext under a 'parameters' key, then the above is loaded in successfully.

Please could you let me know the correct syntax to use for passing parameters through via the config file?

Most helpful comment

This was the best place I found on the whole internet that explained how to pass params to context contructor. If its documented on docs.behat.org, I could not find it. Thanks.

All 15 comments

Just to add:
I've run the context.feature file and it passes successfully, however when trying the same and creating an identical behat.yml as specified within the test, I get NULL parameters.

Sorry for that.

That's weird

Are you sure that you have 4 spaces after - FeatureContext::

        - FeatureContext:
            url:

instead of two?

Also. Are you sure that you're not using tabs in place of 4 spaces?

Hey,
I've just checked and I am using spaces rather than tabs, also there are 4 spaces for the url indented inwards.

And the last one - are your context arguments actually called $url and $key2 ???

I think I know what went wrong there. Correct me if I'm wrong, but your context constructor looks like that, right?:

<?php

public function __construct($parameters)
{
    // ...
}

If not - ignore further reading and we'll try to debug further. But if I am right, continue reading, I'll explain what happens in details.

Passing context constructor arguments in v3

$parameters made sense in v2, because we were passing all arguments together as one value. In v3 however, we have much more care in trying to make context classes as much POPO (Plain Old PHP Object) as possible. In v3 we have much better way to instantiate our context classes :)

Ordered arguments

This includes the fact that now we allow to pass individual arguments to your constructor by order:

default:
  suites:
    default:
      contexts:
        - FeatureContext:
            - [ 'http://url1', 'http://url2' ]
            - 'ssh_key'
<?php

public function __construct($urls, $sshKey)
{
    // ...
}

First parameter in behat.yml becomes first argument to your constructor.

Named arguments

In addition to ordered arguments, we also allow passing arguments by their name. Like that:

default:
  suites:
    default:
      contexts:
        - FeatureContext:
            ssh: 'ssh_key'
            urls: [ 'http://url1', 'http://url2' ]
<?php

public function __construct($urls, $ssh)
{
    // ...
}

Notice that order in case of named arguments is unimportant.

Your case

Now. What happens in case of this behat.yml:

default:
  suites:
    default:
      contexts:
        - FeatureContext:
            ssh: 'ssh_key'
            urls: [ 'http://url1', 'http://url2' ]

and this context:

<?php

public function __construct($parameters)
{
    // ...
}

? Behat tries to find parameters value in the list of your context parameters, can't find it and assigns null. That's the same reason why it works when you group arguments under parameters ;)

Aha that's perfect, thanks for clearing this up :D
In my case I will actually need to use '$parameters' within my Construct due to some abstraction I've got and multiple testing suites passing through different parameters, but that's no problem.

This issue can be closed :) Thanks!

Glad to help. Sorry for absence of docs for now. They should've fixed this faster :( Working on them in the evenings after work. Expecting to push them this week.

No worries, thanks for the help :)

But how do I nest parameters when I have FeatureContext class path defined? I am using Behat 3.0.15

default:
    suites:
        default:
            contexts: [Blah\Tests\FeatureContext]

I can't find this documented anywhere.

Well, see the comment above giving the answer, where FeatureContext is the fully qualified class name of the context class. It works the same when the class is namespaced (except quoting the class name with single quotes may be needed to have a valid Yaml syntax because of the backslash, but I'm not even sure it is needed)

Ah, I see, I somehow thought FeatureContext was reserved key name, not a class name. Thanks.

This was the best place I found on the whole internet that explained how to pass params to context contructor. If its documented on docs.behat.org, I could not find it. Thanks.

Was this page helpful?
0 / 5 - 0 ratings