step argument transformations specflow tables
Tutorial de transformare a argumentelor pas și tabele de flux de specificații:
Tutorialul nostru precedent Specflow ne-a informat despre toate Legături, cârlige și reutilizare în comun detaliat. Aici, în acest tutorial, vom explora mai multe despre Step Argument Transformations în Specflow.
Simțiți-vă liber să citiți documentele noastre Ghid complet de formare Specflow pentru începători pentru o înțelegere clară a conceptului. Caracteristica Step Argument Transformation din Specflow, permite utilizatorului să furnizeze transformări personalizate pentru parametrii furnizați în Pași.
Permite adăugarea logicii personalizate pentru a converti parametrii de intrare într-un parametru specific. De exemplu, puteți crea direct un obiect de clasă din parametri și puteți returna obiectul construit din funcția de transformare.
O altă caracteristică a Specflow pe care o vom analiza este Specflow Tables, care permite transmiterea datelor de intrare sub formă de tabelă cu un singur pas, iar ajutoarele de tabelă pot să fie mapate direct la o instanță Object, după cum doriți.
Priveste filmarea:
Iată un tutorial video despre Transformările argumentului pas și tabelele Specflow:
Ce veți învăța:
Etape Argument Transformări
Pentru a înțelege transformările argumentelor într-un mod mai bun, să încercăm mai întâi să ne dăm seama în ce fel Specflow corespunde parametrilor. După cum am văzut în articolele noastre anterioare, pentru exemplul de căutare YouTube, treceam termenul de căutare ca parametru pentru scenariul de executat.
Potrivirea parametrilor se întâmplă, de obicei, printr-o expresie regulată, iar regexul de potrivire are ca rezultat setarea parametrului metodei la termenul de căutare furnizat în pas.
Să încercăm mai întâi să înțelegem care sunt conversiile acceptate implicit în Specflow și când transformările argumentelor pot fi utile.
Conversii acceptate
Specflow acceptă o mulțime de conversii din cutie, uitându-se la tipul de date în sine după potrivirea regex. Poate avea grijă automat de conversii precum - Șir, număr întreg, GUID, Enumere etc.
Să vedem mai jos un exemplu pentru unele dintre acestea:
Scenario: Get Transactions in my account Given I have entered customer name as Test Customer And I have entered customer account id as 0f8fad5b-d9cb-469f-a165-70867728950e And I select sorting order as DESCENDING And I select number of transactions to be displayed as 25 Then I should see my account transactions
În eșantionul de cod de mai sus, am evidențiat diferite tipuri de intrare pe care le trecem în pași, iar în implementările de pași, acestea sunt convertite în tipurile de date respective.
Să vedem mai jos implementările pasului pentru acestea (pentru simplitate, tocmai am făcut o consolă pentru fiecare dintre pașii care ilustrează faptul că argumentul furnizat este convertit automat la tipul așteptat):
(Given(@'I have entered customer name as (.*)')) public void GivenIHaveEnteredCustomerNameAsTestCustomer(String customerName) { Console.Out.WriteLine(customerName); } (Given(@'I have entered customer account id as (.*)')) public void GivenIHaveEnteredCustomerAccountIdAs(Guid accountId) { Console.Out.WriteLine(accountId.ToString()); } (Given(@'I select sorting order as (.*)')) public void GivenISelectSortingOrderAsAscending(SortOrder sortOrder) { Console.Out.WriteLine(sortOrder.ToString()); } (Then(@'I should see my account transactions')) public void ThenIShouldSeeMyAccountTransactions() { Console.Out.WriteLine('success!'); } (Given(@'I select number of transactions to be displayed as (.*)')) public void GivenISelectNumberOfTransactionsToBeDisplayedAs(int p0) { Console.Out.WriteLine(p0.ToString());
La executarea scenariului de mai sus, ieșirea tipărește cu succes toate valorile, indicând că conversia automată a argumentelor la tipurile de date așteptate a avut succes.
Așa arată rezultatul:
Given I have entered customer name as Test Customer Test Customer -> done: SupportedSpecflowConversions.GivenIHaveEnteredCustomerNameAsTestCustomer('Test Customer') (0.0s) And I have entered customer account id as 0f8fad5b-d9cb-469f-a165-70867728950e 0f8fad5b-d9cb-469f-a165-70867728950e -> done: SupportedSpecflowConversions.GivenIHaveEnteredCustomerAccountIdAs(0f8fad5b-d9cb-469...) (0.0s) And I select sorting order as DESCENDING DESCENDING -> done: SupportedSpecflowConversions.GivenISelectSortingOrderAsAscending(DESCENDING) (0.0s) And I select number of transactions to be displayed as 25 25 -> done: SupportedSpecflowConversions.GivenISelectNumberOfTransactionsToBeDisplayedAs(25) (0.0s) Then I should see my account transactions success! -> done: SupportedSpecflowConversions.ThenIShouldSeeMyAccountTransactions() (0.0s)
Transformări ale argumentelor
Să vedem un exemplu în acțiune pentru a înțelege acest lucru. Asistență, aveți o aplicație care convertește timpul dat și îl convertește în minute. Exemplu: Dacă intrarea utilizatorului este de 1 zi - ieșirea este - 1440, dacă intrarea utilizatorului este de 1 zi 2 ore 2 minute, atunci ieșirea ar trebui să fie 1562.
Acum, se poate vedea că, pentru a suporta diferite tipuri de intrări, va trebui să scrieți diferite implementări de legare în funcție de tipul de intrări. De exemplu: Pentru intrările care au doar parte de zi, va exista o implementare separată a pasului, pentru intrările care au o parte de zi, lună - va exista implementarea separată a etapelor etc.
Să vedem cum se poate implementa acest lucru printr-o implementare cu un singur pas prin transformarea Step Argument și intrarea furnizată este pur și simplu convertită în obiect cu marcaj de timp și returnată la pasul original care se numește transformarea pasului.
Gândiți-vă la aceasta ca la o scanare regex de prim nivel la intrarea dvs. care returnează valoarea parțial transformată la pasul de apelare.
Uitați-vă la fișierul de caracteristici care are 3 variante de intrare diferite, cu o singură transformare, transformându-l în obiect complet de timp și revenind înapoi.
Scenario: Convert timestamp to minutes - variant 1 Given I have entered 50 days into the timestamp to minute converter When I press calculate Then the result should be 72000.00 on the screen Scenario: Convert timestamp to minutes - variant 2 Given I have entered 1 day, 2 hours, 3 minutes into the timestamp to minute converter When I press calculate Then the result should be 1563.00 on the screen Scenario: Convert timestamp to minutes - variant 3 Given I have entered 1 day, 1 hour, 1 minute, 30 seconds into the timestamp to minute converter When I press calculate Then the result should be 1501.50 on the screen
Uitați-vă la valorile evidențiate în exemplul de cod de mai sus. Toate acestea vor avea grijă de aceeași transformare și rezultatul final va fi o valoare de intrare TimeSpan transformată care este trimisă înapoi la pasul de flux de specificații apelant.
Să vedem mai jos implementarea Transformării:
(StepArgumentTransformation(@'(?:(d*) day(?:s)?(?:, )?)?(?:(d*) hour(?:s)?(?:, )?)?(?:(d*) minute(?:s)?(?:, )?)?(?:(d*) second(?:s)?(?:, )?)?')) public TimeSpan convertToTimeSpan(String days, String hours, String minutes, String seconds) { int daysValue; int hoursValue; int minutesValue; int secondsValue; int.TryParse(days, out daysValue); int.TryParse(hours, out hoursValue); int.TryParse(minutes, out minutesValue); int.TryParse(seconds, out secondsValue); return new TimeSpan(daysValue, hoursValue, minutesValue, secondsValue); }
Pentru ca cadrul să știe că este o legare de transformare, StepArgumentTransformation Attribute trebuie adăugat la metoda de implementare a conversiei Argument.
Celelalte puncte importante care trebuie remarcate cu privire la conversia argumentelor sunt:
# 1) Etapa Transformările argumentelor se execută pentru fiecare etapă de potrivire, adică indiferent de tipul de pas, adică dacă este dat, când sau apoi, transformarea se va întâmpla pentru fiecare regex de potrivire.
#Două) În funcție de tipul de returnare al ieșirii transformate, dacă pasul de apelare efectiv nu are tipul de returnare potrivit pentru parametrul de intrare, atunci transformarea nu va avea loc.
Ceea ce înseamnă acest lucru este, să presupunem că pasul de apelare necesită o intrare transformată, dar are marcajul de timp menționat ca ceva care nu se potrivește cu tipul returnat al metodei transformate, atunci potrivirea regex va fi suprascrisă și conversia nu va avea loc.
Să analizăm implementarea apelului la pasul „Dat”:
private TimeSpan ts; (Given(@'I have entered (.*) into the timestamp to minute converter')) public void GivenIHaveEnteredDaysIntoTheTimestampToMinuteConverter(TimeSpan tsTransformed) { ts = tsTransformed; }
Uitați-vă la tipul de parametru de intrare aici, adică TimeSpan, care se potrivește cu tipul returnat de la pasul de transformare dacă acesta este schimbat cu alt tip. De exemplu, String, atunci conversia argumentelor nu se va întâmpla, iar potrivirea regex va fi suprascrisă de implementarea originală Step.
Pro Tip: Un punct important de remarcat aici este că întregul text care trebuie transformat ar trebui să fie alimentat / adaptat prin transformarea argumentului pasului. Prin urmare, pasul dat acum va înfășura toate formatele de intrare posibile într-un singur șir și transformarea regex îl va converti într-un obiect TimeSpan și va reveni înapoi.Tabelele Specflow
Tabelele Specflow sunt o modalitate de a trece o listă a valorilor la funcția de implementare pas. În articolele noastre anterioare, ne-am uitat la modul de implementare a testelor bazate pe date folosind schița scenariului și exemple. Dar asta a fost să executăm în primul rând scenariul cu intrări diferite.
Aici, în tabele, este vorba despre trecerea tuturor datelor simultan sub formă de tabelă la implementarea pasului care furnizează date.
De exemplu, luați în considerare un exemplu în care testați un sistem de gestionare a studenților și, pentru a crea un nou obiect student, vi se solicită să completați o mulțime de detalii precum prenumele, prenumele, vârsta, anul nașterii etc.
O modalitate este de a trece fiecare dintre aceste informații ca un pas separat, care va fi în esență o mulțime de cod boilerplate și, în fiecare etapă, veți ajunge la actualizarea aceluiași obiect care trebuie testat. O altă modalitate poate fi construirea unei regex complexe și încercarea de a transmite toate datele în același pas, dar este destul de predispus la erori și fulgiu.
Mese vin în ajutorul nostru aici. Toate datele de intrare legate de studenți pot fi trimise în aceeași etapă de implementare într-un mod frumos tabular prin caracteristica tabelă a specflow.
Să vedem mai jos un eșantion de cod pentru implementarea funcției și a etapelor:
Scenario: Pass data through Specflow tables for StudentInfo object Given I have entered following info for Student | FirstName | LastName | Age | YearOfBirth | | test | student | 20 | 1995 | When I press add Then i student should get added to database and entered info should be displayed on the screen
Datele din tabel sunt evidențiate în Pasul de scenariu de mai sus.
soapui întrebări și răspunsuri la interviu pentru experți
Specflow oferă o mulțime de TableHelpers, care permit direct caracteristici utile, cum ar fi crearea unei instanțe obiect din datele de intrare furnizate de utilizator, mai degrabă decât analizarea fiecărui câmp pe cont propriu.
Să vedem mai jos etapa de implementare:
private StudentInfo studInfo; (Given(@'I have entered following info for Student')) public void GivenIHaveEnteredFollowingInfoForStudent(Table table) { // converting supplied input data directly to instance of StudentInfo object studInfo = table.CreateInstance(); }
Uită-te la secțiunea evidențiată de mai sus. Iată doar o mică linie de cod, întregul obiect StudentInfo (care este un POCO care conține câmpurile de date ale elevilor, adică prenume, prenume, vârstă, anul nașterii etc.)
Câteva alte caracteristici / concepte legate de tabelele Specflow sunt prezentate mai jos:
# 1) Mesele pot fi orizontale sau verticale. Tabelele verticale seamănă mai mult cu perechile cheie-valoare, iar în scenariul de mai sus seamănă cu mapările nume-valoare, în timp ce tabelele orizontale conțin toate datele pentru un obiect într-un singur rând (la fel cum am văzut în exemplul nostru).
#Două) Tabelele verticale pot fi mapate la un singur obiect .NET, în timp ce tabelele orizontale pot fi mapate la un set sau colecție de obiecte.
# 3) Fiecare valoare de câmp din tabel ar trebui să fie atomică, deoarece va fi mapată la un singur câmp corespunzător din obiectul analizat.
Un punct important de remarcat aici este acela, chiar dacă tu generare automată legând pasul cu datele tabulare, generatorul de legare Specflow va ține cont automat de astfel de tipuri de intrare și îl va recunoaște ca date tabulare valide.
Concluzie
În acest articol, am încercat să explicăm 2 concepte importante și la îndemână în Specflow.
Primul pas este Etape Transformări ale argumentelor care permit conversii de tip personalizate pentru argumentele Specflow pentru a evita codul boilerplate (și permite scriptului de testare să arate mai modularizat și mai logic) și a doua caracteristică pe care am analizat-o este Tabelele Specflow care sunt utile când trebuie să treceți o mulțime de câmpuri / date într-un singur pas într-un format tabular ușor de utilizat.
În viitorul nostru tutorial, vom afla mai multe despre cum puteți genera automat documentație frumoasă folosind Specflow în diferite formate folosind instrumente open source precum Pickles, care pot servi o referință ușoară pentru toți factorii interesați ai proiectului.
PREV Tutorial | NEXT Tutorial
Lectură recomandată
- Implementare în MongoDB: Tutorial pas cu pas
- Instalarea pas cu pas și configurarea Appium Studio
- Specflow și Selenium Webdriver Exemplu de la capăt la capăt
- Un ghid pas cu pas pentru a integra QTP cu ALM / QC
- Top 15 Întrebări de interviuri populare Specflow
- Legături avansate, fluxuri de specificații partajate și acoperite, cârlige și reutilizare în trepte
- Instalați MongoDB pe Windows: un ghid pas cu pas
- Cum se integrează JIRA cu qTest: un ghid pas cu pas