As automation frameworks grow, one problem appears in almost every Cucumber project:
How do we share data between step definitions?
Most teams end up building a custom ScenarioContext using a
Map<String, Object>:
context.put("response", response);
Response response =
(Response) context.get("response");
While this works, it introduces several issues:
Magic string keys
Manual casting
Runtime ClassCastExceptions
Duplicate implementations across projects
Boilerplate code that every framework seems to rewrite
After implementing the same solution multiple times across different projects, I decided to build an open-source library that provides a reusable and type-safe alternative.
Introducing cucumber-scenario-context
GitHub Repository:
https://github.com/sap7deb/cucumber-scenario-context
The library provides:
✅ Type-safe context storage
✅ Cucumber integration
✅ PicoContainer support
✅ Scenario lifecycle management
✅ Cleanup handlers
✅ Framework-independent core module
Traditional Approach
context.put("user", user);
User user =
(User) context.get("user");
Problems:
String-based keys
Casting everywhere
Runtime failures
Type-Safe Approach
Define a key once:
public static final Key<Response> RESPONSE =
Key.key("response", Response.class);
Store:
context.add(RESPONSE, response);
Retrieve:
Response response =
context.get(RESPONSE);
No casting.
No string lookups.
Compile-time type safety.
Real-World Example
Imagine an API test that creates a user and validates the response in a later step.
Create User
@When("a user is created")
public void createUser() {
Response response =
userApi.createUser();
context.add(
ContextKeys.CREATE_USER_RESPONSE,
response
);
}
Validate Response
@Then("user creation should succeed")
public void validateResponse() {
Response response =
context.get(
ContextKeys.CREATE_USER_RESPONSE
);
assertEquals(
201,
response.statusCode()
);
}
The response object is shared safely across step definitions without casting or string-based retrieval.
Core Operations
Define a Key
public static final Key<String> USERNAME =
Key.key("username", String.class);
Add
context.add(USERNAME, "john.doe");
Retrieve
String username =
context.get(USERNAME);
Remove
context.remove(USERNAME);
Clear
context.clear();
Why Use It?
| Traditional Context | cucumber-scenario-context |
| --------------------------------- | ------------------------- |
| String keys | Type-safe keys |
| Manual casting | No casting |
| Runtime type errors | Compile-time safety |
| Custom implementation per project | Reusable library |
| Boilerplate code | Minimal setup |
| Harder to maintain | Consistent design |
Add the dependency to your project and inject ScenarioContext into your step definitions.
The library works particularly well with:
Cucumber JVM
PicoContainer
REST Assured
Selenium
Playwright
Any Java-based automation framework
Learn More
📖 Medium Article:
⭐ GitHub Repository:
https://github.com/sap7deb/cucumber-scenario-context
I'd love to hear feedback from the automation community and learn how others are handling scenario state management in their Cucumber frameworks. Happy testing! 🚀
Top comments (0)