„Karate“ API testavimo įrankio „Cheat Sheet“

„Karate“ yra „openource“ API testavimo įrankis, kurį sukūrė Peteris Thomas iš „Intuit“. „Karate“ yra pastatytas ant „HttpClient“ ir „Agurkas“ ir turi savo DSL, kad API testavimas būtų labai lengvas. Nors gyvavo beveik metus, jis subrendo labai greitai ir turi visas galimybes, kurių tikimasi iš API testavimo įrankio.

Kadangi „Karate“ sėdi ant agurko, jis paveldi visas agurkų funkcijas, todėl galite parašyti savo API testus paprastu „Given When Then“ formatu ir naudoti visus agurkų raktinius žodžius, tokius kaip „Feature“, „Scenario Outline“, „Scenarijus“, „Pavyzdžiai“, „Feature“ žymėjimas.

Aš sukūriau šį apgaulės lapą, kad galėčiau padėti visiems, kurie užsiima API testavimu, pateikdamas pavyzdžius, kaip naudoti „Karate“ įrankį.


Atkreipkite dėmesį , šis apgaulingas lapas yra tik ledkalnio viršūnė. Karatė turi daug kitų funkcijų, kurios čia nepaminėtos. Šis sąrašas yra tik dažniausiai naudojamos operacijos, paprastai naudojamos bandant API.

Pridėkite priklausomybes (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

Projekto struktūra

Galite organizuoti ir struktūrizuoti savo „Maven“ projektą taip:




karate-config.js

Čia galite sukurti kintamuosius, kurių taikymo sritis yra pasaulinė. Karate perskaito šį failą prieš vykdydamas bet kokį scenarijų. Tai labai pravartu keičiant aplinką, kurie konkretūs kintamieji naudojami skirtingoms aplinkoms

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; }

Kaip siųsti HTTP užklausą (gauti, paskelbti, įdėti, ištrinti, pataisyti)

@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

Ankstesniame pavyzdyje AM_USERNAME, AM_PASSWORD, AM_HOST ir AM_AUTHENTICATE_PATH yra iš karate-config.js failą.

' Gali būti interpretuojamas kaip bet kuris duotasis, kada, tada, ir, bet kai veiksmas netinka kontekstui, galime naudoti „ '.


’+’ Veikia kaip konkatanato operatorius

Aukščiau pateiktame pavyzdyje siunčiama tuščia pranešimo turinio užklausa. Mes galime tiesiog naudoti

Metodas gali būti bet koks galiojantis HTTP veiksmažodis (Get, Post, Put, Patch, Delete)

' def ’Naudojama reikšmei kintamajame išsaugoti.


antraštė , URL , prašymą , metodas , statusą , atsakymą yra visi karatė raktiniai žodžiai, sudarantys DSL. Norėdami rasti visą raktinių žodžių sąrašą, apsilankykite „Intuit“.

Ankstesniame pavyzdyje atsakymas yra JSON formatas, todėl norėdami analizuoti atsakymą, galime naudoti „karate“ integruotą „JsonPath“ žymėjimą.

Užklausa dėl grandinės su keliais API skambučiais

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

Ankstesniame pavyzdyje atliekamas pirmasis skambutis, o autentId analizuojamas iš atsakymo ir išsaugomas kintamajame, pavadintame authId. Tada mes pakeisime antrą naudingąją apkrovą autentifikavimu, gautu per pirmąjį skambutį. Tada mes naudojame naują naudingąją apkrovą siųsti į kitą API skambutį.

Kaip skaityti užklausos šablonus ir iškviesti kitus funkcijų failus

Mes galime padaryti savo scenarijus daugkartinio naudojimo ir iškviesti juos iš kitų funkcijų failų. Šiame pavyzdyje galime sukurti „bendrą“ failą „create-user.feature“, kur galime siųsti vartotojo užklausą, bet naudodami kitą užklausos turinį


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

Atminkite, kad aukščiau pateiktame pavyzdyje „__arg“ naudojame kaip „body body“ užklausą.

Tada galime paskambinti aukščiau nurodytam failo failui ir perduoti reikalingą įrašo turinį, kurį savo ruožtu galime perskaityti iš šablono

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

Aukščiau pateiktas kodas nuskaito šabloną, esantį com/example/templates/idm/idm-create-user-template.json ir saugo jį kaip JSON kintamąjį, vadinamą myReq

Tada mes galime išsiųsti JSON kintamąjį į kitą funkcijos failą naudodami skambinimo metodą.


Šablonas atrodo

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

Kaip skaityti kitus funkcinius failus - 2 pavyzdys

Mes galime perskaityti konkretų kintamąjį iškviestame failo faile, kuris perduodamas iš skambinančio funkcijos failo

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

Atminkite, kad aukščiau pateiktame pavyzdyje mes naudojame „__arg.emailAddress“ kaip pranešimo turinio užklausą. Mums rūpi tik išsiųsti el. Pašto adresą kaip užklausą

Tada galime paskambinti aukščiau nurodytam failo failui ir perduoti reikalingą įrašo turinį, kurį savo ruožtu galime perskaityti iš šablono

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

Aukščiau pateiktas kodas ištraukia pašto lauką iš JSON šablono. Kai kintamąjį perduodame kitam funkcijų failui, jis turi būti JSON tipo, todėl kintamasis emailAddress turi būti galiojantis JSON.

Tada mes galime išsiųsti JSON kintamąjį į kitą funkcijos failą naudodami iškvietimo metodą ir siųsti JSON kintamąjį, šiuo atveju emailAddress

Sukurkite „Test Runner“ klasę

Scenarijus galime atlikti funkcijų faile naudodami „maven“ (tai naudinga atliekant bandymus PI aplinkoje)

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();
} }

Aukščiau nurodytu kodu vykdomi visi funkcijų failai, pažymėti kaip „@FR“, tačiau ignoruojami visi bandymai, pažymėti kaip „@ignore“.

Taip pat sukuriama agurkų ataskaita, skirta vizualizuoti bandymų rezultatus.

Vykdykite bandymus naudodami komandinę eilutę arba CI

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

Čia vykdome „TestRunner_FR“ klasę ir nustatome aplinką kaip etapą.

Vykdykite „JavaScript“ funkcijų faile

Funkcijos faile mes taip pat galime vykdyti „javascript“

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)

Aukščiau pateiktas kodas sukuria atsitiktinę 10 ilgio eilutę ir išsaugo ją kintamajame, vadinamame sessionId.

Duomenimis pagrįsti testai

Kadangi „Karate“ sėdi ant agurko, pagal numatytuosius nustatymus atliekami duomenimis pagrįsti bandymai

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) |

Aukščiau pateiktame pavyzdyje kuriant duomenimis pagrįstus bandymus naudojami „Agurko scenarijaus metmenys“ ir „Pavyzdžiai“ raktiniai žodžiai. Norėdami perskaityti kiekvieną parametrą, mes naudojame kampinius skliaustus

Skambinkite „Java“ iš funkcijų failo

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

Aukščiau pateiktas funkcijų failas iškviečia „Java“ metodą klasėje, vadinamą StringUtil. Tada išsaugo to skambučio atsakymą į otpCode kintamąjį.