1. Problems
A BDD automation framework typically consists of Feature Files, Step Definition classes or Hook class, and other classes (that provides context or service). Feature Files define the scenarios in a human-readable format using Gherkin syntax (Given-When-Then). Step Definitions map the Gherkin steps to executable code. Usually, Step Definitions called Page Objects encapsulate the interactions with specific pages of the application for UI testing, or API services for API testing. This type of framework is facing many following problems:
Sharing state between scenarios
Scenarios must be independent of one other so it is important that state is NOT shared between scenarios. The problem is that accidentally leaking state from one scenario into others makes your scenarios brittle and also difficult to run in isolation in parallel execution. To prevent accidentally leaking state between scenarios, we should avoid using global or static variables. It is unfortunately very easy for information to leak from one scenario to another.
Sharing state between steps
A scenario in Gherkin is created by steps. Each step depends and uses data on previous steps. This means that we must be able to share state/data between steps. Moreover, Step Definition Class is dependent on the another classes. It’s dependent because those classes store some context or data we need during test scenario. In a basic setup, the dependent class (Step Definition Class) will create instances of the classes that it’s dependent on. So we have to create a new instance every time to Step Definition Classes. The next problem you will have to solve is to handle a shared state between the steps in the simple and isolated way.
2. What is Dependency Injector
The challenge to the above problems is how do we create the first AND ONLY instance of a context class and then share it between all our step definition classes. We need a clever way to hand off the creation and management of Context class to another entity. That entity is our Context Injector that is responsible for creating the instance of the ‘Context’ class and ‘injecting’ the Context class into any other classes that might need it. It is also recreated every time a new scenario is executed. Each scenario has a fresh world and leakage between scenarios through this object is unlikely.
This injector class delivers 4 things:
- CREATE: when an instance of the class doesn’t exist the Injector creates that first instance.
- MAINTAIN: when one dependent class (e.g. a step defintion class) has finished with the Context class and we want to keep one insance in play (ie. not dispose of it).
- PROVIDE/INJECT: to provide the ‘in play’ instance of the context class to any other client/class when it needs it. MANY dependent classes can have the ONE instance of the Context class injected.
- DISPOSE: to dispose of the context class instance when, AND only when, we’re ready.

3. How to implement
Implement Dependency Injector with the following steps:
- Based on BDD framework (e.g. Cucumber), add the inbuilt libraries that provide the Injector capability (e.g. PicoContainer).
- Create a TestContext class that is responsible for initializing instances that Step Definition classes are using. e.g;
- PageObjectManager
- WebDriverManager
- scenarioContext
- APIServices
- Then dependency injection can be done in many ways.
- Constructor Injection
- Parameter Injection

