E-book
23.63
drukowana A5
32.94
Gherkin Guru

Bezpłatny fragment - Gherkin Guru

Automatyzacja testów


Objętość:
84 str.
ISBN:
978-83-8414-237-0
E-book
za 23.63
drukowana A5
za 32.94

Tytułem wstępu


Na wszystkich etapach procesu wytwarzania oprogramowania konieczna jest kontrola i zapewnienie jakości, realizowane poprzez rozbudowany proces testowania. Zazwyczaj testowaniem zajmują się dedykowane zespoły testerskie. Często w metodykach zwinnych członek zespołu testerskiego wchodzi także w skład zespołu projektowego, na bieżąco monitorując sytuację w projekcie i postępy programistów, czuwając nad właściwym zapewnieniem jakości aplikacji z punktu widzenia użytkownika końcowego.

Zespołom programistycznym zaleca się tworzenie testów jednostkowych na wczesnym etapie tworzenia oprogramowania, zapewniających jak największe pokrycie kodu.

Jednak śledząc sytuację rynkową, te procesy nadal nie są wystarczające dla zapewnienia satysfakcjonującego dla potencjalnego klienta poziomu jakości. Klienci biznesowi oczekują oprogramowania pozbawionego błędów funkcjonalnych i graficznych na poziomie pokrycia niemal stu procent. Wszystkie użyte w procesie tworzenia oprogramowania procesy nie są w stanie zapewnić takiego pokrycia. Niestety, coraz częściej dochodzi do sytuacji, w których całym ciężarem obarczany jest tester, jako jedno z ostatnich ogniw weryfikacji oprogramowania przed dostarczeniem wersji dla klienta końcowego.

Na tym etapie należy zdać sobie sprawę z faktu, że żadna technika, metodyka, żaden, nawet dokładnie zaplanowany i poddany kontroli proces, nie uwolni oprogramowania od wszystkich błędów. Jako zespół projektowy, uczestnicy procesu mogą jedynie wdrażać rozwiązania, zmniejszające potencjalne ryzyko do minimum.

Jednym z takich rozwiązań jest automatyzacja testów po stronie zespołu zapewnienia jakości lub zespołu testerskiego (często mylnie oba te stanowiska są łączone z punktu widzenia definicji i odpowiedzialności na danym stanowisku).

Automatyzacja, jako jeden z etapów procesu wytwarzania oprogramowania oczywiście również nie zapewnia stuprocentowego pokrycia kodu aplikacji i uwolnienia go od błędów. Jednak jest przy tym elementem który, jeżeli dobrze zaprojektowany, może znacznie odciążyć zespół projektowy i częściowo przerzucić odpowiedzialność na procesy, stojące po stronie maszyny. Integracja z narzędziami i procesami CI zapewnia kontrolę błędów na poziomie budowania aplikacji, tj. przetwarzania dostarczonego przez programistów kodu na kod zrozumiały dla maszyny w sposób ciągły i zautomatyzowany. Niniejsze rozwiązanie, dopasowane do potrzeb zespołu projektowego na podstawie wieloletnich doświadczeń jest elastyczne i może zostać wdrożone w dowolnym projekcie biznesowym.

Na przestrzeni lat i rozwoju metodyk zarządzania projektami ewoluowały również różnorodne podejścia do testów automatycznych. Największym problemem, z którym borykają się zespoły projektowe, jak również firmy informatyczne, jest brak jednoznacznego narzędzia, gwarantującego skalowalność do każdej z metodyk oraz języków programowania, stosowanych w tych firmach. Problem ten jest z reguły dystrybuowany na zespoły testerskie lub programistyczne, tym samym przerzucając odpowiedzialność za rzetelne i stuprocentowe pokrycie kodu testami.

Jak wiadomo, testy same w sobie nie stanowią o niezawodnym działaniu aplikacji, a procent pokrycia kodu skryptami nie jest wyznacznikiem jakości. Przykładowo, system może być pokryty w 90% skryptami testowymi, to jednak nie zapewnia zespołu testerskiego ani też klienta o tym, że aplikacja pozbawiona jest błędów. Nie da się bowiem żadnego programu przetestować w 100%, nie da się także przewidzieć wszystkich możliwych scenariuszy użytkownika.

Jednym ze sposobów jest wspomniany już Gherkin, język dla scenariuszy testowych, który przy współpracy z BDD daje możliwość zachowawczego projektowania przypadków testowych oraz samych funkcjonalności systemu. Jednakże to nadal nie rozwiązuje problemu. Klienci potrzebują działającego, gotowego rozwiązania, w zasadzie od zaraz. W większości przypadków klienta nie stać na szkolenie od podstaw zespołu specjalistów do spraw automatyzacji, tym bardziej w tym jednym, konkretnym języku aplikacji, w którym powstaje dany projekt. Brak skalowalności większości rozwiązań implikowałby konieczność nauki każdego z języków programowania dla projektu, a co za tym idzie coraz większy narzut kosztowy w miarę rozwoju technologii bez rozsądnej stopy zwrotu z inwestycji.

W kolejnych rozdziałach przedstawiam opis podejść i narzędzi, których użyjemy do stworzenia naszego frameworka testów automatycznych. Jeżeli jesteś już z nimi zaznajomiony, proponuję, abyś przeszedł do części praktycznej, w którym przejdziemy przez kolejne etapy instalacji i konfiguracji środowisk, od pierwszej do ostatniej linii kodu, aż po uruchomienie skryptów testowych.

Zachęcam przy tym do zapoznania się z pozycjami z bibliografii, które na pewno rozwiną wiedzę na temat metodyk, jak i przedstawionych rozwiązań.

Behave Driven Development

Behave Driven Development jako jedna z technik wytwarzania oprogramowania poprzez definiowanie zachowań staje się coraz bardziej popularnym podejściem. Daje ono szeroki wachlarz rozwoju procesów. Z roku na rok przybywa też narzędzi, wspomagających BDD.

Pojęcie po raz pierwszy zdefiniowane przez Dana Northa łączy testy jednostkowe tworzone w podejściu Test Driven Development (TDD) i testy akceptacyjne User Acceptance Tests (UAT). Celem jest poznanie potrzeb i oczekiwań użytkownika docelowego w rozumieniu klienta i stworzenie oprogramowania, które te oczekiwania spełnia.

W podejściu BDD testy akceptacyjne pisane są najczęściej z użyciem języka Gherkin, w oparciu o historyjki użytkownika, skupiające się na roli, funkcji i wynikających z nich korzyści w rozumieniu funkcjonalności.

Parafrazując Janet Gregory, takie działanie ma na celu wytworzenie oprogramowania dopasowanego do potrzeb użytkownika już w początkowej fazie procesu wytwarzania oprogramowania. Cel ten sam w sobie nie jest łatwy do osiągnięcia, jeżeli nawet nie niemożliwy, jednakże takie podejście zapewnia zminimalizowanie wystąpienia błędów w późniejszych fazach.

Jak dodaje Liz Keogh, pojęcie „zachowanie” (behave) pozwala na eksplorację niejednoznacznych obszarów aplikacji (jak również przypadków brzegowych), których nie da się opisać zero-jedynkowo (jest lub nie ma), poprzez odwołanie się do kontekstu użytkownika. Tym samym pozwala na jednoznaczną definicję przypadków testowych dla niejednoznacznych wymagań klienta.

Page Object Pattern

Podczas pisania testów stron internetowych należy odnosić się bezpośrednio do konkretnych elementów tych stron, w celu otwarcia danego linku, czy weryfikacji wyświetlania elementów. Podczas projektowania skryptów, które działają bezpośrednio na kodzie HTML testowanej aplikacji, narażone są one na zmiany występujące po stronie UI. Zastosowanie Page Object Pattern wspomaga proces tworzenia takich przypadków. Ukrywa obiekt strony, nadpisuje kod HTML lub jego fragment tzw. API specyficznym dla aplikacji, umożliwiając manipulację takimi elementami bez potrzeby bezpośrednich odwołań do kodu HTML.

Obiekty strony kierują się podstawową zasadą, by klient oprogramowania „robił” wszystko i „widział” wszystko, co człowiek (użytkownik). Zapewnia on również interfejs, który jest łatwy w programowaniu i ukrywaniu podstawowych widżetów i elementów w oknie aplikacji. Przykładowo, aby uzyskać dostęp do pola tekstowego, konieczne są metody typu „accessor”, przyjmujące i zwracające ciąg znaków. Elementy wyboru powinny używać zmiennych typu boolean, a przyciski muszą być reprezentowane nazwami metod zorientowanych na ich działanie. W założeniu obiekt strony powinien otoczyć całą tę mechanikę odpowiedzialną za znalezienie, identyfikację i manipulowanie danymi po stronie GUI. Zmiana konkretnej akcji kontroli elementu nie powinna wymusić zmiany interfejsu strony.

Mimo użycia terminu „strona”, obiekty strony nie powinny być budowane dla każdej ze stron testowanej lub tworzonej aplikacji, a dla kluczowych jej elementów. Przykładowo, strona będąca galerią zdjęć, zawierająca kilka albumów zawierałaby obiekt z listą albumów. Te obiekty zawierałyby w sobie kilka obiektów po stronie albumu. Istniałby także obiekt strony nagłówka i obiekt strony stopki. Takie skomplikowanie hierarchii obiektów interfejsu użytkownika występuje tylko w celu ustrukturyzowania interfejsu użytkownika. Obiekty będące komponentami tej hierarchii nie powinny być ujawniane przez obiekty stron. Podstawową zasadą jest takie modelowanie struktury na stronie, która ma sens dla użytkownika aplikacji. W przypadku akcji nawigowania do innej strony obiekt początkowy powinien zwrócić kolejny (nowy) obiekt dla otwartej strony.

Podsumowując, operacje na obiektach strony powinny zwracać podstawowe typy zmiennych (string, data, boolean) lub inne obiekty stron.

Obiekty stron w rozumieniu Page Object Pattern są często używane podczas testowania, ale nie powinny zawierać elementów weryfikacyjnych same w sobie. Są one odpowiedzialne jedynie za zapewnienie dostępu do niższej warstwy kodu. To po stronie testów leży zapewnienie logiki weryfikacyjnej.

Ten sam schemat ma zastosowanie nie tylko w przypadku stron internetowych czy logiki testów. Jak twierdzi Mark Fowler, spotkał się on z pozytywnym zaadaptowaniem obiektów stron w efektywnym ukrywaniu detali Java Swing UI. Jest także przekonany o powszechnym zastosowaniu Page Object Pattern w wielu innych rozwiązaniach i frameworkach bazujących na UI.

Problemy ze współbieżnością to kolejny temat, w którym można zastosować obiekty stron, chociażby poprzez ukrywanie asynchronii w operacjach asynchronicznych, które nie są widoczne dla użytkownika jako asynchroniczne. Możliwa jest także enkapsulacja wątków w interfejsie użytkownika, gdzie konieczne jest alokowanie zachowania między interfejsem użytkownika i wątkami zależnymi.

Obiekty stron to modelowy przykład enkapsulacji — ukrywają szczegóły struktury UI i odniesienia do innych komponentów strony lub testów. Dobrą manierą projektowania jest odnajdywanie takich sytuacji w miarę rozwoju kodu. Podobnie jak w przypadku enkapsulacji, daje to dwie niezaprzeczalne korzyści. Jedną z nich jest ograniczanie logiki manipulującej interfejsem użytkownika w jednym miejscu poprzez jej modyfikację bez wpływu na inne składniki systemu. Drugą z korzyści jest łatwiejsze zrozumienie kodu klienta lub testów z uwagi na intencje, by skupić się na funkcji kod lub testu a nie detalach interfejsu użytkownika.

Wybór języka programowania

W celu prawidłowej implementacji frameworka konieczny jest wybór właściwego języka programowania. O ile skalowane rozwiązanie można zaimplementować dla dowolnego języka programowania (wobec wielu opinii najlepiej takiego, w jakim stworzony został cały testowany projekt) ważne jest, aby prace nad rozwiązaniem rozpocząć od łatwego w nauce i intuicyjnego języka, na tyle elastycznego, aby późniejszy rozwój za pomocą innych języków był dość intuicyjny.

W przypadku popularnego podejścia tworzenia przypadków testowych w języku projektu, na każdym etapie w przypadku problemów z dalszym rozwojem skryptów, łatwo jest uzyskać niezbędną wiedzę od programisty zaangażowanego w powstawanie aplikacji. Jednakże brak znajomości tego języka programowania implikować może dalsze problemy po stronie testera, mające wpływ na cały zespół — konieczna jest dodatkowa nauka danego języka, powstają opóźnienia w dostarczeniu kodu z uwagi na zaangażowanie zespołu w naukę i natłok pytań ze strony zespołu testerskiego. To może prowadzić do porażki całego przedsięwzięcia, a w konsekwencji do znacznych strat, głównie finansowych.

Jednym z najprostszych rozwiązań jest identyfikacja potrzeb zespołu i klienta. Dostosowanie języka programowania do strony, która będzie właścicielem skryptów i będzie odpowiadała za ich dalszy rozwój, jest najodpowiedniejszym podejściem.

Dla zespołu testerskiego, tworzącego i utrzymującego testy automatyczne dobrym podejściem jest użycie języka programowania, w którym napisane są testy dla innych projektów, które tworzy firma zatrudniająca. Testy tworzone z pomocą Selenium nie wymagają tego samego języka do ich tworzenia, co testowana aplikacja.

Dla zespołu programistycznego warto zastanowić się nad perspektywą utrzymania kodu, to implikuje z kolei prosty wniosek, aby testy tworzyć w języku, w którym tworzona jest testowana aplikacja.

Decyzja wyboru języka programowania testów automatycznych nie jest łatwa. Obarczona jest dalszymi konsekwencjami, które warto przewidzieć i omówić przed przystąpieniem do właściwych prac, w taki sposób, aby spełnić oczekiwania zarówno zespołu projektowego, jak i klienta. Wszystko to zapewni późniejszy sukces i ułatwi dalsze prace.

W niniejszym projekcie został użyty język Python, jako wyjściowa dla dalszych prac z uwagi na łatwość nauki przez osoby początkujące (późniejsze zaznajomienie się z innymi językami programowania także nie powinno nastręczać problemów), dostępność rozwiązań, a także fakt znajomości tego języka programowania przez autora.

Gherkin

Gherkin jest językiem, który rozumieją interpretery Cucumber, Behave i wiele innych. Umożliwia opisywanie zachowań aplikacji bez zagłębiania się w szczegóły, dotyczące implementacji kodu. To sprawia, że jest czytelny, zrozumiały dla biznesu, specyficzny dla domeny. Zapewnia wsparcie dla dwóch dziedzin — dokumentacji projektowej wszelkiego typu oraz automatyzacji testów.

Gramatyka specyficzna dla tego języka zdefiniowana jest w gramatyce Treetop, która jest częścią bazy kodu Cucumber. Gramatyka ta istnieje w wielu odmianach, specyficznych dla wielu języków mówionych. Oznacza to już ponad 60 języków używanych na całym świecie. Umożliwia to więc swobodny rozwój spisywanych scenariuszy w dowolnym języku, którym posługuje się zespół projektowy lub klient biznesowy.

Składnia języka Gherkin podobna jest do składni Python oraz YAML, opiera się na użyciu wcięć (akapitów) i znaków nowej linii dla zdefiniowania struktury. Znaki nowej linii definiują koniec danego kroku scenariusza.

Zakłada się użycie składni anglojęzycznej w prezentowanym projekcie.

Struktura pojedynczego pliku feature (zawierającego opisy scenariuszy dla danej funkcjonalności) przedstawia się więc następująco:


Feature: Zdanie opisujące w sposób zwięzły funkcjonalność

In order to przedstawienie wartości biznesowej

As an rola użytkownika systemu

I want to uzyskanie rezultatów, które prowadzą do określonego celu (realizacji wyników funkcjonalności)


Scenario: Przykładowa, możliwa do określenia, sytuacja biznesowa

Given pewien wstępny warunek

And dodatkowy warunek wstępny

When pewna akcja wykonana przez użytkownika (kliknij, przejdź do strony, itp.)

And kolejna akcja wykonana przez użytkownika

And kolejna akcja wykonana przez użytkownika (ich ilość może być dowolna)

Then osiągnięcie pewnego testowalnego wyniku (w części tej następuje sprawdzenie poprawności wykonania scenariuszy z części „When” przy założeniu wstępnych warunków części „Given”)

And weryfikacja kolejnego zdarzenia


Scenario: Inna sytuacja biznesowa

Treść scenariusza


Możliwe jest użycie mechanizmu komentarzy w postaci linii, rozpoczynających się znakiem „#”, zawierających dowolną ilość tekstu komentarza.


Interpreter na podstawie struktury dzieli na wejściu zawartość tekstową na funkcjonalności, scenariusze oraz ich składowe — poszczególne kroki testów. Po uruchomieniu zestawu testów tekst, znajdujący się po słowie kluczowym „Given”, „And”, „When”, „Then” dla poszczególnych scenariuszy dopasowywany jest do bloku kodu wykonawczego nazywanego „definicjami kroku”, znajdującymi się w plikach „steps”.

Selenium

Selenium jest jednym z popularnych, jeżeli nie najpopularniejszym rozwiązaniem dla testów automatycznych w ujęciu testowania UI aplikacji web.

Zapewnia narzędzia do nagrywania i odtwarzania skryptów w sposób prosty i zrozumiały, bez konieczności posiadania zaawansowanej wiedzy z dziedziny programowania. Prosty eksport tak przygotowanych skryptów daje duże możliwości adaptacyjne do dowolnej platformy czy też języka programowania dzięki pseudojęzykowi Selenese. Języki programowania, wspierane przez Selenium: C#, Groovy, Java, Perl, PHP, Python, Ruby, czy scala, przewyższają dalece innych konkurentów rynkowych, nic więc dziwnego, że duże korporacje, tworzące oprogramowanie dla szerokiej gamy konsumentów indywidualnych i biznesowych, wybierają właśnie to narzędzie.

Testy przygotowane w Selenium, czy to za pomocą narzędzi nagrywających, czy za pomocą języka skryptowego, mogą zostać w łatwy sposób uruchomione w wielu popularnych, nowoczesnych przeglądarkach na urządzeniach stacjonarnych i przenośnych, dzięki czemu idealnie wpasowuje się w ideę niniejszego projektu.

Selenium przygotowane zostało z myślą o systemach Windows, Linux, OS X, nie jest więc uzależnione od platformy stosowanej przez producenta oprogramowania.

Jednocześnie Selenium jest narzędziem w pełni darmowym, rozpowszechnianym na licencji open-source Apache 2.0.

Behave

Behave jest interpreterem języka Gherkin dla Behave Driven Development, przygotowanym z myślą o języku Python.

Behave wykorzystuje testy pisane językiem naturalnym, użytkowym, z myślą o łatwej kooperacji pomiędzy programistami, testerami i biznesem, niekoniecznie zorientowanym na języki programistyczne w projekcie informatycznym.

Na rynku istnieje szereg podobnych narzędzi i interpreterów, dedykowanych konkretnym językom programowania i frameworka. Poniżej przedstawiono porównanie narzędzi dedykowanych językowi Python, z zaznaczeniem plusów i minusów w odniesieniu do użytego w projekcie Behave.

Jednym z narzędzi jest popularny dla Ruby i Java Cucumber. Może on być także użyty do uruchomienia testów napisanych w języku Python. Używa biblioteki „rubypython” do uruchomienia interpretera Python wewnątrz procesów Ruby. Biblioteka ta została porzucona jakiś czas temu i nie posiada już wsparcia, dlatego też Cucumber używany jest częściej z językiem Java i Ruby, aniżeli z Pythonem. Oczywistą decyzją jest użycie narzędzia w pełni wspieranego przez Python, napisanego z użyciem tego języka. Rozwiązanie to nie zostało więc użyte do stworzenia niniejszego projektu.

Kolejnym interpreterem języka Gherkin jest Lettuce. Jest on podobny do narzędzia Behave jako jedno z rozwiązań przepisanych bezpośrednio z Cucumber. Podstawowa różnica pomiędzy Lettuce i Behave to użycie jedynie dekoratora @step, zamiast wielu dekoratorów typu @given, @when, @then, @step dla zróżnicowanych kroków testów.

Lettuce nie wspiera także opcji tagowania, tak potrzebnej w tworzonym projekcie frameworka testów automatycznych. Kod definicji kroków może być przechowywany gdziekolwiek w folderze „features” — daje to nieco więcej swobody, niż w przypadku Behave, jednak poniekąd zaprzecza idei użycia Page Object Pattern w konkretnym schemacie. Innym problemem w Lettuce jest brak czyszczenia zmiennej globalnej „world” pomiędzy kolejnymi wykonaniami scenariuszy typu „outline”, przez co konieczne jest dodatkowe obsłużenie tego typu sytuacji. Behave czyści ten rodzaj zmiennych domyślnie pomiędzy każdym scenariuszem.

Na rynku istnieje także wtyczka Freshen. Jednak z uwagi na pojawiające się problemy, takie jak:

— Integracja z „nose runner” powodująca trudności w debugowaniu wyjątków porażki w testach,

— Wyniki wykonania skryptów, obsługiwane przez „nose” nie są czytelne, implikuje to konieczność instalacji dodatkowych wtyczek

— Zmienne kontekstowe nie są tak elastyczne, jak w przypadku Behave — zmiana ich nazwy czy przenoszenie wymaga dodatkowych nakładów pracy

— Nazwy kroków muszą być unikatowe, nawet jeżeli używają dekoratorów różnego typu kroków

— Brak obsługi i kontroli Before / After scenario — jedynie Before — powoduje konieczność użycia operacji „atexit” lub „teardown” pozostawia skrypty bez pełnej kontroli

Z uwagi na powyższe problemy, Lettuce nie jest brany pod uwagę jako narzędzie, które mogłoby zostać użyte w niniejszym projekcie.

PyCharm

Jako zintegrowane środowisko programistyczne dedykowane językowi Python, PyCharm oferuje edycję i analizę kodu źródłowego, moduł debugowania kodu w formie graficznej, moduł uruchomieniowy dla testów jednostkowych (i automatycznych) oraz zintegrowaną kontrolę wersji.

PyCharm działa na wielu platformach. Zapewnia wsparcie dla systemów Windows, Linux oraz OSX. Wydawany jest zarówno w wersji Community Edition (darmowej), jak i w wersji Professional. W projekcie użyto wersji Professional ze względu na pełne wsparcie wtyczek, koniecznych do jego realizacji.

Przeczytałeś bezpłatny fragment.
Kup książkę, aby przeczytać do końca.
E-book
za 23.63
drukowana A5
za 32.94