Global Hooks
Global hooks allow you to run setup and teardown operations before and after your entire test suite, enabling cross-scenario data sharing and environment preparation.
What are Global Hooks?
Global hooks are special feature files that run at specific points in your test execution:
- BeforeAll — Runs once before any test scenarios
- AfterAll — Runs once after all test scenarios complete
Use Cases
- ✅ Set up test data via API before tests run
- ✅ Initialize global variables used across scenarios
- ✅ Configure authentication tokens
- ✅ Seed a database
- ✅ Clean up test data after all tests complete
Creating Global Hooks
BeforeAll Hook
Create a feature file with the @BeforeAll tag:
@BeforeAll
Feature: Test Setup
Scenario: Initialize test environment
Given I prepare a request for the "login" endpoint
And I set the request body to:
"""
{
"email": "test@example.com",
"password": "testpass123"
}
"""
When I send the request
And I save the response path "$.token" as global variable "auth_token"
Then the response status code should be 200
Scenario: Create test user
Given I prepare a request for the "create_user" endpoint
And I set the request header "Authorization" to "Bearer {{auth_token}}"
And I set the request body to:
"""
{
"name": "Test User",
"email": "testuser@example.com"
}
"""
When I send the request
And I save the response path "$.data.id" as global variable "test_user_id"
Then the response status code should be 201
AfterAll Hook
Create a feature file with the @AfterAll tag:
@AfterAll
Feature: Test Cleanup
Scenario: Delete test user
Given I prepare a request for the "delete_user" endpoint
And I set the following path parameters:
| id | {{test_user_id}} |
And I set the request header "Authorization" to "Bearer {{auth_token}}"
When I send the request
Then the response status code should be 204
Scenario: Log completion
Given I store the "completed" into "test_status" variable
Global Variables
Storing Global Variables
Use the global variable step to store data that persists across all scenarios:
# From API response
And I save the response path "$.token" as global variable "auth_token"
# Direct value
And I store the value "https://api.example.com" into global variable "api_base_url"
Using Global Variables
Global variables use the same {{variable_name}} syntax:
Scenario: Access protected resource
Given I prepare a request for the "protected_data" endpoint
And I set the request header "Authorization" to "Bearer {{auth_token}}"
When I send the request
Variable Scope Comparison
| Type | Scope | Persistence |
|---|---|---|
| Scenario Variable | Single scenario | Cleared after scenario |
| Global Variable | All scenarios | Persists until test suite ends |
File Organization
Recommended Structure
features/
├── hooks/
│ ├── before_all.feature # @BeforeAll
│ └── after_all.feature # @AfterAll
├── auth/
│ └── login.feature
├── users/
│ └── user_crud.feature
└── products/
└── product_tests.feature
Execution Order
@BeforeAllscenarios execute (in order defined)- All test scenarios execute
@AfterAllscenarios execute (in order defined)
Real-World Examples
Authentication Setup
@BeforeAll
Feature: Authentication Setup
Scenario: Login as admin user
Given I prepare a request for the "login" endpoint
And I set the request body to:
"""
{
"email": "admin@example.com",
"password": "adminpass"
}
"""
When I send the request
And I save the response path "$.accessToken" as global variable "admin_token"
And I save the response path "$.refreshToken" as global variable "refresh_token"
Then the response status code should be 200
Scenario: Login as regular user
Given I prepare a request for the "login" endpoint
And I set the request body to:
"""
{
"email": "user@example.com",
"password": "userpass"
}
"""
When I send the request
And I save the response path "$.accessToken" as global variable "user_token"
Then the response status code should be 200
Test Data Seeding
@BeforeAll
Feature: Seed Test Data
Scenario: Create test products
Given I prepare a request for the "create_product" endpoint
And I set the request header "Authorization" to "Bearer {{admin_token}}"
And I set the request body to:
"""
{
"name": "Test Product A",
"price": 99.99
}
"""
When I send the request
And I save the response path "$.data.id" as global variable "product_a_id"
Then the response status code should be 201
Given I prepare a request for the "create_product" endpoint
And I set the request header "Authorization" to "Bearer {{admin_token}}"
And I set the request body to:
"""
{
"name": "Test Product B",
"price": 149.99
}
"""
When I send the request
And I save the response path "$.data.id" as global variable "product_b_id"
Then the response status code should be 201
Cleanup After Tests
@AfterAll
Feature: Cleanup Test Data
Scenario: Remove test products
Given I prepare a request for the "delete_product" endpoint
And I set the following path parameters:
| id | {{product_a_id}} |
And I set the request header "Authorization" to "Bearer {{admin_token}}"
When I send the request
Then the response status code should be 204
Given I prepare a request for the "delete_product" endpoint
And I set the following path parameters:
| id | {{product_b_id}} |
And I set the request header "Authorization" to "Bearer {{admin_token}}"
When I send the request
Then the response status code should be 204
Best Practices
1. Keep Hooks Focused
Each hook scenario should have a single responsibility:
# Good: Focused scenarios
Scenario: Authenticate admin user
# Only authentication steps
Scenario: Create test users
# Only user creation steps
# Bad: Mixed responsibilities
Scenario: Setup everything
# Authentication + Data creation + Configuration
2. Handle Failures Gracefully
If a BeforeAll hook fails, no tests will run. Design hooks to be resilient:
Scenario: Create test user if not exists
Given I prepare a request for the "get_user_by_email" endpoint
And I set the following query parameters:
| email | test@example.com |
When I send the request
# Continue based on response...
3. Clean Up Completely
Ensure AfterAll hooks clean up all created data:
@AfterAll
Feature: Complete Cleanup
Scenario: Remove all test data
# Delete in reverse order of creation
# Handle missing resources gracefully
4. Document Dependencies
Comment on what global variables are set and required:
@BeforeAll
Feature: Setup
# Sets: auth_token, admin_token, test_user_id
# Required by: All authenticated test scenarios
Troubleshooting
Hook Not Executing
- Verify the
@BeforeAllor@AfterAlltag is present - Check the feature file is in the features directory
- Ensure the file has
.featureextension
Global Variable Not Available
- Confirm the variable was set in a BeforeAll hook
- Check for typos in variable names
- Verify BeforeAll completed successfully
Cleanup Not Running
- AfterAll runs even if tests fail
- Check for syntax errors in AfterAll feature
- Review test output for hook execution status
Next Steps
- Variables — Learn more about the variable system
- API Testing — API testing in hooks
- Configuration — Environment configuration