4

https://github.com/intuit/karate#calling-other-feature-files

The link above contains an example of calling a feature file in order to reuse the code. The feature file which is reused is called with the inputs

Background:
* configure headers = read('classpath:my-headers.js')
* def signIn = call read('classpath:my-signin.feature') { username:'john', password: 'secret' }
* def authToken = signIn.authToken

The called my-signin.feature:

Scenario:
    Given url loginUrlBase
    And request { userId: '#(username)', userPass: '#(password)' }
    When method post
    Then status 200
    And def authToken = response
    ...

In this example the my-signin.feature must be run with the inputs username and password. I know that if you had the following:

Background:
   * def username = "foo"
   * def password = "secret"

at the top of the my-signing.feature file, the parameters input by the feature attempting to reuse the feature file would be overwritten.

My question is: If reuse is the main interest of being able to call other feature files, is there a way to have the calling feature file overwrite the username and password parameters if they had been defined in the background?

It seems to me that having the background overwrite the input parameters instead of vice versa makes it harder to reuse *.feature files. I know I found it a little frustrating on my project not being able to reuse tests I had already written without refactoring out the reusable code into another file.

Peter Thomas
  • 54,465
  • 21
  • 84
  • 248
Luke D.
  • 53
  • 6
  • do want something thing like if username, password is passed it should use it else it should the one defined in background and background should not overwrite the the values paased? – Babu Sekaran May 14 '19 at 06:27
  • Yeah I was thinking something like that. I know you can do something similar with a javascript function, but I think that the way you @BabuSekaran mentioned would help simplify and expand the reuse of features. – Luke D. May 14 '19 at 06:38

1 Answers1

3

Any called feature in karate will have a magic variable __arg, you can check for this before assigning values to your variables in your called script.

Background:
 * def username = (__arg == null) ? "foo" : __arg.username
 * def password = (__arg == null)? "secret" : __arg.password

this will check for values passed,

  • if none passed it will assign default

* def signIn = call read('classpath:my-signin.feature')

  • if passed with arguments passed arguments will be assigned

* def signIn = call read('classpath:my-signin.feature') { username: 'notfoo', password: 'notsecret' }

For simplicity don't have anyother parameters that need to passed other than this.

Babu Sekaran
  • 4,129
  • 1
  • 9
  • 20
  • 1
    also want to add that if you are using `{ foo: '#(bar)' }` in the called feature, it is not mandatory to pass arguments at all. keep in mind that any variable defined in the caller (at any time before the `call` happens) will automatically be available in the called feature. – Peter Thomas May 14 '19 at 07:53
  • This answer worked, just had to call the __arg with this.__arg – Luke D. May 16 '19 at 22:38