step argument transformations specflow tables
Samouczek dotyczący transformacji argumentów krokowych i tabel specyfikacji przepływu:
Nasz poprzedni samouczek dotyczący Specflow poinformował nas o wszystkim Wspólne powiązania i zakresy, haki i ponowne wykorzystanie kroków szczegółowo. Tutaj, w tym samouczku, dowiemy się więcej o transformacjach argumentów krokowych w Specflow.
Zapraszam do przeczytania naszego Kompletny przewodnik szkoleniowy Specflow dla początkujących dla pełnego zrozumienia pojęcia. Funkcja Step Argument Transformation w Specflow umożliwia użytkownikowi zapewnienie niestandardowej transformacji parametrów dostarczonych w Steps.
Umożliwia dodanie niestandardowej logiki w celu konwersji parametrów wejściowych na określony parametr. Na przykład, możesz bezpośrednio utworzyć obiekt klasy z parametrów i zwrócić skonstruowany obiekt z funkcji transformacji.
Kolejną cechą Specflow, której przyjrzymy się, są Tabele Specflow, które umożliwiają przekazywanie danych wejściowych w formie tabelarycznej za pomocą jednego kroku, a pomocnicy tabel mogą je mapować bezpośrednio do instancji Object zgodnie z potrzebami.
Obejrzyj wideo:
Oto samouczek wideo dotyczący transformacji argumentów krokowych i tabel Specflow:
Czego się nauczysz:
Transformacje argumentów krokowych
Aby lepiej zrozumieć transformacje argumentów, spróbujmy najpierw dowiedzieć się, jak dokładnie Specflow dopasowuje parametry. Jak widzieliśmy w naszych poprzednich artykułach, na przykładzie wyszukiwania w YouTube przekazaliśmy wyszukiwane hasło jako parametr do wykonania scenariusza.
Dopasowywanie parametrów zwykle odbywa się za pomocą wyrażenia regularnego, a pasujące wyrażenie regularne powoduje ustawienie parametru metody na podany wyszukiwany termin w kroku.
Najpierw spróbujmy zrozumieć, jakie są domyślnie obsługiwane konwersje w Specflow i kiedy transformacje argumentów mogą być pomocne.
Obsługiwane konwersje
Specflow obsługuje wiele konwersji po wyjęciu z pudełka, patrząc na sam typ danych po dopasowaniu wyrażenia regularnego. Może automatycznie zająć się konwersjami, takimi jak - ciąg, liczba całkowita, identyfikator GUID, wyliczenia itp.
Zobaczmy przykład dla niektórych z nich poniżej:
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
W powyższym przykładzie kodu wyróżniliśmy różne typy danych wejściowych, które przekazujemy w krokach, a w implementacjach kroków są one konwertowane na odpowiednie typy danych.
Zobaczmy poniżej ich implementacje krokowe (dla uproszczenia właśnie wykonaliśmy konsolę dla każdego z kroków, aby zilustrować, że dostarczony argument jest automatycznie konwertowany na oczekiwany typ):
[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());
Po wykonaniu powyższego scenariusza dane wyjściowe pomyślnie wypisują wszystkie wartości, wskazując, że automatyczna konwersja argumentów na oczekiwane typy danych zakończyła się pomyślnie.
Tak wygląda wynik:
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)
Przekształcenia argumentów
Zobaczmy przykład w akcji, aby to zrozumieć. Support, masz aplikację, która konwertuje podany czas i zamienia go na minuty. Przykład: Jeśli wejście użytkownika to 1 dzień - wyjście to - 1440, jeśli wejście użytkownika to 1 dzień 2 godziny 2 minuty, to na wyjściu powinno być 1562.
Teraz widać, że aby obsługiwać różne typy danych wejściowych, trzeba będzie napisać różne implementacje powiązań w zależności od typu danych wejściowych. Na przykład: Dla danych wejściowych mających tylko porę dnia będzie oddzielna implementacja krokowa, dla wejść mających część dzienną, miesięczną - będzie oddzielna implementacja krokowa itp.
Zobaczmy, jak można to zaimplementować za pomocą jednoetapowej implementacji poprzez transformację argumentu kroku, a podane dane wejściowe są po prostu konwertowane na obiekt znacznika czasu i zwracane do pierwotnego kroku, który jest nazywany transformacją krokową.
Potraktuj to jako skanowanie wyrażeń regularnych pierwszego poziomu do danych wejściowych, które zwraca częściowo przekształconą wartość do kroku wywołującego.
Przyjrzyj się plikowi funkcji, który ma 3 różne warianty wejściowe, z pojedynczą transformacją, konwertując go na kompletny obiekt czasu i wróć.
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
Spójrz na podświetlone wartości w powyższym przykładzie kodu. Wszystkie te zostaną uwzględnione w tej samej transformacji, a wynikiem końcowym będzie przekształcona wartość wejściowa TimeSpan, która jest wysyłana z powrotem do wywołującego kroku Specflow.
Przyjrzyjmy się poniższej implementacji Transformacji:
[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); }
Aby struktura wiedziała, że jest to powiązanie transformacji, atrybut StepArgumentTransformation musi zostać dodany do metody implementującej konwersję Argument.
Inne ważne punkty, na które należy zwrócić uwagę w odniesieniu do konwersji argumentów, to:
# 1) Transformacje argumentów kroku są wykonywane dla każdego pasującego kroku, tj. Niezależnie od typu kroku, tj. Czy jest dany, kiedy czy wtedy, transformacja nastąpi dla każdego pasującego wyrażenia regularnego.
#dwa) W zależności od typu zwracanego przekształconego wyjścia, jeśli rzeczywisty krok wywołujący nie ma pasującego typu zwracanego dla parametru wejściowego, transformacja nie nastąpi.
Oznacza to, że przypuśćmy, że krok wywołujący wymaga przekształconych danych wejściowych, ale ma wspomniany znacznik czasu wejścia jako coś, co nie pasuje do typu zwracanego przez przekształconą metodę, wtedy dopasowanie wyrażenia regularnego zostanie nadpisane i konwersja nie nastąpi.
Przyjrzyjmy się implementacji wywołania kroku „Given”:
private TimeSpan ts; [Given(@'I have entered (.*) into the timestamp to minute converter')] public void GivenIHaveEnteredDaysIntoTheTimestampToMinuteConverter(TimeSpan tsTransformed) { ts = tsTransformed; }
Spójrz na typ parametru wejściowego tutaj, tj. Jego TimeSpan, który pasuje do typu zwróconego z kroku transformacji, jeśli zostanie zmieniony na inny typ. Na przykład String, wtedy konwersja argumentów nie nastąpi, a dopasowanie wyrażenia regularnego zostanie nadpisane przez oryginalną implementację Step.
Wskazówka dla profesjonalistów: Ważną kwestią, na którą należy zwrócić uwagę, jest to, że cały tekst, który ma zostać przekształcony, powinien zostać dostarczony / dopasowany przez krokową transformację argumentów. W związku z tym Given krok zawinie teraz wszystkie możliwe formaty wejściowe w jeden ciąg, a wyrażenie regularne transformacji przekonwertuje je na obiekt TimeSpan i wróci z powrotem.Tabele Specflow
Tabele Specflow są sposobem na przekazanie listy wartości do funkcji implementacji krokowej. W naszych poprzednich artykułach przyjrzeliśmy się sposobowi implementacji testów opartych na danych przy użyciu konspektu scenariusza i przykładów. Ale to było przede wszystkim wykonanie scenariusza z różnymi danymi wejściowymi.
Tutaj, w tabelach, chodzi o przekazanie wszystkich danych naraz w formie tabelarycznej do implementacji krokowej, która dostarcza dane.
Na przykład rozważ przykład, w którym testujesz system zarządzania uczniami i aby utworzyć nowy obiekt studenta, musisz podać wiele szczegółów, takich jak imię, nazwisko, wiek, rok urodzenia itp.
Jednym ze sposobów jest przekazanie każdej z tych informacji jako osobnego kroku, który będzie zasadniczo składał się z wielu standardowych kodów, a na każdym kroku zaktualizujesz ten sam obiekt, który należy przetestować. Innym sposobem może być zbudowanie złożonego wyrażenia regularnego i próba przekazania wszystkich danych w tym samym kroku, ale jest to dość podatne na błędy i niestabilne.
Tu z pomocą przychodzą nam stoły. Wszystkie dane wejściowe związane z uczniami mogą być przesyłane do tej samej implementacji kroku w przyjemny sposób tabelaryczny za pomocą funkcji tabeli w specyfikacji przepływu.
Zobaczmy poniżej przykładowy kod implementacji funkcji i kroków:
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
Dane tabeli są wyróżnione w powyższym kroku scenariusza.
qa pytania i odpowiedzi na rozmowę z liderem testowym
Specflow zapewnia wiele narzędzi TableHelpers, które bezpośrednio pozwalają na przydatne funkcje, takie jak tworzenie instancji obiektu z danych wejściowych dostarczonych przez użytkownika, zamiast samodzielnego analizowania każdego pola.
Zobaczmy poniżej krok implementacji:
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(); }
Spójrz na podświetloną sekcję powyżej. Oto tylko jedna mała linia kodu, cały obiekt StudentInfo (który jest POCO zawierającym pola danych ucznia, tj. Imię, nazwisko, wiek, rok urodzenia itp.)
Poniżej przedstawiono inne funkcje / koncepcje związane z tabelami Specflow:
# 1) Tabele mogą być poziome lub pionowe. Tabele pionowe bardziej przypominają pary klucz-wartość, aw powyższym scenariuszu bardziej przypominają odwzorowania nazwa-wartość, podczas gdy tabele poziome zawierają wszystkie dane obiektu w jednym wierszu (tak jak widzieliśmy w naszym przykładzie).
#dwa) Tabele pionowe można odwzorować tylko na pojedynczy obiekt .NET, natomiast tabele poziome można również odwzorować na zestaw lub kolekcję obiektów.
# 3) Każda wartość pola w tabeli powinna być niepodzielna, ponieważ zostanie odwzorowana na pojedyncze odpowiednie pole w analizowanym obiekcie.
Ważną kwestią, na którą należy zwrócić uwagę, jest to, że nawet jeśli ty generuj automatycznie powiązań krokowych z danymi tabelarycznymi, generator powiązań Specflow automatycznie uwzględni takie typy danych wejściowych i rozpozna je jako prawidłowe dane tabelaryczne.
Wniosek
W tym artykule próbowaliśmy wyjaśnić 2 ważne i przydatne pojęcia w Specflow.
Pierwszym krokiem jest Transformacje argumentów krokowych które pozwalają na konwersje typów niestandardowych dla argumentów Specflow, aby uniknąć standardowego kodu (i sprawiają, że skrypt testowy wygląda bardziej modularnie i logicznie), a druga funkcja, której przyjrzeliśmy się, to Tabele Specflow które przydają się, gdy trzeba przekazać wiele pól / danych w jednym kroku w przyjaznym dla użytkownika formacie tabelarycznym.
W naszym nadchodzącym samouczku dowiemy się więcej o tym, w jaki sposób można automatycznie generować piękną dokumentację za pomocą Specflow w różnych formatach przy użyciu narzędzi open source, takich jak Pickles, które mogą służyć jako łatwe źródło informacji dla wszystkich interesariuszy projektu.
POPRZEDNIA samouczek | NEXT Tutorial
rekomendowane lektury
- Wdrożenie w MongoDB: samouczek krok po kroku
- Instalacja i konfiguracja Appium Studio krok po kroku
- Specflow i Selenium Webdriver Przykład od końca do końca
- Przewodnik krok po kroku dotyczący integracji QTP z ALM / QC
- 15 najpopularniejszych pytań do wywiadów Specflow
- Zaawansowane powiązania współdzielone i zakresowe Specflow, haki i ponowne użycie kroków
- Zainstaluj MongoDB w systemie Windows: przewodnik krok po kroku
- Jak zintegrować JIRA z qTest: przewodnik krok po kroku