Page Object Pattern + Fluent Interface

Page Object Pattern jest jednym z częściej używanych wzorców w testach interfejsowych. Nie bez powodu – pozwala świetnie odzwierciedlić architekturę aplikacji w testach, zapobiega także niepotrzebnemu powtarzaniu kodu, jeżeli pewne struktury powtarzają się w wielu miejscach aplikacji (na przykład wspólne dla każdej podstrony menu).

Jeden Page Object powinien odwzorowywać jeden logiczny fragment aplikacji. Posługując się przytoczonym wyżej przykładem menu, klasa „Menu” będzie zawierać wszystkie pozycje w menu (a jeśli ma ono strukturę hierarchiczną, także i zagnieżdżone, kolejne Page Objecty).

Każda metoda w klasie udostępnia oferowane przez obiekt usługi (np. rozwinięcie i zwinięcie podmenu, wybór pozycji itd.).

W tym wzorcu metoda zawsze zwraca Page Object (z czego korzysta kolejny wzorzec: Fluent Interface). Dzięki temu w testach można stworzyć bardzo elegancko wyglądającą ścieżkę wędrówki pomiędzy podstronami.

Z pozoru te same akcje mogą zwracać różne wyniki, np. dwie metody:


public AdminPage LoginWithCorrectCredentials(string userName, string password);

public ErrorPage LoginWithIncorrectCredentials(string userName, string password);

Asercje wykonywane są w testach, nie w klasach Page Objectowych.

Sterownik (WebDriver) może być przekazywany w konstruktorze Page Object.

Czytaj więcej

Dobre praktyki w testach Selenium

kawa_selenium

Dobre praktyki w automatycznych testach w Selenium:

  • Podstawowa zasada – używanie aktywnego czekania (WebDriverWait, wait.Until, ImplicitlyWait itd.) zamiast Thread.Sleep, który spowalnia testy, nie dając jednocześnie gwarancji, że zastosowana przerwa jest odpowiednio długa (jest wiele artykułów na ten temat w sieci).
  • Wyszukiwanie elementów na stronie za pomocą selektorów CSS (By.CssSelector) lub identyfikatorów ID lub name (By.Id, By.Name) – taka metoda jest o niebo szybsza niż wyszukiwanie przez XPATH.
  • Używanie wzorca Page Object.

Oraz kilka dobrych praktyk, które mogą być stosowane ogólnie w testach, nie tylko Selenium:

  • DRY – Don’t Repeat Yourself – niepowielanie tego samego kodu poprzez tworzenie np. zestawów funkcji bibliotecznych, dobre rozplanowanie architektury testów, korzystanie z dostarczanych przez framework metod jak Test Setup, Teardown (np. ustawienie przeglądarki przed testami, zamknięcie przeglądarki po testach).
  • Behaviour Driven Testing – testy będą „bliżej autentycznego użytkownika”.
  • Logowanie błędów! Bardzo przydatne w przypadku testów uruchamianych na środowiskach Continuous Integration, gdzie jeśli testy nie mają logów, jedyną informacją, jaką dostarczą będzie „test nie przeszedł, coś nie działa”. Warto logować ścieżkę wykonanych akcji wraz z parametrami metod oraz informacje o środowisku na którym uruchomiono testy: system, przeglądarka, baza danych itd., godzina – a nuż błąd pojawia się na przykład pomiędzy 23 a 1 dnia następnego?, itd.
  • Screenshoty – jeżeli jest taka możliwość (a w Selenium jest) – stanowią wspaniałe źródło informacji o błędach. Nie wszystko da się wyczytać z logu – informacja typu „nie da się kliknąć kontrolki x” niewiele mówi – tymczasem „obraz wyraża więcej niż tysiąc słów”, a na screenie dokładnie widać, co się wydarzyło.

Może się wydawać (nadal!), że testy są niepotrzebne, są stratą czasu. Tymczasem są one w stanie wykryć defekty już na bardzo niskim poziomie (testy jednostkowe). Jeżeli aplikacja boryka się z problemami dużego długu technicznego, złej architektury a klasy cechują się wysokim sprzężeniem, próby modyfikacji aplikacji „na siłę”, byle tylko pokryć ją testami mogą niestety narobić więcej szkody, niż pożytku. W takim przypadku lepiej sprawdzi się metoda małych kroków. Implementując nowe funkcjonalności w aplikacji warto rozważyć piszanie testów jednostkowych tylko do nowych partii aplikacji (TDD). Przymierzając się natomiast do dużych zmian w całej aplikacji warto przygotować jak najwięcej wysokopoziomowych testów czarnoskrzynkowych (funkcjonalnych, integracyjnych). Nawet jeśli ich implementacja byłaby kosztowna w sensie czasowym lub finansowym, warto to zrobić. Optymalnym rozwiązaniem jest zautomatyzowanie owych testów. Minimalnym – spisanie wszystkich wymagań stawianych aplikacji (np. w formie proponowanej przez BDD).

Inspirację do tworzenia nowych przypadków testowych można czerpać również z błędów zgłaszanych przez użytkowników. To bardzo dobre źródło informacji o tym, w jaki sposób użytkownicy naprawdę używają aplikacji. Dobrze zgłoszony błąd zawiera pełną ścieżkę czynności potrzebnych do zreprodukowania błędu. Po jego naprawieniu, warto ją zautomatyzować.

Czytaj więcej

Tymczasowa zmiana języka w terminalu Ubuntu

Moje Ubuntu było w wersji polskiej, co za tym idzie – komunikaty błędów w terminalu były po polsku, co utrudniało szukanie pomocy w sieci. Na szczęście język można zmienić tymczasowo na angielski, komendą:

LC_ALL=C bash

Jeśli natomiast chce się zmienić język na zawsze, trzeba wyedytować pliki:

sudo gedit /etc/default/locale
sudo gedit ~/.pam_environment

Zmieniając linijki:

LANGUAGE=en_GB:en
LANG=en_GB.UTF-8

Po tej zmianie konieczny jest reset.

Czytaj więcej

Jak dodać tabelę w WordPressie?

WordPress domyślnie niestety nie dostarcza narzędzia do tworzenia tabel w trybie wizualnym. Można zainstalować sobie wtyczkę (o ile ma się uprawnienia administracyjne do dodawania wtyczek). Jeśli tabela jest prosta, można napisać ją sobie samodzielnie w HTMLu, co jest pracochłonne i niewygodne, barierą jest także znajomość HTML (co wcale nie jest takie oczywiste;)).

Jest jednak opcja kompromisowa – użycie gotowego generatora tabel. Na przykład takiego: http://html-tables.com/ – ten jest chyba najprostszym generatorem, jaki znalazłam.

  1. Podajemy wymaganą liczbę kolumn i wierszy, klikamy „Generate”.
  2. Jeśli któreś komórki chcemy połączyć, zaznaczamy je i klikamy „Merge”.
  3. Wpisujemy zawartość komórek.
  4. Kopiujemy kod HTML.
  5. W WordPressie przełączamy się w tryb tekstowy.
  6. Wklejamy kod HTML.
  7. Aby dodać ładne obramowania, niestety trzeba pobawić się z CSS. Aby dodać proste obramowanie, wystarczy do znacznika „Table” dodać  border="1".
  8. Gotowe.

Przykładowa tabelka:

x o
x o
o x

Czytaj więcej

BDD, TDD, FDD i inne

Garść terminów na temat kilku metodyk zwinnych. Pochodzą z moich notatek do egzaminów i rozmów kwalifikacyjnych:)

 

Programowanie zwinne (Agile) – iteracyjno-przyrostowa metoda wytwarzania oprogramowania.Zakłada częsty kontakt z klientem, dostarczanie co jakiś czas kolejnych (działających!) fragmentów systemu. Proces:

  1. określenie wymagań, wykonanie ogólnego projektu całości
  2. wybór podzbioru funkcjonalności
  3. szczegółowy projekt podzbioru
  4. implementacja podzbioru
  5. testowanie podzbioru
  6. dostarczenie podzbioru
  7. powrót do punktu 2. aż do zakończenia projektu.

Manifest Agile:
Ludzie i interakcje ponad procesy i narzędzia
Działające oprogramowanie ponad obszerną dokumentację
Współpracę z klientem ponad formalne ustalenia
Reagowanie na zmiany ponad podążanie za planem

 

Scrum – jedna z najbardziej znanych metodyk zwinnych. Podstawowe założenia:

  • Czas realizacji projektu jest podzielony na mniejsze odcinki trwające od tygodnia do miesiąca (sprinty). Każdy sprint to jedna iteracja procesu, po której dostarczona zostaje kolejna wersja oprogramowania.
  • Lista wymagań, spisana jest w formie user stories (jak w BDD, patrz niżej), zbiór ten to backlog.
  • Zespół projektowy składa się z różnych ról: programiści, testerzy i inni wykonawcy, scrum master zarządzający procesem, product owner który zna wymagania użytkownika i jest ogniwem łączącym klienta z zespołem.
  • Zespół jest samoorganizujący się. Nie ma kierowników, każdy sam wybiera sobie realizowane zadania.

Proces:

  1. Przed rozpoczęciem iteracji, zespół na sesji groomingu przegląda backlog produktu, dzieląc zadania na mniejsze fragmenty i przypisując im punkty (story points), będące miarą złożoności zadania. Mogą używać do tego kart do Sprint pokera, czyli kart ze zdefiniowaną ilością punktów (0, ½, 1, 2, 3, 5, 8, 13, 20, 40, 100, ?, nieskończoność).
  2. Na początku iteracji zespół planuje sprint (sprint planning), wybierając funkcjonalności, które będzie realizować – przerzuca je z product backlogu do sprint backlogu. Dzięki prowadzeniu statystyk i przedstawieniu każdego zadania za pomocą punktów, wiadomo ile mniej więcej zadań może wziąć na siebie zespół.
  3. Podczas trwania sprintu, zespół wykonuje zadania. Może kontaktować się z product ownerem w celu uzyskania dokładniejszych wyjaśnień itd.
  4. Każdego dnia odbywają się maksymalnie 15-minutowe spotkania podsumowujące co udało się zrobić wczoraj, co jest planowane na dziś, jakie są problemy. (Daily Scrum / stand up).
  5. Sprint kończy się spotkaniem podsumowującym (sprint review), w którym uczestniczą wszyscy zainteresowani (nawet klienci!). Prezentowana jest kolejna wersja produktu (demo).

 

TDD (Test Driven Development) – podejście, w którym najpierw pisze się testy (jednostkowe), a następnie funkcjonalności we właściwym programie. Dzięki TDD możliwe jest uzyskanie wysokiego pokrycia testami (test coverage).

  1. Pisanie testu jednostkowego do żądanej funkcjonalności. Test failuje, ponieważ nie ma jeszcze kodu programu.
  2. Implementacja funkcjonalności. Test przechodzi.
  3. Refaktoryzacja kodu.

 

FDD (Feature Driven Development)

  1. Budowa ogólnego modelu
  2. Budowa listy „cech”. „Cechy” są:
    1. niewielkie
    2. użyteczne
    3. zdefiniowane jednym zdaniem (np.: „rezerwacja pokoju”).
    4. grupowane w obszary funkcjonalne (np. „system rezerwacji hoteli”).
  3. Planowanie wg cech. Wskaźniki:
    1. priorytet
    2. pracochłonność
    3. ryzyko
  4. Projekt wg cech
  5. Implementacja wg cech
  6. Kroki 4. i 5. są powtarzane iteracyjnie. Po każdej iteracji wydawana jest wersja dla klienta.

 

BDD (Behavior Driven Development) – rozwijanie oprogramowania od strony wymagań użytkownika. Wymagania są przechowywane w postaci historyjek (user stories) w formie:

Jako powracający użytkownik
Gdy wpiszę szukany przedmiot
Pod listą wyników widzę swoje poprzednie wyszukania

Opis jest realizowany wg punktów:

given - warunki początkowe, aktor, kontekst
when - akcje, wydarzenie
then - oczekiwane rezultaty

User stories są niezwykle popularną formą przechowywania wymagań także poza BDD, o czym świadczyć może choćby popularność takich frameworków jak Cucumber, JBehave.

(więcej…)

Czytaj więcej

Więc jestem

Dziś wpis z kompletnie innej beczki, ale również bardzo mnie interesującej – psychologii. Może nie tyle wpis, co link do serwisu http://www.wiecjestem.us.edu.pl/.

Dziwię się, że wcześniej nie natknęłam się na tą stronę. A może i się nie dziwię? Internet nie jest już tym samym Internetem, co kilka(naście) lat temu, lecz coraz bardziej staje się kolejną planszą biznesowej rozgrywki. (Taka gorzka refleksja niedzielna…). Serwis nie jest natomiast nastawiony na zysk, wnioskuję zatem iż nie zatrudnia sztabu SEO, pracującego nad jego wysoką pozycją w wynikach wyszukiwarek.

Tematyka „Więc jestem” jest szeroka, od choćby autoterapii (przykład: przystępnie przedstawiony model ABCD), przez wyzwania współczesnego świata (np. uzależnienie od sieci), aż po bardziej prozaiczne i codzienne problemy (np. zachowanie na rozmowach kwalifikacyjnych). Duży plus za solidnie przygotowane, merytoryczne artykuły, oparte na źródłach (pod każdym artykułem bibliografia), co w ogarniętej pożogą bylejakości Sieci zdarza się coraz rzadziej.

Polecam:)

Czytaj więcej

Zapisywanie wyniku komendy do pliku w Linuksie

Większość poleceń, których efekt widać na konsoli, zwraca swój efekt do strumienia stdout. Aby efekt zapisać do pliku (co polecam w przypadku konieczności analizy dużej ilości wyników, które po prostu nie mieszczą się na ekranie), wystarczy przekierować go do pliku za pomocą „>

ls > result_ls.txt

Czasem jednak tak się nie da. Na przykład polecenie make zwraca wynik nie do strumienia stdout, lecz do stderr. Mamy dwie opcje:

  1. Przekazanie stdout i stderr do pliku:
    make &> result_make_full.txt
  2. Przekazanie tylko stderr do pliku:
    make 2> result_make_stderr.txt
  3. Przekazanie tylko stdout do pliku:
    make 1> result_make_stdout.txt

 

Czytaj więcej

Kupiłam dom!

Kupiłam pierwszą w życiu nieruchomość! Dom. A właściwie domek w górskim stylu. O taki:

Umiejscowiony jest w pięknej górskiej Sopotni Wielkiej, skąd wiodą szlaki między na Rysiankę, Romankę, Pilsko.

Jedynym mankamentem jest to, że domek jest w skali H0;)

A najfajniejszym faktem jest, że każdy może zostać dzierżawcą takiego domku. Klik tu: http://www.polaris.org.pl.

Dochód przeznaczony jest na działalność statutową stowarzyszenia Polaris, które zajmuje się ogólnie popularyzacją nauki (zwłaszcza astronomii) wśród młodego pokolenia :)

Czytaj więcej

How to install LHAPDF6

Instruction is easy to find here: https://lhapdf.hepforge.org/install.html. But on „fresh” Linux you need to install some dependencies.

Download LHAPDF archive from page https://www.hepforge.org/downloads/lhapdf and unpack to any directory. Alternative method is to use wget:

wget http://www.hepforge.org/archive/lhapdf/LHAPDF-6.6.1.6.tar.gz
tar xf LHAPDF-6.1.6.tar.gz
cd LHAPDF-6.1.6

Installation is standard: configure, make, make install.

I prefer to not use any special path and install this lib directly to /usr/local/lib. So I didn’t use any prefixes:

./configure

After invoking this command I got a message:

checking for Boost headers version >= 1.41.0... no
configure: error: cannot find Boost headers version >= 1.41.0

Boost was missing. To install:

sudo apt-get install libboost1.48-*

When installation process ends, checking if boost is installed:

dpkg -s libboost1.48-all-dev

How to get version of Boost:

dpkg -s libboost1.48-all-dev | grep 'Version'

In my case: Version: 1.48.0-3.

After installing Boost, retry configure LHAPDF:

./configure

Succeed. Installation:

make
sudo make install

How to check if LHAPDF is installed? Try to invoke:

ls /usr/local/lib/

Czytaj więcej

Linux – zmienne systemowe

Tak się składa, że czasem nawet najbardziej zagorzałą fankę Microsoftu 😉 dopada konieczność przesiadki na inny system. I szybko okazuje się, jak wielu rzeczy się nie wie lub nie pamięta. Przeczuwam więc, że w najbliższym czasie będą się tu pojawiać głównie notatki związane z różnymi poleceniami linuksowymi.

Wyświetlenie zmiennych systemowych na konsolę realizowane jest poleceniem: env lub printenv

Przykładowy output:

d9k@Nihilia:~$ env
SSH_AGENT_PID=1689
TERM=xterm
SHELL=/bin/bash
WINDOWID=69209558
USER=d9k
...

i tak dalej.

Ważną zmienną jest także PATH (jak na Windowsie). Jej zawartość można wyświetlić po prostu:

d9k@Nihilia2:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Jak widać, separatorem jest dwukropek (w przeciwieństwie do Windowsowego średnika).

Modyfikacja zmiennej PATH – w zależności od konfiguracji systemu:

  1. Plik ~/.profile
  2. Plik ~/.bash_profile
  3. Plik ~/.bash_login
  4. Plik  /etc/environment

W moim przypadku zmienna PATH występowała w /etc/environment. Zmodyfikowałam plik (sudo gedit /etc/environment), dla zastosowania zmian: source /etc/environment && export PATH.

Czytaj więcej