In the following code example, we declare and initialize a variable then conditionally change it's value, after that we call on another scenario with no interest in passing this variable down to it or have the scenario return anything (to make steps more reusable and legible). Finally we print and do a match step on the variable and for some reason it has its initial value again ('value1'), disregarding what was done in the if() step ('value2').
Feature: Variable Scope
Scenario: Check variable scope
* def variable = 'value1'
* def condition = true
* if(condition) variable = 'value2'
* call read('test.feature@callable-scenario')
* print 'variable value:', variable
* match variable == 'value2'
@callable-scenario
Scenario: Just print
* print 'hello'
Output:
hello
variable value: value1
However if we do any of the following, the variable in the end does have its second value:
Change the way the variable value is modified
* if(condition) karate.set('variable', 'value2')
Store the scenario result/execution in a variable
* def result = call read('test.feature@callable-scenario')
Pass the variable down to the scenario
* call read('test.feature@callable-scenario'){variable: '#(variable)'}
Output:
hello
variable value: value2
Why does this happen? What is the difference between these approaches?
Yes, this is because of limitations of the JS engine used behind the scenes to evaluate it. It has some issues, and will be re-written in one of the upcoming releases. I would say using karate.set()
would be the right thing to do in this case.
By the way, call read('@callable-scenario')
should work in the latest versions of Karate if it is within the same feature file.