Reusing Authentication in Karate DSL with the call Keyword
Learn how to eliminate duplicated login steps in Karate DSL by extracting authentication into a reusable feature and invoking it with the call keyword.
05 Nov 2025, 08:13 UTC

Problem: duplicated login steps
When testing a REST API that requires a JWT, many feature files repeat the same sequence: send a credentials payload to /auth/login, extract the token, and add it to an Authorization header. This duplication makes the suite harder to maintain and increases the chance of inconsistency when the login endpoint changes.
Thesis
Karate’s call keyword lets you extract a reusable authentication routine into its own feature file. By invoking that file and returning the token as a variable, each test feature can focus on its actual scenario while keeping setup DRY.
Setup: a reusable auth feature
Create auth.feature in the src/test/resources folder:
Feature: Reusable login
Background:
* url baseUrl
Scenario Outline: obtain token
Given path '/auth/login'
And request { username: '#(username)', password: '#(password)' }
When method post
Then status 200
And def token = responseToken
# return the token to the caller
return token
Examples:
| username | password |
| admin | secret |
The return statement makes the value of token available to the caller.
Usage: calling the auth feature
In any test feature, invoke auth.feature with call and store the returned token:
Feature: Create a pet in the store
Background:
* def result = call read('classpath:auth.feature') { username: 'admin', password: 'secret' }
* def token = result
Scenario: add a new pet
Given path '/pets'
And request { name: 'Fluffy', status: 'available' }
And header Authorization = 'Bearer ' + token
When method post
Then status 201
And match response.id == '#notnull'
The call step executes the login, captures the token, and makes it available as token for the header.
Worked example: login → pet‑store
Assume a minimal Maven project with the dependency:
<dependency>
<groupId>com.intuit.karate</groupId>
<artifactId>karate-junit5</artifactId>
<version>1.4.0</version>
<scope>test</scope>
</dependency>
Place auth.feature and create-pet.feature (the example above) under src/test/resources. Running mvn test will:
- Execute the login request defined in
auth.feature. - Extract the JWT and return it to the calling feature.
- Use that token in the
Authorizationheader of the pet‑creation request.
You can verify the flow by adding a Karate logger:
* configure logLevel = 'debug'
The debug output will show both the login POST and the subsequent pet POST with the expected header.
Trade‑off / limitation
The call mechanism works best for returning simple scalars or strings. If you need to return a complex JSON object (e.g., full user profile), you must either:
- Serialize the object to a string and parse it in the caller, or
- Use Karate’s
defin a shared*.jsfile andimportit instead ofcall.
Additionally, variables created inside the called feature are not visible to the caller unless explicitly returned, which can make debugging a bit harder because stack traces point to the caller line only. Enabling detailed Karate logging mitigates this.
Actionable closing
Adopt the call pattern for any repetitive setup—authentication, default headers, payload templates. Keep each called feature focused on a single concern and limit its inputs/outputs to what is strictly needed. This keeps your test suite readable, easier to maintain, and less prone to drift when the underlying API evolves.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.