Macros
Macros in TestFlowKit are reusable, parameterized test scenarios that help reduce code duplication and improve maintainability.
What are Macros?
Macros allow you to define common test patterns once and reuse them across multiple test scenarios with different data sets.
Key Benefits
- ✅ Parameterized Reusability — Use the same macro with different data
- ✅ Table-Driven Testing — Easy to test multiple scenarios with different parameters
- ✅ Improve Maintainability — Update logic in one place, affects all usages
- ✅ Better Organization — Separate macro definitions from test scenarios
How Macros Work
1. Define a Macro
Create a scenario with the @macro tag and use ${variable_name} syntax for placeholders:
@macro
Scenario: Login as user
Given the user goes to the "login" page
When the user enters "${email}" into the "email" field
And the user enters "${password}" into the "password" field
And the user clicks the "login" button
Then the page title should be "Dashboard"
2. Use the Macro
Invoke the macro with a data table containing variable values:
Scenario: Admin can access dashboard
Given Login as user:
| email | admin@example.com |
| password | admin123 |
When the user clicks the "admin_panel" link
Then the "admin_dashboard" should be visible
Macro Syntax
Defining Variables
Use ${variable_name} to define placeholders in your macro:
@macro
Scenario: Fill contact form
When the user enters "${name}" into the "name" field
And the user enters "${email}" into the "email" field
And the user enters "${message}" into the "message" field
And the user clicks the "submit" button
Invoking Macros
Use the scenario name followed by a colon and data table:
Scenario: Submit support request
Given the user goes to the "contact" page
When Fill contact form:
| name | John Doe |
| email | john@example.com |
| message | I need help with login |
Then the "success_message" should be visible
Variable Substitution
Variables are replaced at runtime with the provided values:
| Step in Macro | Data Table | Result |
|---|---|---|
the user enters "${email}" | email: john@example.com | the user enters "john@example.com" |
Real-World Examples
Login Macros
# macros/auth.feature
@macro
Scenario: Login with credentials
Given the user goes to the "login" page
When the user enters "${email}" into the "email" field
And the user enters "${password}" into the "password" field
And the user clicks the "login" button
Then the "dashboard" should be visible
@macro
Scenario: Logout
When the user clicks the "user_menu" button
And the user clicks the "logout" link
Then the "login" page should be visible
Usage:
Scenario: User session management
Given Login with credentials:
| email | user@example.com |
| password | userpass123 |
Then the "welcome_message" should contain "Welcome"
When Logout
Then the current URL should contain "/login"
Data Setup Macros
@macro
Scenario: Create product via API
Given I prepare a request for the "create_product" endpoint
And I set the request body to:
"""
{
"name": "${product_name}",
"price": ${price},
"category": "${category}"
}
"""
When I send the request
Then the response status code should be 201
Usage:
Scenario: Verify product catalog
Given Create product via API:
| product_name | Laptop Pro |
| price | 999 |
| category | Electronics |
And Create product via API:
| product_name | Office Chair |
| price | 299 |
| category | Furniture |
When the user goes to the "products" page
Then the "product_list" should contain "Laptop Pro"
And the "product_list" should contain "Office Chair"
Form Submission Macros
@macro
Scenario: Complete checkout
Given the user goes to the "checkout" page
When the user enters "${card_number}" into the "card" field
And the user enters "${expiry}" into the "expiry" field
And the user enters "${cvv}" into the "cvv" field
And the user selects "${country}" from the "country" dropdown
And the user clicks the "pay_button" button
Then the "confirmation" should be visible
Usage:
Scenario: Purchase with US credit card
# ... add items to cart ...
When Complete checkout:
| card_number | 4111111111111111 |
| expiry | 12/25 |
| cvv | 123 |
| country | United States |
Then the "order_number" should be visible
Organizing Macros
File Structure
features/
├── macros/
│ ├── auth.feature # Login/logout macros
│ ├── data-setup.feature # API data creation macros
│ └── checkout.feature # E-commerce macros
├── login/
│ └── login.feature # Login tests
└── checkout/
└── purchase.feature # Checkout tests
Naming Conventions
- ✅ Use descriptive names that indicate the macro's purpose
- ✅ Start with a verb: "Login as", "Create", "Fill", "Complete"
- ✅ Keep names concise but clear
Best Practices
Do's
- ✅ Keep macros focused on single responsibilities
- ✅ Use descriptive variable names
- ✅ Group related macros in the same file
- ✅ Document variable requirements
- ✅ Test macros with different variable combinations
- ✅ Limit to 2-5 variables per macro
Don'ts
- ❌ Don't create overly complex macros
- ❌ Don't use unclear variable names
- ❌ Don't mix macro definitions with test scenarios
- ❌ Don't create macros too specific to one use case
- ❌ Don't ignore macro reusability
Troubleshooting
Macro Not Found
Problem: TestFlowKit can't find your macro
Solutions:
- Verify the
@macrotag is present - Check the scenario name matches exactly
- Ensure the macro file is in the features directory
Variable Not Substituted
Problem: ${variable} appears literally in test output
Solutions:
- Verify variable name in data table matches the placeholder
- Check for typos in variable names
- Ensure data table is properly formatted
Wrong Values Used
Problem: Variables have unexpected values
Solutions:
- Check data table row/column alignment
- Verify variable names are unique
- Use
--verboseflag for debugging
Next Steps
- Global Hooks — Setup and teardown across test suites
- Frontend Testing — Browser automation features
- API Testing — REST API testing