I have my features under test/behat/ rather than features/ due to project conventions. To point Behat at the correct path, I have a config/behat.yml with the following content:
default:
paths:
features: '%%BEHAT_BASE_PATH%%'
bootstrap: '%behat.paths.features%/bootstrap'
and I invoke Behat with the following command:
bin/behat -c config/behat.yml test/behat/
This works in Behat 2.3.5, but in 2.4.0 I get a "Context class not found" error.
use %behat.paths.base% instead of %%BEHAT_BASE_PATH%%.
%behat.paths.base% directs to either:
behat.yml (or custom config) directory path, if config file exists and loadedThere's no magic %%...%% directives in Behat anymore. Only:
behat.paths.base - described abovebehat.paths.features - features path (defaults to features)behat.paths.bootstrap - bootstraps path (defaults to %behat.paths.features%/bootstrap)Also, all paths are relative from behat.paths.base by default, meaning, that you can use just features instead of %behat.paths.base%/features.
Ah, ok. Thanks.
So just to clarify: there's no means now of referencing the features directory passed via commandline in the config file, so can't add paths relative to it?
And also no way of loading features from a non-standard directory without using behat.yml, since bootstrap isn't found by default in any passed directory?
e.g. 'behat foo', where foo/bootstrap/FeatureContext.php exists, still gives the 'Context not found' error?
Yep. Just no magic happens now. Custom directories are still supported, but you need to specify them explicitly in config:
# behat.yml
default:
paths:
features: 'foo'
bootstrap: 'foo/bootstrap'
Paths in config are relative from config path. So, just put behat.yml whenever you want and call Behat with --config:
$> behat --config=/usr/local/etc/global_behat.yml
Thanks for the clarification. The challenge comes when you have a number of features spread across different paths (e.g. modules). It makes a single global config with shared profiles for the entire suite somewhat difficult to use. Instead, it forces copying of behat.yml into each module somewhere, which then need to be kept in sync in some way - unless I've not understood this correctly?
It's a shame that the paths can't be overridden by commandline options; this would make running a suite programatically a tiny bit easier, I think.
Why not using profiles? Each module have it's own profile and shortname:
# behat.yml
# project suite:
# features/
# features/bootstrap
default:
paths:
features: 'features'
# module1 suite:
# modules/module_1/features/
# modules/module_1/features/bootstrap
module1:
paths:
features: 'modules/module_1/features'
# module2 suite:
# modules/module_2/features/
# modules/module_2/bootstrap/
module2:
paths:
features: 'modules/module_2/features'
bootstrap: 'modules/module_2/bootstrap'
Then just run them independently:
$> behat
$> behat -p=module1
$> behat -p=module2
The problem with guessing path from argument is that argument could be anything. Now any extension could extend Behat and provide support for it's custom loaders. For example, Symfony2Extension adds support for bundle-related paths:
$> behat @SomeBundleName/login.feature
You just can't get path from it before loading suite.
Thanks, but a profile for each module means that these need to be known in advance and behat.yml edited manually, rather than being able to load features dynamically. I'll look into writing a custom loader, and check out the Symfony extension.
@zeebinz maybe it would be easier to create specific extension for your configuration, with custom Context\ClassGuesser and custom Gherkin\Loader. This way, you'll be able to autoload everything in your suite-specific way.
Thanks everzet, that sounds like a good solution, now to dig a bit deeper into the code. :)
Any progress on the extention part?
Most helpful comment
use
%behat.paths.base%instead of%%BEHAT_BASE_PATH%%.%behat.paths.base%directs to either:behat.yml(or custom config) directory path, if config file exists and loadedThere's no magic
%%...%%directives in Behat anymore. Only:behat.paths.base- described abovebehat.paths.features- features path (defaults tofeatures)behat.paths.bootstrap- bootstraps path (defaults to%behat.paths.features%/bootstrap)Also, all paths are relative from
behat.paths.baseby default, meaning, that you can use justfeaturesinstead of%behat.paths.base%/features.