Varalica za alat za testiranje karate API-ja

Karate je alat za testiranje API-ja otvorenog izvora koji je razvio Peter Thomas iz Intuita. Karate je izgrađen na vrhu HttpClienta i krastavca i ima vlastiti DSL koji API testiranje čini vrlo jednostavnim. Iako postoji gotovo godinu dana, sazrio je vrlo brzo i ima sve mogućnosti koje se očekuju od alata za testiranje API-ja.

Budući da Karate sjedi na vrhu krastavca, on nasljeđuje sve funkcionalnosti krastavca, tako da API testove možete pisati u jednostavnom formatu S obzirom na to kada i upotrijebiti sve ključne riječi krastavca kao što su Značajka, Okvir scenarija, Scenarij, Primjeri, Označavanje značajki.

Napravio sam ovaj varalica kako bih pomogao svima koji su uključeni u testiranje API-ja, dajući primjere kako koristiti alat Karate.

Molim Zabilježite , ova je varalica samo vrh ledenog brijega. Karate ima mnoštvo drugih značajki koje ovdje nisu spomenute. Ovaj je popis samo najčešćih operacija koje se obično koriste prilikom testiranja API-ja.

Dodajte ovisnosti (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

Struktura projekta

Možete organizirati i strukturirati svoj maven projekt ovako:



karate-config.js

Ovdje možete stvoriti varijable koje imaju globalni opseg. Karate čita ovu datoteku prije izvođenja bilo kojeg scenarija. To je vrlo korisno kod prebacivanja okruženja koje se specifične varijable koriste za različita okruženja

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

Kako poslati HTTP zahtjev (Nabavite, objavite, stavite, izbrišite, zakrpite)

@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

U gornjem primjeru, AM_USERNAME, AM_PASSWORD, AM_HOST i AM_AUTHENTICATE_PATH dolaze iz karate-config.js datoteka.

' 'Može se protumačiti kao bilo koji od Dana, Kada, Tada i I, ali kada radnja ne služi kontekstu, možemo koristiti' '.

’+’ Djeluje kao operater za spajanje

Gornji primjer šalje prazan zahtjev za tijelom posta. Možemo jednostavno upotrijebiti

Metoda može biti bilo koji valjani HTTP glagol (Get, Post, Put, Patch, Delete)

' def 'Koristi se za pohranu vrijednosti u varijablu.

Zaglavlje , url , zahtjev , metoda , status , odgovor su sve ključne riječi karatea koje čine DSL. Za cjelovit popis ključnih riječi posjetite Intuit.

U gornjem primjeru odgovor je JSON format, pa za raščlanjivanje odgovora možemo koristiti ugrađenu JratePath notaciju karatea.

Zahtijevajte ulančavanje s više API poziva

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

U gornjem primjeru upućuje se prvi poziv i authId se raščlanjuje iz odgovora i sprema u varijablu koja se naziva authId. Zatim zamjenjujemo drugu korisnu težinu s authId dobavljenim u prvom pozivu. Zatim koristimo novu korisnu težinu za slanje na sljedeći API poziv.

Kako čitati predloške zahtjeva i pozivati ​​druge datoteke značajki

Naše scenarije možemo učiniti ponovno upotrebljivima i pozvati ih iz drugih datoteka značajki. U ovom primjeru možemo stvoriti 'generičku' datoteku create-user.feature gdje možemo poslati zahtjev za kreiranje korisnika, ali s drugim tijelom zahtjeva

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

Imajte na umu da u gornjem primjeru koristimo '__arg' kao zahtjev za tijelom pošte.

Tada možemo nazvati gornju datoteku značajki i proslijediti traženo tijelo posta, koje zauzvrat možemo pročitati iz predloška

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

Gornji kôd čita predložak koji se nalazi na lokaciji com/example/templates/idm/idm-create-user-template.json i pohranjuje je kao JSON varijablu koja se naziva myReq

Tada možemo poslati JSON varijablu u drugu datoteku značajki pomoću metode poziva.

Predložak izgleda

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

Kako čitati druge značajke - primjer 2

Možemo pročitati određenu varijablu u pozvanoj datoteci značajki koja se prenosi iz pozivne datoteke značajke

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

Imajte na umu da u gornjem primjeru koristimo '__arg.emailAddress' kao zahtjev za tijelom posta. Zanima nas samo slanje adrese e-pošte kao zahtjeva

Tada možemo nazvati gornju datoteku značajki i proslijediti traženo tijelo posta, koje zauzvrat možemo pročitati iz predloška

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

Gornji kôd izdvaja polje pošte iz JSON predloška. Kada varijablu proslijedimo drugoj datoteci značajke, ona mora biti tipa JSON, tako da varijabla emailAddress mora biti valjani JSON.

Tada možemo poslati JSON varijablu u drugu datoteku značajki pomoću metode poziva i poslati JSON varijablu, u ovom slučaju, emailAddress.

Stvorite klasu Test Runner

Možemo izvršiti scenarije u datoteci značajki pomoću mavena (što je korisno za pokretanje testova u CI okruženju)

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

Gornji kôd pokreće sve datoteke značajki koje su označene kao '@FR', ali ignorira sve testove koji su označeni kao '@ignore'.

Također stvara izvještaj o krastavcu za vizualizaciju rezultata probnih vožnji.

Pokrenite testove iz naredbenog retka ili CI

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

Ovdje izvodimo klasu TestRunner_FR i postavljamo okruženje kao inscenaciju.

Izvršite JavaScript u datoteci značajke

U datoteci značajki imamo mogućnost izvršenja i javascripta

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)

Gornji kod generira slučajni niz duljine 10 i sprema ga u varijablu koja se naziva sessionId.

Podaci vođeni testovima

Budući da Karate sjedi na vrhu krastavca, testiranje na temelju podataka dolazi kao zadano

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

Gornji primjer koristi ključne riječi Okvir scenarija krastavca i Primjeri za stvaranje testova na temelju podataka. Za čitanje svakog parametra koristimo kutne zagrade

Nazovite Javu iz datoteke značajke

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

Gornja datoteka značajke poziva Java metodu u klasi koja se zove StringUtil. Zatim sprema odgovor tog poziva na varijablu otpCode.