Fragments
Fragments are reusable scenario steps that can be included in multiple scenarios. They help reduce duplication and improve maintainability of your test suites.
Creating Fragments
Fragment files use the .fragment extension and are placed in the
src/test/resources/berrycrush/fragments/ directory by default.
berrycrush/fragments/auth.fragment:
# Authentication Fragment
# Reusable authentication steps for protected endpoints
fragment: authenticate
given I have valid credentials
call using auth ^login
body: {"username": "test", "password": "test"}
extract $.token => authToken
then authentication is successful
assert status 200
fragment: logout
when I log out
call using auth ^logout
then the session is terminated
assert status 200
Fragment Structure
Each fragment starts with fragment: <name> followed by indented steps:
fragment: <fragment-name>
<step-type> <description>
<actions>
<step-type> <description>
<actions>
Using Fragments
Include fragments in your scenarios using the include directive:
scenarios/list-pets.scenario:
scenario: Authenticated list pets
given I authenticate first
include authenticate
when I request the list of pets
call ^listPets
then I get a successful response
assert status 200
The steps from the authenticate fragment are expanded inline during execution.
Fragment Discovery
BerryCrush discovers fragment files using patterns specified in the
@BerryCrushScenarios annotation.
Default Discovery
By default, BerryCrush searches for fragment files matching the pattern
berrycrush/fragments/*.fragment:
@BerryCrushScenarios(locations = ["berrycrush/scenarios/*.scenario"])
// fragments = ["berrycrush/fragments/*.fragment"] is the default
class MyApiTest
Custom Fragment Locations
You can specify custom fragment locations using the fragments property:
@BerryCrushScenarios(
locations = ["scenarios/*.scenario"],
fragments = ["shared/fragments/*.fragment", "auth/*.fragment"]
)
class MyApiTest
The fragments property accepts an array of glob patterns, allowing you to:
Search multiple directories
Use wildcard patterns (
*,**)Specify exact file paths
Examples:
// Single directory
fragments = ["my-fragments/*.fragment"]
// Multiple directories
fragments = ["auth/*.fragment", "common/*.fragment", "api/*.fragment"]
// Recursive search
fragments = ["**/*.fragment"]
// Specific files
fragments = ["fragments/auth.fragment", "fragments/setup.fragment"]
Directory Structure
Typical project structure with custom fragment locations:
src/test/resources/
├── petstore.yaml
├── auth/
│ └── auth.fragment
├── common/
│ └── setup.fragment
└── scenarios/
├── pet-crud.scenario
└── user-api.scenario
With annotation:
@BerryCrushScenarios(
locations = ["scenarios/*.scenario"],
fragments = ["auth/*.fragment", "common/*.fragment"]
)
class MyApiTest
Variables in Fragments
Fragments can extract values that become available in the calling scenario:
fragment: authenticate
given I have valid credentials
call using auth ^login
body: {"username": "test", "password": "test"}
extract $.token => authToken
The authToken variable is now available in the scenario that included this fragment:
scenario: Access protected resource
given I am authenticated
include authenticate
when I access the protected endpoint
call ^getSecretData
header_Authorization: Bearer {{authToken}}
then I get the data
assert status 200
Multi-Spec in Fragments
Fragments can use the using keyword to call operations from named specs:
fragment: admin-login
given I have admin credentials
call using auth ^login
body: {"username": "admin", "password": "admin123"}
extract $.token => adminToken
then admin authentication is successful
assert status 200
Example: Complete Test Suite
Directory structure:
src/test/resources/
├── petstore.yaml
├── auth.yaml
├── fragments/
│ └── auth.fragment
└── scenarios/
├── 01-setup.scenario
├── pet-crud.scenario
└── 99-cleanup.scenario
fragments/auth.fragment:
fragment: authenticate
given I have valid credentials
call using auth ^login
body: {"username": "test", "password": "test"}
extract $.token => authToken
then authentication is successful
assert status 200
fragment: authenticate-admin
given I have admin credentials
call using auth ^login
body: {"username": "admin", "password": "admin123"}
extract $.token => adminToken
then admin authentication is successful
assert status 200
scenarios/pet-crud.scenario:
scenario: Create pet as authenticated user
given I am authenticated
include authenticate
when I create a new pet
call ^createPet
header_Authorization: Bearer {{authToken}}
body: {"name": "Fluffy", "status": "available"}
then the pet is created
assert status 201
extract $.id => petId
scenario: Delete pet as admin
given I am an admin
include authenticate-admin
when I delete the pet
call ^deletePet
header_Authorization: Bearer {{adminToken}}
petId: {{petId}}
then the pet is deleted
assert status 204
Best Practices
Keep fragments focused: Each fragment should do one thing well
Use descriptive names: Fragment names should clearly indicate their purpose
Document variables: Comment which variables are extracted by the fragment
Organize by domain: Group related fragments together
Avoid deep nesting: Don’t include fragments within fragments