Karate API Test Tool Cheat Sheet

Karate is 'n open source API-toetsinstrument wat ontwikkel is deur Peter Thomas van Intuit. Karate is bo-op HttpClient en Cucumber gebou en het sy eie DSL om API-toetsing baie maklik te maak. Alhoewel dit al amper 'n jaar bestaan, het dit baie vinnig verouder en het al die vermoëns wat verwag word deur 'n API-toetsinstrument.

Omdat Karate bo-op komkommer sit, erf dit al die funksies van komkommer, sodat u u API-toetse kan skryf in eenvoudige gegewe Wanneer dan al die komkommer-sleutelwoorde soos Feature, Scenario Outline, Scenario, Voorbeelde, Feature-tagging formateer en gebruik.

Ek het hierdie cheat sheet geskep om almal te help wat betrokke is by die toets van API's, en voorbeelde gee van hoe om die Karate-instrument te gebruik.


Neem asseblief kennis , hierdie cheat sheet is net die punt van die ysberg. Karate het baie ander funksies wat nie hier genoem word nie. Hierdie lys is slegs die mees algemene handelinge wat gewoonlik gebruik word by die toets van API's.

Voeg die afhanklikhede by (pom.xml)


UTF-8
3.7.0
1.8
1.8
1.8
0.8.0.RC4
3.13.0


com.intuit.karate
karate-core
${karate.version}


com.intuit.karate
karate-apache
${karate.version}
test


com.intuit.karate
karate-testng
${karate.version}


net.masterthought
cucumber-reporting
${cucumber.reporting.version}
test

Projekstruktuur

U kan u maven-projek so organiseer en struktureer:


karate-config.js

Dit is hier waar u veranderlikes kan skep wat 'n algemene omvang het. Karate lees hierdie lêer voordat hy 'n scenario uitvoer. Dit is baie handig wanneer u van omgewing verander, watter spesifieke veranderlikes vir verskillende omgewings gebruik word

function() {
var env = karate.env; // get java system property 'karate.env'
karate.log('karate.env selected environment was:', env);
karate.configure('ssl', true)
if (!env) {
env = 'dev'; //env can be anything: dev, qa, staging, etc.
}
var config = {
env: env,
AM_USERNAME: 'devuser',
AM_PASSWORD: 'devpass',
AM_HOST: 'https://am.'+env+'.example.net',
AM_AUTHENTICATE_PATH: '/am/json/realms/root/authenticate',
IDM_USERNAME: 'devuser',
IDM_PASSWORD: 'devpass',
IDM_HOST: 'https://idm.'+env+'.example.net',
IDM_MANAGED_USER_PATH: '/idm/managed/user',
};
if(env == 'qa') {
config.AM_USERNAME: 'myUserName'
config.AM_PASSWORD: 'myPa55word'
}
if(env == 'live') {
config.AM_USERNAME: 'admin'
config.AM_PASSWORD: 'secret'
}
karate.log('OpenAM Host:', config.AM_HOST);
karate.configure('connectTimeout', 60000);
karate.configure('readTimeout', 60000);
return config; }

Hoe stuur u 'n HTTP-versoek (kry, plaas, plaas, verwyder, plak)

@FR Feature: AM Admin Login
Scenario: Login as Admin to AM and get token
Given header X-OpenAM-Username = AM_USERNAME
Given header X-OpenAM-Password = AM_PASSWORD
Given url AM_HOST + AM_AUTHENTICATE_PATH
And request ''
When method POST
Then status 200
* assert response.tokenId != null
* def tokenId = response.tokenId

In die voorbeeld hierbo kom AM_USERNAME, AM_PASSWORD, AM_HOST en AM_AUTHENTICATE_PATH van die karate-config.js lêer.

' 'Kan geïnterpreteer word as enige van Gegewe, Wanneer, Dan, En, maar as 'n handeling nie 'n konteks dien nie, kan ons' '.


'+' Tree op as 'n gekoppelde operateur

Die bostaande voorbeeld stuur 'n leë versoek vir die liggaam. Ons kan net ''

Die metode kan enige geldige HTTP-werkwoord wees (kry, plaas, plaas, plak, verwyder)

' def ’Word gebruik om 'n waarde in 'n veranderlike op te slaan.


kop , url , versoek , metode , status , reaksie is al die sleutelwoorde van karate wat die DSL vorm. Besoek Intuit vir die volledige lys sleutelwoorde.

In die bostaande voorbeeld is die antwoord JSON-formaat, dus kan ons die ingeboude JsonPath-notasie van karate gebruik om die antwoord te ontleed.

Versoek ketting met verskeie API-oproepe

Feature: request chaining with multiple api calls Scenario: chain request demo
* json req = read('classpath:com/example/templates/idm/create-user-template.json')
* def user = req.givenName
Given header X-Username = 'anonymous'
Given header X-Password = 'anonymous'
Given url AM_HOST + '/some/endpoint
And request ''
When method POST
* def authId = response.authId
* def payload1 =
'''
{'authId':'${authId}','callbacks':[{'type':'NameCallback','output':[{'name':'prompt','value':'Email Address'}],'input':[{'name':'IDToken0','value':'${user}@putsbox.com'}]}]}
'''
* replace payload1
| token
| value |
| ${authId} | authId |
| ${user} | user |
* json mypayload1 = payload1
Given header X-Username = 'anonymous'
Given header X-Password = 'anonymous'
Given url AM_HOST + '/openam/some-other-endpoint
And request mypayload1
When method POST

In die bostaande voorbeeld word die eerste oproep gemaak en die authId van die antwoord ontleed en gestoor in 'n veranderlike genaamd authId. Ons vervang dan die tweede loonvrag deur die authId wat in die eerste oproep opgespoor word. Ons gebruik dan die nuwe loonvrag om na die volgende API-oproep te stuur.

Hoe u versoeksjablone kan lees en ander funksielêers kan oproep

Ons kan ons scenario's herbruikbaar maak en dit oproep uit ander funksielêers. In hierdie voorbeeld kan ons 'n 'generiese' create-user.feature-lêer skep waarheen ons die create user-versoek kan stuur, maar met 'n ander versoekinstansie


Feature: Create User in IDM
Scenario: Create user in IDM with given guid
Given header X-Requested-With = 'Swagger-UI'
Given header X-OpenIDM-Username = IDM_USERNAME
Given header X-OpenIDM-Password = IDM_PASSWORD
Given url IDM_HOST + IDM_MANAGED_USER_PATH
And request __arg
When method POST
Then status 201

Let op, in die voorbeeld hierbo gebruik ons ​​'__arg' as versoek vir die liggaam.

Ons kan dan die bogenoemde funksielêer oproep en die vereiste posliggaam instuur, wat ons weer op 'n sjabloon kan lees

Feature: Create a user
Scenario: Create user in IDM
* json myReq = read('classpath:com/example/templates/idm/idm-create-user-template.json')
* call read('classpath:com/example/idm/idm-create-user.feature') myReq

Die kode hierbo lees 'n sjabloon wat op die plek is com/example/templates/idm/idm-create-user-template.json en stoor dit as 'n JSON-veranderlike genaamd myReq

Dan kan ons die JSON-veranderlike na die ander funksielêer stuur met behulp van die oproepmetode.


Die sjabloon lyk

{
'mail' : 'david@putsbox.com',
'givenName' : 'david',
'sn' : 'putsbox',
'jobRole' : 'developer',
'telephoneNumber' : '91234567890',
'dob' : '01/02/2010', }

Hoe om ander funksielêers te lees - voorbeeld 2

Ons kan 'n spesifieke veranderlike in die genoemde funksielêer lees wat van 'n roepfunksie-lêer gestuur word

Feature: Create User in IDM
Scenario: Create user in IDM with given guid
Given header X-Requested-With = 'Swagger-UI'
Given header X-OpenIDM-Username = IDM_USERNAME
Given header X-OpenIDM-Password = IDM_PASSWORD
Given url IDM_HOST + IDM_MANAGED_USER_PATH
And request __arg.emailAddress
When method POST
Then status 201

Let op, in die voorbeeld hierbo gebruik ons ​​'__arg.emailAddress' as versoek vir die liggaam. Ons wil slegs die e-posadres as die versoek stuur

Ons kan dan die bogenoemde funksielêer oproep en die vereiste posliggaam instuur, wat ons weer op 'n sjabloon kan lees

Feature: Create a user
Scenario: Create user in IDM
* json myReq = read('classpath:com/example/templates/idm/idm-create-user-template.json')
* json emailAddress = '{'emailAddress': '' +myReq.mail+ ''}'
* call read('classpath:com/example/fr/idm/idm-create-user.feature') emailAddress

Bogenoemde kode haal die e-posveld uit die JSON-sjabloon. Wanneer ons 'n veranderlike na 'n ander funksielêer deurgee, moet dit van die tipe JSON wees, dus moet die veranderlike emailAddress 'n geldige JSON wees.

Dan kan ons die JSON-veranderlike na die ander funksielêer stuur met behulp van die oproepmetode en die JSON-veranderlike stuur, in hierdie geval emailAddress

Skep 'n toetsloperklas

Ons kan die scenario's in die funksielêer uitvoer met behulp van maven (wat nuttig is om die toetse in 'n CI-omgewing uit te voer)

import com.intuit.karate.cucumber.CucumberRunner; import com.intuit.karate.cucumber.KarateStats; import cucumber.api.CucumberOptions; import net.masterthought.cucumber.Configuration; import net.masterthought.cucumber.ReportBuilder; import org.apache.commons.io.FileUtils; import org.testng.annotations.Test; import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.List; import static org.testng.AssertJUnit.assertTrue; @CucumberOptions(tags = {'@FR', '~@ignore'}) public class TestRunner_FR {
@Test
public void testParallel() {
String karateOutputPath = 'target/cucumber-html-reports';
KarateStats stats = CucumberRunner.parallel(getClass(), 1, karateOutputPath);
generateReport(karateOutputPath);
assertTrue('there are scenario failures', stats.getFailCount() == 0);
}
private static void generateReport(String karateOutputPath) {
Collection jsonFiles = FileUtils.listFiles(new File(karateOutputPath), new String[] {'json'}, true);
List jsonPaths = new ArrayList(jsonFiles.size());
for (File file : jsonFiles) {

jsonPaths.add(file.getAbsolutePath());
}
Configuration config = new Configuration(new File('target'), 'YOUR PROJECT NAME');
config.addClassifications('Environment', System.getProperty('karate.env'));
ReportBuilder reportBuilder = new ReportBuilder(jsonPaths, config);
reportBuilder.generateReports();
} }

Die kode hierbo laat al die funksielêers loop wat as '@FR' gemerk is, maar al die toetse wat as '@ignore' gemerk is, ignoreer.

Dit skep ook 'n komkommerverslag om die resultate van die toetslopies te visualiseer.

Voer die toetse vanaf 'n opdraglyn of CI uit

mvn clean test -DargLine='-Dkarate.env=staging' -Dtest=TestRunner_FR

Hier hou ons die TestRunner_FR-klas en stel ons die omgewing as toneel.

Voer JavaScript uit in die funksielêer

In 'n funksielêer is ons in staat om ook javascript uit te voer

Feature: Generate a random session id
Scenario: generate random session id
* def random_string =
'''
function(s) {
var text = '';
var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
for (var i = 0; i < s; i++)
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
}
'''
* def sessionId = random_string(10)

Bogenoemde kode genereer 'n ewekansige string van lengte 10 en stoor dit in 'n veranderlike genaamd sessionId.

Data-gedrewe toetse

Aangesien Karate bo-op komkommer sit, is data-gedrewe toetsing standaard

Feature: Data driven testing example Scenario Outline: An 'Invalid input request' error is returned if required parameters have incorrect values.
* def attribute_name = ''
* xml malformed_request =
* json activate_request = malformed_request
* def activate_response = call read('activate.feature') activate_request
* match activate_response.contentType == 'text/xml;charset=ISO-8859-1'
* match activate_response.gas_version == '5.2.7'
* match activate_response.error_code == '1000'
Examples:
| name_attribute | method_call













|
| auth_method
| Java.type('com.example.StringUtil').removeNodeByAttribute(xml_req, attribute_name) |
| app_url
| Java.type('com.example.StringUtil').removeNodeByAttribute(xml_req, attribute_name) |

In die voorbeeld hierbo word Cucumber se Scenario Outline en voorbeelde sleutelwoorde gebruik om data-gedrewe toetse te skep. Om elke parameter te lees, gebruik ons ​​die hoekhakies

Bel Java vanuit 'n funksielêer

package com.example; public class StringUtil {
public static String getNumberFromString(String text) {
return text.replaceAll('\D+', '');
} }
Feature: Call java demo Scenario: Get number from text
Given url 'https://preview.putsbox.com/p/david/last.json'
When method GET
* def emailText = response.text
* def otpCode = Java.type('com.example.StringUtil').getNumberFromString(emailText)
* print otpCode

Die funksielêer hierbo noem 'n Java-metode in die klas genaamd StringUtil Stoor dan die antwoord van die oproep na die otpCode-veranderlike.