Behat not autoloading additional classes to a test context - php

Behat version 3.0.12, PHP 5.3.3
I'll describe the problem before showing my setup: I'm creating a small test Behat project, but when I try and create additional classes in other files to pull into my context file, Behat doesn't autoload them. The docs say that anything in features/bootstrap should be autoloaded and available. The specific error is this:
Fatal error: Class 'TestObject' not found in /data/drupal7/sites/behat-test/projects/test-project/features/bootstrap/TestContext.php on line 23
In the version 3 docs, the tutorial defines a class in a new PHP file and brings it in effortlessly. Trying to do the same on my version doesn't work.
I've got a Behat setup like this:
composer.*
projects
vendor
This is a standard result of installing Behat, except there's a new folder where my individual projects have their own folder in project/<project name>. For instance, project/test_project:
behat.yml
features
|-- test.feature
|-- bootstrap
|-- TestContext.php
|-- Test.php
My config file, behat.yml looks like this:
default:
suites:
default:
paths: [ %paths.base%/features ]
bootstrap: [ $paths.features%/bootstrap ]
contexts: [ TestContext ]
The TestContext.php looks like this:
<?php
use Behat\Behat\Tester\Exception\PendingException;
use Behat\Behat\Context\Context;
use Behat\Gherkin\Node\PyStringNode;
use Behat\Gherkin\Node\TableNode;
/**
* Behat context class.
*/
class TestContext implements Context
{
private $test;
public function __construct()
{
$this->test = new TestObject();
}
/**
* #Given I go to the Google homepage
*/
public function iGoToTheGoogleHomepage()
{
throw new PendingException();
}
}
And finally, Test.php
<?php
final class TestObject {
private $price = 0;
public function setPrice($amount) {
$this->price = $amount;
}
public function getPrice() {
return $this->price;
}
}
Any ideas?

Turns out that additional files need to follow the PSR-0 standard - and in the case of this, the TestObject class needed to be in a file with the same name, e.g. TestObject.php

Related

Get config parameters from controller within a custom bundle

I'm trying to get some params from a config yaml file, I'm doing the following:
namespace ExampleVendor\AdminBundle\Controller;
/**
* #Route("/", name="_home")
*/
public function index(ParameterBagInterface $params) {
$menuIcons = $this->getParameter('admin-aside-menu');
dump($menuIcons);
return $this->render('#ExampleVendorAdminBundle/index.html.twig');
}
As you can see is just a dump function that prints the admin-aside-menu parameter, the problem is, this code works when it is in a controller in App\src\Controller, I mean in the "main" application src folder, but when I copy this code and paste it in a controller inside a custom bundle (something like vendor/myVendor/myBundle/src/Controller) I get an error when reloading the page:
Could not resolve argument $params of "ExampleVendor\AdminBundle\Controller\AdminController::index()", maybe you forgot to register the controller as a service or missed tagging it with the "controller.service_arguments"?
I need ParameterBagInterface to get those parameters but I dont know how to "inject" it in my controller.
Okay so it seems like this post says how to fix this issue but, since the controller I need to inject something is in a custom bundle in the vendor folder, the answer doesn't help me at all
Project
|
+--AdminBundle <- My custom bundle, installed via composer as symlink
| |
| +--Controller
| | |
| | +--AdminController.php <- Heres where I want to get my parameter
| |
| +--DependencyInjection
| +--Entity
| +--Resources
| |
| +--config
| |
| +--custom.yaml <- There are my custom params
| +--services.yaml <- Heres where I should register my controller as service?
|
+--assets
|
+--bin
|
+--config
|
+--public
|
+--src
|
+--templates
|
+--vendor <- Heres my admin bundle as symlink
The AdminBundle folder is installer via composer as symlink so I can use it in my project, so knowing this, anyone know how can I inject ParametersBag or the parameter directly into my controller?
This is my custom.yaml that holds the params from my bundle
// AdminBundle/Resources/config/custom.yaml
parameters:
admin-aside-menu:
items:
- icon: 'Home/Chair2'
title: 'Prueba'
- icon: 'Home/Deer'
title: 'Prueba Venado'
This is the configuration class in the dependency injection
// AdminBundle/DependencyInjection/Configuration.php
class Configuration implements ConfigurationInterface {
public function getConfigTreeBuilder() {
$treeBuilder = new TreeBuilder('admin-aside-menu');
$treeBuilder->getRootNode()
->children()
->arrayNode('items')
->children()
->scalarNode('icon')->end()
->scalarNode('title')->end()
->end()
->end()
;
return $treeBuilder;
}
}
and this is the bundle extension
// AdminBundle/DependencyInjection/ExampleVendorAdminExtension .php
class ExampleVendorAdminExtension extends Extension {
/**
* Loads a specific configuration.
*
* #throws \InvalidArgumentException When provided tag is not defined in this extension
*/
public function load(array $configs, ContainerBuilder $container) {
$loader = new YamlFileLoader( $container, new FileLocator(__DIR__.'/../Resources/config') );
$loader->load('custom.yaml');
$loader->load('services.yaml');
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
}
}
I wrote this in my services.yaml to inject my parameter into my controller according to Florian's response
// AdminBundle/Resources/config/services.yaml
services:
admin-bundle.controller.admin-controller:
class: ExampleVendor\AdminBundle\Controller\AdminController
arguments:
- "%admin-aside-menu%"
it seems to work in a way because when I write "%admin-aside-menu%" bad (a typo) an error page says
"Did you mean this: "admin-aside-menu"?"
So I think it is actually loading my param but in my controller I cannot "inject" it
This is the controller:
/**
* #Route(name="admin")
*
* Class AdminController
* #package ExampleVendor\AdminBundle\Controller
*/
class AdminController extends AbstractController {
public function __construct(array $adminAsideMenu) {
dump($adminAsideMenu);
}
}
but when I run this I get this error
The controller for URI "/admin/" is not callable. Controller "ExampleVendor\AdminBundle\Controller\AdminController" has required constructor arguments and does not exist in the container. Did you forget to define the controller as a service?
Building your own bundle is not straightforward.
From the bundle structure you shared with us, I can see that you already have the Dependency injection folder.
This folder should contains two file:
Configuration.php
YourBundleNameExtension.php
The parameter you want to inject in your controller should be in the configuration of your bundle so you have to complete the Configuration.php to add it. (I'm not a pro for that so I let you search by yourself)
Moreover, in order to acces your configuration in your bundle's code, you have to inject the configuration as a parameter with a a prefix for your bundle. You can find an example to see how to do it here : https://github.com/Orbitale/CmsBundle/blob/4.x/DependencyInjection/OrbitaleCmsExtension.php
Now in your Resources/services.yaml you can add you controller as a service:
services:
bundle_name.controller.your_controller:
class: Your\Controller\Namespace
arguments:
- '%bundle_key.your_parameter_name%'
Something like that should work but it's maybe not totally clear. So if you have more questions, I'll try to answer you.
Don't hesitate to check existing bundles as a source of inspiration.
---------------------- EDIT TO ANSWER EDIT 2 ----------------------
From what I see, your bundle configuration key is "admin-aside-menu"? Maybe it should be "admin_aside_menu" instead (to match convention). Anyway :
Yeah you almost there but there is missing something. You can't directly define parameters in config from your bundle. Instead, when you will use your bundle from your application you will have a file like this in /config/packages/admin-aside-menu.yaml :
admin-aside-menu:
items:
- icon: 'Home/Chair2'
title: 'Prueba'
- icon: 'Home/Deer'
title: 'Prueba Venado'
This is your bundle configuration for your current usage and this should match the format you define in your AdminBundle/DependencyInjection/Configuration.php file. (I can't help you with that because it's not something I often do).
You can now remove totally the file AdminBundle/Resources/config/custom.yaml because the configuration is in your application.
Then in your extension, you can get this configuration to inject it in your the application parameters with a prefix for your bundle. If I modify your code, it should be something like this :
// AdminBundle/DependencyInjection/ExampleVendorAdminExtension .php
class ExampleVendorAdminExtension extends Extension {
/**
* Loads a specific configuration.
*
* #throws \InvalidArgumentException When provided tag is not defined in this extension
*/
public function load(array $configs, ContainerBuilder $container) {
$loader = new YamlFileLoader( $container, new FileLocator(__DIR__.'/../Resources/config') );
// $loader->load('custom.yaml'); not needed anymore
$loader->load('services.yaml');
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
// This part inject your config in parameters
foreach ($config as $key => $value) {
$container->setParameter('admin-aside-menu.'.$key, $value);
}
}
}
Now your config parameters are set!
Last step, inject it in your controller :
// AdminBundle/Resources/config/services.yaml
services:
admin-bundle.controller.admin-controller:
class: ExampleVendor\AdminBundle\Controller\AdminController
arguments:
- "%admin-aside-menu.items%"
Is this ok ?
Open service.yaml
then put the class name and choose an id to fetch it with autowiring
services:
ExampleVendor\AdminBundle\Controller = '#adminbundle_thenameyouchoose'
You should never write code in vendor packages due to any coding standards and practices. vendor is not a folder that you should push into the git repository, one of the reasons is the excess size of the static libraries that does not practically belong to your project, also this practice would make a total mess when you would try to update your composer dependencies. You should keep it clean and add vendor into the .gitignore. Symfony provides good support for overriding services check this.

Symfony 4 : Override public services in container

I am migrating our project to Symfony 4. In my test suites, we used PHPUnit for functional tests (I mean, we call endpoints and we check result). Often, we mock services to check different steps.
Since I migrated to Symfony 4, I am facing this issue: Symfony\Component\DependencyInjection\Exception\InvalidArgumentException: The "my.service" service is already initialized, you cannot replace it.
when we redefine it like this : static::$container->set("my.service", $mock);
Only for tests, how can I fix this issue?
Thank you
Replacing is deprecated since Symfony 3.3. Instead of replacing service you should try using aliases.
http://symfony.com/doc/current/service_container/alias_private.html
Also, you can try this approach:
$this->container->getDefinition('user.user_service')->setSynthetic(true);
before doing $container->set()
Replace Symfony service in tests for php 7.2
Finally, I found a solution. Maybe not the best, but, it's working:
I created another test container class and I override the services property using Reflection:
<?php
namespace My\Bundle\Test;
use Symfony\Bundle\FrameworkBundle\Test\TestContainer as BaseTestContainer;
class TestContainer extends BaseTestContainer
{
private $publicContainer;
public function set($id, $service)
{
$r = new \ReflectionObject($this->publicContainer);
$p = $r->getProperty('services');
$p->setAccessible(true);
$services = $p->getValue($this->publicContainer);
$services[$id] = $service;
$p->setValue($this->publicContainer, $services);
}
public function setPublicContainer($container)
{
$this->publicContainer = $container;
}
Kernel.php :
<?php
namespace App;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
class Kernel extends BaseKernel
{
use MicroKernelTrait;
public function getOriginalContainer()
{
if(!$this->container) {
parent::boot();
}
/** #var Container $container */
return $this->container;
}
public function getContainer()
{
if ($this->environment == 'prod') {
return parent::getContainer();
}
/** #var Container $container */
$container = $this->getOriginalContainer();
$testContainer = $container->get('my.test.service_container');
$testContainer->setPublicContainer($container);
return $testContainer;
}
It's really ugly, but it's working.
I've got a couple of tests like this (the real code performs some actions and returns a result, the test-version just returns false for every answer).
If you create and use a custom config for each environment (eg: a services_test.yaml, or in Symfony4 probably tests/services.yaml), and first have it include dev/services.yaml, but then override the service you want, the last definition will be used.
app/config/services_test.yml:
imports:
- { resource: services.yml }
App\BotDetector\BotDetectable: '#App\BotDetector\BotDetectorNeverBot'
# in the top-level 'live/prod' config this would be
# App\BotDetector\BotDetectable: '#App\BotDetector\BotDetector'
Here, I'm using an Interface as a service-name, but it will do the same with '#service.name' style as well.
As I understood it, it means that class X was already injected(because of some other dependency) somewhere before your code tries to overwrite it with self::$container->set(X:class, $someMock).
If you on Symfony 3.4 and below you can ovverride services in container regardless it privite or public. Only deprication notice will be emmited, with content similar to error message from question.
On Symfony 4.0 error from the question was thown.
But on Symfony 4.1 and above you can lean on special "test" container. To learn how to use it consider follow next links:
https://symfony.com/blog/new-in-symfony-4-1-simpler-service-testing
https://dev.to/nikolastojilj12/symfony-5-mocking-private-autowired-services-in-controller-functional-tests-24j4

Name already in use fatal error using composer's autoload in PHPUnit

Using PSR-4 autoloading with Composer, when I try to test this class:
namespace User;
use User\Contracts\UserId;
use User\Contracts\User as UserContract;
class User implements UserContract
{
private $id;
public function __construct(UserId $id)
{
$this->id = $id;
}
public function getId()
{
return $this->id;
}
}
using PHPUnit:
use User\Contracts\UserId;
class UserTest extends \PHPUnit_Framework_TestCase
{
public function test_the_identifier_can_be_used_as_string()
{
$identifier = m::mock(UserId::class);
$identifier->shouldReceive('__toString')->once()->andReturn('foo');
$user = new User($identifier);
$this->assertSame('foo', (string) $user->getId());
}
}
I receive this error in the console
PHP Fatal error: Cannot use User\Contracts\UserId as UserId because the name is already in use in /src/User/User.php on line 5
This is the file/folder structure:
src
`-- User
|-- Contracts
| |-- User.php
| `-- UserId.php
|-- User.php
`-- UserId.php
tests
`-- User
|-- UserIdTest.php
`-- UserTest.php
I've done a lot of searches about this problems, but I've not found any solution about that.
PHP Version: 5.6.13-1+deb.sury.org~trusty+3
PHPUnit version: 5.0.3
OS: Ubuntu 14.04.3 LTS
How can I solve this problem?
You cannot import a class into a namespace that is already declared inside it with the same alias.
You have \User\UserId and want to import \User\Contracts\UserId into the \User namespace. This would make the shortcut UserId ambigous.
http://php.net/manual/en/language.namespaces.importing.php#117334
You could either use an alias when importing, or directly use a relative path:
namespace User;
class User implements Contracts\User
{
private $id;
public function __construct(Contracts\UserId $id) {}
}
Update 2018-03-20:
There is a bug report https://bugs.php.net/bug.php?id=66773 that complains about PHP triggering this error if used without opcode cache, but not otherwise. The reason is that with opcache the compilation is done per file, and it is a reasonable expectation that the file's contents ONLY are considered. However it seems that the error is that existing class definitions from previously loaded files are in the way when importing "conflicting" classes.
It was fixed in the correct way for PHP 7.0.13: Every single file only accounts for itself, and if you desire to import a class and use it by it's shorthand name, you may do so irrespective of any other classes that may exist in the namespace. You simply loose access to these classes - which is irrelevant because your code doesn't use them in the first place. If you'd wanted that changed, you'd have to change the imports.
As the opcache is usually disabled on the command line, you were likely to trigger this bug when using PHPUnit.
Try the following:
use User\Contracts\UserId as UserIdContract;
probably you're getting a naming conflict because you're doing
use User\Contracts\UserId;
but you also have UserId in the same namespace of the User class.
So...
namespace User;
use User\Contracts\UserId as UserIdContract;
use User\Contracts\User as UserContract;
class User implements UserContract
{
private $id;
public function __construct(UserIdContract $id)
{
$this->id = $id;
}
public function getId()
{
return $this->id;
}
}
Hope it helps!

How to structure a modular app in Laravel 5?

I would like to divide my application in modules. For instance, there would be a "core" modules that contains the basic login functionality, app layout/formatting (CSS etc), user management and a diary.
Later on I may create other modules like a contact manager that can easily be added or removed from the application.
There would be some logic in the apps navigation for determining which modules are present and to show/hide the links to them.
How can I do this in terms of directory structure, namespaces and anything else that's needed?
I am looking at creolab/laravel-modules but it states that it is for Laravel 4. Can I still use it with 5 in exactly the same way?
The documentation says to place models, controllers and views within each module directory, but how does this work with routes? Ideally I would like each module to have its own routes.php file. How will all of this work with the stuff in the http and the resources directory?
I was thinking of something like this:
But I have no idea how I would get it to work.
I have just tried the tutorial here:
http://creolab.hr/2013/05/modules-in-laravel-4/
With no extra libraries etc, just pure Laravel 5.
I seem to have hit a brick wall with an error message:
FatalErrorException in ServiceProvider.php line 16:
Call to undefined method Illuminate\Config\Repository::package()
Regarding the following:
<?php namespace App\Modules;
abstract class ServiceProvider extends \Illuminate\Support\ServiceProvider
{
public function boot()
{
if ($module = $this->getModule(func_get_args())) {
$this->package('app/' . $module, $module, app_path() . '/modules/' . $module);
}
}
public function register()
{
if ($module = $this->getModule(func_get_args())) {
$this->app['config']->package('app/' . $module, app_path() . '/modules/' . $module . '/config');
// Add routes
$routes = app_path() . '/modules/' . $module . '/routes.php';
if (file_exists($routes)) require $routes;
}
}
public function getModule($args)
{
$module = (isset($args[0]) and is_string($args[0])) ? $args[0] : null;
return $module;
}
}
What is causing this and how can I fix it?
Got my head around this a bit more now. Got my package/module routes and views working which is great:
abstract class ServiceProvider extends \Illuminate\Support\ServiceProvider
{
public function boot()
{
if ($module = $this->getModule(func_get_args())) {
include __DIR__.'/'.$module.'/routes.php';
}
$this->loadViewsFrom(__DIR__.'/'.$module.'/Views', 'core');
}
public function register()
{
if ($module = $this->getModule(func_get_args())) {
}
}
public function getModule($args)
{
$module = (isset($args[0]) and is_string($args[0])) ? $args[0] : null;
return $module;
}
}
I have one last question, how would I load all my controllers from inside my package, much like how the loadViewsFrom() method works?
I seem to have figured it all out.
I'll post it here in case it helps other beginners, it was just about getting the namespaces right.
In my composer.json I have:
...
"autoload": {
"classmap": [
"database",
"app/Modules"
],
"psr-4": {
"App\\": "app/",
"Modules\\": "Modules/"
}
}
My directory and files ended up like this:
I got my Core module router.php to work by wrapping my controllers for that module in a group specifying the namespace:
Route::group(array('namespace' => 'Modules\Core'), function() {
Route::get('/test', ['uses' => 'TestController#index']);
});
I imagine when I come to doing my models for the package it will be a similar case of getting the namespaces right.
Thanks for all your help and patience!
Solution:
Step1: Create Folder “Modules” inside “app/”
Step2: In Modules folder create your Module (Module1( suppose admin Module))
Inside admin module : create the following folder
1. Controllers (here will your controller files)
2. Views (here will your View files)
3. Models (here will your Model files)
4. routes.php (here will your route code in this file)
Similarly, you can create multiple modules
Module2( suppose API )
-Controllers
-Views
-Models
-routes.php
Step3 : Create ModulesServiceProvider.php inside “Modules/” Folder
Step4 : Paste following code inside ModulesServiceProvider.php
<?php
namespace App\Modules;
/**
* ServiceProvider
*
* The service provider for the modules. After being registered
* it will make sure that each of the modules are properly loaded
* i.e. with their routes, views etc.
*
* #author kundan Roy <query#programmerlab.com>
* #package App\Modules
*/
use Illuminate\Support\Facades\Route;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
class ModulesServiceProvider extends ServiceProvider {
/**
* Will make sure that the required modules have been fully loaded
*
* #return void routeModule
*/
public function boot() {
// For each of the registered modules, include their routes and Views
$modules=config("module.modules");
while (list(,$module)=each($modules)) {
// Load the routes for each of the modules
if (file_exists(DIR.'/'.$module.'/routes.php')) {
include DIR.'/'.$module.'/routes.php';
}
if (is_dir(DIR.'/'.$module.'/Views')) {
$this->loadViewsFrom(DIR.'/'.$module.'/Views',$module);
}
}
}
public function register() { }
}
Step5 : Add following line inside ‘config/app.php’ file
App\Modules\ModulesServiceProvider::class,
Step6 : Create module.php file inside ‘config’ folder
Step7 : Add following code inside module.php (path =>
“config/module.php”)
<?php
return [
'modules'=>[
'admin',
'web',
'api'
]
];
Note : You can add your module name whichever you have created. Here there are modules.
Step8 : Run this command
composer dump-autoload
A little late, but if you want to use modules in your future projects, i've written a module generator. It generates modules via php artisan make:module name You can also just drop some modules in the app/Modules folder and they are ready to use/work.
Take a look. Save some time ;)
l5-modular
You can also use pingpong-labs
documentations Here.
Here is an example.
You can just install and check the process.
Note: I am not advertising. Just checked that cms built on Laravel with module support. So thought that might be helpful for you and others.
Kundan roy: I liked your solution but I copied your code from StackOverflow, I had to change the quotes and semi-quotes to get it working - I think SOF replace these. Also changed Dir for base_path() to be more inline with Laravel's (new) format.
namespace App\Modules;
/**
* ServiceProvider
*
* The service provider for the modules. After being registered
* it will make sure that each of the modules are properly loaded
* i.e. with their routes, views etc.
*
* #author kundan Roy <query#programmerlab.com>
* #package App\Modules
*/
use Illuminate\Support\Facades\Route;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
class ModulesServiceProvider extends ServiceProvider
{
/**
* Will make sure that the required modules have been fully loaded
* #return void routeModule
*/
public function boot()
{
// For each of the registered modules, include their routes and Views
$modules = config("module.modules");
while (list(,$module) = each($modules)) {
// Load the routes for each of the modules
if(file_exists(base_path('app/Modules/'.$module.'/routes.php'))) {
include base_path('app/Modules/'.$module.'/routes.php');
}
// Load the views
if(is_dir(base_path('app/Modules/'.$module.'/Views'))) {
$this->loadViewsFrom(base_path('app/Modules/'.$module.'/Views'), $module);
}
}
}
public function register() {}
}
pingpong/modules is a laravel package which created to manage your large laravel app using modules. Module is like a laravel package for easy structure, it have some views, controllers or models.
It's working in both Laravel 4 and Laravel 5.
To install through composer, simply put the following in your composer.json file:
{
"require": {
"pingpong/modules": "~2.1"
}
}
And then run composer install to fetch the package.
To create a new module you can simply run :
php artisan module:make <module-name>
- Required. The name of module will be created.
Create a new module
php artisan module:make Blog
Create multiple modules
php artisan module:make Blog User Auth
for more visit: https://github.com/pingpong-labs/modules

Behat - Implement Step definitions

I am having difficulties in setting Behat framework correctly. The test runs fine, however the step definitions are not being picked up from the FeatureContext file. Have tried out answers from other questions with no luck. The behat.yml file is currently stored in the root of the project:
default:
paths:
features: 'bin/features'
bootstrap: 'bin/features/bootstrap'
context:
class: 'FeatureContext'
extensions:
Behat\MinkExtension\Extension:
goutte: ~
selenium2: ~
In the root of the project I have a bin folder which contains the standard behat files: behat.bat, webunit.bat etc. Within the bin folder I have the features folder which contains the file search.feature:
Feature: Search
In order to find a word
As a website user
I need to be able to search for a word
#javascript
Scenario: Searching for a word that does exist
Given I am on "http://drupalcamp.mx/search/"
When I fill in "Escriba las palabras clave" with "behat, mink"
And I press "Buscar"
Then I should see "Behavior Driven Development"
And I follow "Behavior Driven Development"
And I wait for 5 seconds
Within the features folder I there is a bootstrap folder which contains the file "FeatureContext"
namespace features;
use Behat\Behat\Context\ClosuredContextInterface,
Behat\Behat\Context\TranslatedContextInterface,
Behat\Behat\Context\BehatContext,
Behat\Behat\Exception\PendingException;
use Behat\Gherkin\Node\PyStringNode,
Behat\Gherkin\Node\TableNode;
use Behat\MinkExtension\Context\MinkContext;
/**
* Features context.
*/
class FeatureContext extends MinkContext
{
/**
* Initializes context.
* Every scenario gets it's own context object.
*
* #param array $parameters context parameters (set them up through behat.yml)
*/
public function __construct(array $parameters)
{
// Initialize your context here
}
/**
* #Given /^I wait for (\d+) seconds$/
*/
public function iWaitForSeconds($seconds)
{
$this->getSession()->wait($seconds*1000);
}
When I run "behat" from the root directory of the project in CL, it fires the test in the browser, passes all but fails to recognise the step definition, it states "You can implement step definitions for undefined steps with these snippets:" which then it gives an example.
You need to configure the autoloader to load classes from your custom bootstrap folder.
If you're using composer, here's an example of how it could be done:
"autoload": {
"psr-0": { "": ["src/", "bin/features/bootstrap/"]}
}
Note: bin folder is a really odd location to put your features or context files.
Related question with an answer: Behat + Symfony, Custom definitions are not loaded (actually, might be a duplicate).

Categories