Q11 of 40 · Karate
How do you reuse logic across scenarios with Karate (helpers and library features)?
Short answer
Short answer: Extract common steps into a helper feature under helpers/ and call it with * def result = call read('classpath:helpers/create-user.feature') { email: 'test@example.com' }. For JavaScript utilities, define them in a .js file and import with * def utils = read('classpath:helpers/utils.js'). Both patterns enable DRY reuse without duplicating steps.
Detail
Karate has two complementary reuse mechanisms:
Feature helpers — for HTTP actions (create data, login, call sub-APIs):
src/test/resources/
helpers/
login.feature
create-user.feature
create-order.feature
users/
get-user.feature
update-user.feature
Helpers are called with call read and return variables via * def at the end of their Scenario:
# helpers/create-user.feature
Scenario:
Given url baseUrl
And path '/users'
And request { name: '#(name)', email: '#(email)' }
When method POST
Then status 201
* def id = response.id
* def email = response.email
JavaScript libraries — for data transformation, date utilities, random generators:
* def utils = read('classpath:helpers/utils.js')
* def uniqueEmail = utils.generateEmail('alice')
callonce for expensive helpers that should run once per suite (e.g., seeding reference data or fetching an access token).
Java helpers — for complex logic that's hard to express in JS or the DSL:
* def MyHelper = Java.type('com.example.test.MyHelper')
* def result = MyHelper.generateHmacSignature(payload, secret)
// EXAMPLE
helpers/create-product.feature
# helpers/create-product.feature
# Arguments received: name, price, category
Feature: Create product helper
Scenario:
Given url baseUrl
And path '/products'
And header Authorization = 'Bearer ' + adminToken
And request { name: '#(name)', price: '#(price)', category: '#(category)' }
When method POST
Then status 201
* def productId = response.id
* def productSlug = response.slug
# Caller feature:
# * def prod = call read('classpath:helpers/create-product.feature')
# { name: 'Widget', price: 9.99, category: 'tools' }
# * def productId = prod.productId
# Then use productId in subsequent assertions