Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
667 views
in Technique[技术] by (71.8m points)

testing - How to use dynamic values for Karate Features

I've a need where I should use dynamic values in the features of my karate tests.

I've came accross with some of the questions and answers like this: How to read input data from an excel spreadsheet and pass it JSON payload in karate framework?

But no mather what how hard I try, I couln't make it happen. I believe I should share the code parts that I am trying to use, so that a discussion can start.

I have a SOAP request for creating new users as below:

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xxxxxx>
<soapenv:Header/>
<soapenv:Body>
    <int:createSubscriber soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
        <custBean xxxxx>
            <accountNumber xsi:type="xsd:string">#(accountNo)</accountNumber>
            <custName xsi:type="xsd:string" xs:type="type:string">Xbox</custName>
        </custBean>
        <addSubscriberBean xxxxx>7
            <subscriberID xsi:type="xsd:string">#(subsID)</subscriberID>
            <password xsi:type="xsd:string" xs:type="type:string">0</password>
            <areaID xsi:type="xsd:string" xs:type="type:string">1</areaID>
            <lineOfCredit xsi:type="xsd:int" xs:type="type:int"></lineOfCredit>
            <creditCycle xsi:type="xsd:int" xs:type="type:int"></creditCycle>
            <points xsi:type="xsd:int" xs:type="type:int"></points>
            <bandwidth xsi:type="xsd:int" xs:type="type:int"></bandwidth>
            <physicalPorts xsi:type="xsd:string" xs:type="type:string">8080</physicalPorts>
            <mobilePhoneNo xsi:type="xsd:string" xs:type="type:string">#(mobile)</mobilePhoneNo>
            <stbCount xsi:type="xsd:int" xs:type="type:int">5</stbCount>
            <oTTCount xsi:type="xsd:int" xs:type="type:int">10</oTTCount>
            <subscriptionType xsi:type="xsd:string" xs:type="type:string">#(subsType)</subscriptionType>
        </addSubscriberBean>
        <sequenceID xxxxx>1234567840123422700</sequenceID>
    </int:createSubscriber>
</soapenv:Body>

As you've seen, I have some variables which are going to be given from outside, and those are: accountNo, subsID, subsType and mobile.

Now, I have a feature file where I make a call to a SOAP service by using above file. I am assigning new values to all variables of request, so that I can create new users all the time.

Here is the example:

Feature: Create Subscriber Feature End-To-End Scenario

Background:
* url SOAP_CREATE_SUBSCRIBER_HOST

* def accountNumber = '789'
* def subscriberID = '456'
* def userMsisdn = '123'
* def subscriptionType = 'ASD'

* def createUser = read('create-user-soap.xml') # This is the above one
* replace createUser
  | token              | value               |
  | #(accountNo)       | accountNumber       |
  | #(subsID)          | subscriberID        |
  | #(mobile)          | userMsisdn          |
  | #(subsType)        | subscriptionType    |

Scenario: Create Subscriber
Given request createUser
When soap action SOAP_CREATE_SUBSCRIBER_HOST
Then status 200

And match //returnCode == 0
And match //returnMessage == 'The operation succeeded.'

However, I need to create bunch of users, so I need to use dynamic variables to call my .xml file too many times.

I checked the docs and answer here: How to read input data from an excel spreadsheet and pass it JSON payload in karate framework?

But couldn't locate it in my situation.

Thanks in advance.

EDIT: I am aware of the situation that I need to use table or json or csv or excel kind of data holder to use it late, so below is my users table. Just don't know how to implement it to my feature file so that it can create too many users.

    * table userstable
  | accountNo   | subsID         | mobile       | subsType   |
  | '113888572' | '113985218890' | '1135288836' | 'asd'     |
  | '113888573' | '113985218891' | '1135288837' | 'qwe'     |
  | '113888582' | '113985218810' | '1135288846' | 'asd'     |
  | '883889572' | '883985219890' | '8835298836' | 'qwe'     |
  | '773888572' | '773985218890' | '7735288836' | 'asd'     |
  | '663888572' | '663985218890' | '6635288836' | 'qwe'     |
  | '553888572' | '553985218890' | '5535288836' | 'asd'     |
  | '443888572' | '443985218890' | '4435288836' | 'qwe'     |
  | '333888572' | '333985218890' | '3335288836' | 'asd'     |
  | '223888572' | '223985218890' | '2235288836' | 'qwe'     |
  | '165488572' | '175585218890' | '1114788836' | 'asd'     |

EDIT 2: After a deep dive into the some answers and reading lots of docs, I've encounter with the solution below. There should be a .feature file where you place your create method to fire up the single user creation mechanism. It is going to look like this:

@ignore
Feature: re-usable feature to create a single user

Background:
* url SOAP_CREATE_SUBSCRIBER_HOST

Scenario: Create single user

* match __arg == bulkusers[__loop]
* def createUser = read('xxxx')

Given request createUser
When soap action SOAP_CREATE_SUBSCRIBER_HOST
And request { accountNo: '#(accountNo)', subsID: '#(subsID)', mobile: '#(mobile)', subsType: '#(subsType)' }
Then status 200

So above code can be placed as a template in your mind. On the other hand, we need another**.feature** file to call that template. And it is going to look like this:

Feature: call template feature.

Background: * url SOAP_CREATE_SUBSCRIBER_HOST

Scenario: Use bulkusers table to create default users

* table bulkusers
  | accountNo   | subsID         | mobile       | subsType |
  | '131451715' | '133451789134' | '5335167897' | 'asd'   |
  | '122452715' | '123452789124' | '5334287897' | 'qwe'  |
  | '124453715' | '123453789114' | '5334367817' | 'asd'   |

* def result = call read('user-create.feature') bulkusers
* def created = $result[*].response

* match result[*].__loop == [0, 1, 2]
* match created[*].name == $bulkusers[*].name

* def createUser = read('xxx')

What this code achieve is, it is packing up the bulkusers table with user-create.feature, thus, user-create.feature template class being called recursively till the number of the table variables ends, with the bulkusers variables.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I am providing a simplified example below, but am sure you will find the answers to your questions here. It is easy to loop over data and build XML in Karate using the karate.set(varName, xPath, value) API:

* table users
  | accountNo   | subsID         | mobile       | subsType  |
  | '113888572' | '113985218890' | '1135288836' | 'asd'     |
  | '113888573' | '113985218891' | '1135288837' | 'qwe'     |
  | '113888582' | '113985218810' | '1135288846' | 'asd'     |

* def xml = <users></users>
* def fun =
"""
function(u, i) {
  var base = '/users/user[' + (i + 1) + ']/';
  karate.set('xml', base + 'account', u.accountNo);
  karate.set('xml', base + 'mobile', u.mobile);
  karate.set('xml', base + 'type', u.subsType);
}
"""
* eval karate.forEach(users, fun)
* match xml ==
"""
<users>
  <user>
    <account>113888572</account>
    <mobile>1135288836</mobile>
    <type>asd</type>
  </user>
  <user>
    <account>113888573</account>
    <mobile>1135288837</mobile>
    <type>qwe</type>
  </user>
  <user>
    <account>113888582</account>
    <mobile>1135288846</mobile>
    <type>asd</type>
  </user>
</users>
"""

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...