Robot Framework to ciekawe narzędzie, które może nam pomóc zautomatyzować testy w różnych projektach. W tym artykule chciałbym je opisać i pokazać jego zastosowanie w automatyzacji aplikacji webowej.

Dzień dobry 🙂 Czasem w życiu początkującego testera słowa takie jak: automatyzacja, Selenium, programowanie mogą wywołać strach i lekką panikę. Dlatego wydaje mi się, że wspomniane wyżej narzędzie może być dobre do rozpoczęcia przygody z automatyzacją.
Niedawno natknąłem się na ciekawy projekt Robot Framework (w dalszej części będę je nazywać Robot). Postaram się Robota zaprezentować na przykładzie testu logowania do poczty Onet.pl.
Artykuł został opublikowany 30.01.2019, a zaktualizowany 22.06.2022.
Czego dowiesz się z artykułu?
Z przygotowanego przeze mnie wpisu dowiesz się jak:
zainstalować Pythona i biblioteki za pomocą polecenia pip,
- zainstalować Robot Framework wraz z potrzebnymi bibliotekami,
- skonfigurować pierwszy test automatyczny,
- napisać łatwy przypadek testowy z wykorzystaniem Robot Framework,
- za pomocą konsoli cmd oraz Excela usprawnić swoją pracę,
- uruchomić przygotowany test.
Automatyzacja testów jest jedną ze ścieżek rozwoju testera i jest obecnie bardzo popularna. Nawet moja kotka o imieniu Kimci stara się opanować tę wiedzę i czyta branżowe książki na temat automatyzacji testów, a ostatnio zaczęła sięgać po książkę o Java.
Czemu ten framework zrobił na mnie takie wrażenie?
Narzędzie to jest bardzo zaawansowane i można je użyć w różnych projektach. Framework ten posiada wiele wbudowanych bibliotek, a także umożliwia skorzystanie z zewnętrznych. Dzięki duetowi Robot + Appium przeprowadzisz testy na urządzeniach mobilnych. Robot pomoże Ci także wykonać testy REST API oraz baz danych. Nic nie stoi na przeszkodzie, by w projekcie Continuous Integration wykorzystać na przykład Jenkins.
Robot pozwolił mi w łatwy sposób stworzyć test automatyczny i przy okazji umożliwił mi, bez posługiwania się zewnętrznymi frameworkami lub bibliotekami, uzyskanie raportu z wynikami testów w przystępnej formie.
Moim zdaniem framework ten jest też przydatny ze względów biznesowych, aby napisać w łatwy sposób test z wykorzystaniem języka naturalnego (Keyword-driven) oraz oczywiście w Robot Framework można skorzystać z konstrukcji BDD when, given, then.
Cała magia tego narzędzia polega na tym, że my do niego „mówimy” po angielsku (można także po niemiecku i hiszpańsku), a gdy wykonujemy test to framework nasze polecenia zamienia na odpowiedni kod.
Więcej możesz dowiedzieć się na stronie projektu Robot Framework.
Projekt jest ciągle rozwijany w co angażuje się wielu użytkowników. Jeżeli natrafisz na jakieś problemy lub będziesz chciał się spytać o rzeczy związane z tym narzędziem, możesz to zrobić za pomocą listy mailingowej lub skorzystać z kanału IRC czy na Slacku.
Instalacja
Najpierw należy zainstalować Pythona i pamiętać o opcji Add to Path:

Następnie instalujemy framework korzystając z konsoli cmd:
pip install robotframework
W naszym projekcie będziemy korzystać z biblioteki SeleniumLibrary, dlatego tą bibliotekę też musimy zainstalować:
pip install robotframework-seleniumlibrary
Do pisania naszego testu polecam PyCharm.
Wykorzystanie
Teraz możemy zaczynać 🙂 Na początku, dla porównania, chciałbym pokazać kod testu do logowania do poczty z wykorzystaniem Pythona i behave (prawa strona) oraz w Robot Framework (lewa strona).

Zaczniemy od utworzenia i skonfigurowania naszego skryptu. W tym celu tworzymy nowy plik z rozszerzeniem *.robot
PyCharm powinien automatycznie zaproponować instalację wtyczek związanych z tym frameworkiem. W moim przypadku PyCharm zaproponował instalcję pluginów pokazanych poniżej:

Jako że test będzie sprawdzał logowanie do Poczty Onet.pl, utworzyłem plik Onet.robot.
Następnie tworzymy nasz test wykorzystując dostępne sekcje:
*** Settings *** | wykorzystywana do konfiguracji i ustawień |
*** Varibles *** | wykorzystywana do przechowywania zmiennych |
*** Test cases *** | wykorzystywana do tworzenia przypadków testowych |
*** Keywords *** | wykorzystana do definiowania czynności dla danego kroku |
Dlatego zaczniemy w sekcji ustawień od zaimportowania biblioteki, z której będziemy w naszym teście korzystać.
*** Settings ***
Library SeleniumLibrary
W sekcji Settings mamy możliwość ustawienia bibliotek, z których korzystamy. Listę dostępnych bibliotek znajdziesz tutaj.
Sekcja Variables służy do ustawienia naszych zmiennych. Jak zobaczysz w zmiennej Browser wystarczy wpisać tylko Chrome. Oczywiście w takim przypadku odpowiednie drivery muszą znajdować się w katalogu projektu. Jeżeli chcielibyśmy uruchomić test w innej przeglądarce, wystarczy wpisać jej nazwę.
*** Settings ***
Library SeleniumLibrary
*** Variables ***
${LOGIN URL} http://www.poczta.onet.pl/
${BROWSER} Chrome
@{list} = Niepoprawny e-mail lub hasło. Wprowadź poprawne dane.
Dla porównania odpowiedni kod w Javie wyglądałby tak:
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
public class Onet {
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver", "G:\\Selenium\\chromedriver.exe");
ChromeDriver driver = new ChromeDriver();
W językach programowania, na przykład Java czy Python, aby uruchomić test w innej przeglądarce, za każdym razem musiałbyś zaimportować właściwe biblioteki i wskazać odpowiedni driver. Różnicę widać bardzo wyraźnie.
W Robot Framework nie ma takiej potrzeby. Dodatkowo, w łatwy sposób można tak napisać skrypt, że przed testem Robot spyta się, w jakiej przeglądarce uruchomić ma test. Rozwiązanie to znajdziesz w moim projekcie na GitHubie.
Test cases i Keywords
Następnie możemy przejść do sekcji Test cases. W tej sekcji ustawiamy kolejne kroki, które będą wykonywane. Kroki te musimy zdefiniować w sekcji Keywords.
*** Test Cases ***
Valid Login
Open main page
Rodo
Input Username
Input Password
Login button
Assert Onet Mail
[Teardown] Close Browser
Invalid Login
Open main page
Rodo
Input invalid login
Input invalid password
Login button
Assert invalid
[Teardown] close browser
Sekcja Keywords ogranicza się do wskazania, co framework ma zrobić w konkretnym przypadku z sekcji Test case. Wskazujemy w niej na przykład, jaka strona ma zostać otworzona i następnie lokalizujemy elementy i wchodzimy w interakcję z nimi. Oczywiście, korzystamy z dobrze nam znanych lokalizatorów między innymi poprzez id, css, XPath.
Zamieszczam poradnik jak lokalizować elementy z wykorzystaniem Selenium.
Wiadomo, że za pomocą asercji test powinien coś sprawdzać oraz zweryfikować, czy aplikacja zachowuje się w oczekiwany sposób.
Asercja
Asercja (ang. assertion) czyli predykat (forma zdaniowa w danym języku, która zwraca prawdę lub fałsz), umieszczony w pewnym miejscu w kodzie. Asercja wskazuje, że programista zakłada, że predykat ów jest w danym miejscu prawdziwy. W przypadku gdy predykat jest fałszywy (czyli niespełnione są warunki postawione przez programistę), asercja powoduje przerwanie wykonania programu.
Asercja ma szczególne zastosowanie w trakcie testowania tworzonego oprogramowania np. dla sprawdzenia luk lub jego odporności na błędy. Zaletą stosowania asercji jest możliwość sprawdzenia, w którym fragmencie kodu źródłowego programu nastąpił błąd.
Jak widać poniżej użyłam do tego konstrukcję Title Should Be, Page should contain element oraz Should Contain Any.
*** Keywords ***
Open main page
Open browser ${LOGIN URL} ${BROWSER}
Title Should Be Onet Poczta - najlepsza skrzynka pocztowa
Rodo
wait until element is visible css=button.cmp-button_button.cmp-intro_acceptAll
Click Element css=button.cmp-button_button.cmp-intro_acceptAll
Input Username
Input Text id=f_login validlogin@onet.pl
Input password
Input Text id=f_password validpassword
Login button
click element css=input.loginButton
Assert Onet Mail
page should contain element id=NewMail-button
Input invalid login
Input Text id=f_login blednylogin@onet.pl
Input invalid password
Input Text id=f_password blednehaslo1
Assert invalid
wait until element is visible class=messageContent
get text class=messageContent
Should Contain Any ${list} Niepoprawny e-mail lub hasło. Wprowadź poprawne dane.
Dla przykładu, gdy użytkownik poprawnie się zaloguje powinien zobaczyć listę wiadomości i móc wysłać wiadomość klikając przycisk „Napisz wiadomość”. Dlatego poprawne zalogowanie sprawdzamy poprzez weryfikowanie czy na stronie znajduję się element: id=NewMail-button poprzez słowa page should contain element
Z dokumentacji tego frameworku dowiesz się, z jakich keywordów możesz skorzystać. Tak wygląda lista keywordów w bibliotece Selenium:
Uruchamianie testu
Poniżej przedstawiam kod zaktualizowany w 06.2022:
*** Settings ***
Library SeleniumLibrary
*** Variables ***
${LOGIN URL} http://www.poczta.onet.pl/
${BROWSER} Chrome
@{list} = Niepoprawny e-mail lub hasło. Wprowadź poprawne dane.
*** Test Cases ***
Valid email
Open main page
Rodo
Input email
Click Next
Input Password
Login button
Assert Onet Mail
[Teardown] Close Browser
Invalid email
Open main page
Rodo
Input invalid email
Click Next
Assert invalid email
[Teardown] close browser
Valid email and invalid password
Open main page
Rodo
Input email
Click Next
Input invalid password
Login button
Assert invalid password
[Teardown] Close Browser
*** Keywords ***
Open main page
Open browser ${LOGIN URL} ${BROWSER}
Title Should Be Poczta Onet - Darmowa Poczta bez Opłat
Rodo
wait until element is visible
class=cmp-intro_acceptAll
Click Element class=cmp-intro_acceptAll
Input email
Input Text id=email validemail@onet.eu
Click Next
Click Element xpath=//*[contains(text(),'Dalej')]
Input password
wait until element is visible id=password
Input Text id=password validpassword
Login button
click element xpath=//*[contains(text(),'Zaloguj')]
Assert Onet Mail
wait until element is visible
xpath=//*[contains(text(),'Napisz wiadomość')]
page should contain element xpath=//*[contains(text(),'Napisz wiadomość')]
Input invalid email
Input Text id=email blednylogin@onet.pl
Input invalid password
wait until element is visible id=password
Input Text id=password blednehaslo1
Assert invalid email
wait until element is visible
xpath=//*[contains(text(),'Konto nie istnieje')]
page should contain element
xpath=//*[contains(text(),'Konto nie istnieje')]
Assert invalid password
wait until element is visible
xpath=//*[contains(text(),'Nieprawidłowe hasło')]
page should contain element
xpath=//*[contains(text(),'Nieprawidłowe hasło')]
We wcześniejszej wersji artykułu mogliście zapoznać się z jego inną wersją (nieaktualną):
*** Settings ***
Library SeleniumLibrary
*** Variables ***
${LOGIN URL} http://www.poczta.onet.pl/
${BROWSER} Chrome
@{list} = Niepoprawny e-mail lub hasło. Wprowadź poprawne dane.
*** Test Cases ***
Valid Login
Open main page
Rodo
Input Username
Input Password
Login button
Assert Onet Mail
[Teardown] Close Browser
Invalid Login
Open main page
Rodo
Input invalid login
Input invalid password
Login button
Assert invalid
[Teardown] close browser
*** Keywords ***
Open main page
Open browser ${LOGIN URL} ${BROWSER}
Title Should Be Onet Poczta - najlepsza skrzynka pocztowa
Rodo
wait until element is visible css=button.cmp-button_button.cmp-intro_acceptAll
Click Element css=button.cmp-button_button.cmp-intro_acceptAll
Input Username
Input Text id=f_login validmail@onet.pl
Input password
Input Text id=f_password validpassword
Login button
click element css=input.loginButton
Assert Onet Mail
page should contain element id=NewMail-button
Input invalid login
Input Text id=f_login blednylogin@onet.pl
Input invalid password
Input Text id=f_password blednehaslo1
Assert invalid
wait until element is visible class=messageContent
get text class=messageContent
Should Contain Any ${list} Niepoprawny e-mail lub hasło. Wprowadź poprawne dane.
Aktualizacja w czerwcu 2022
Aktualizacja w kodzie wynikała ze zmian, jakie zaszły w ciągu ostatnich 3 lat. Proces logowania do poczty został zmieniony i obecnie przebiega w dwóch etapach.
Wcześniej w celu zalogowania aplikacja wymagała podania e-maila oraz hasła (na jednym ekranie logowania) oraz kliknięcia w przycisk „Zaloguj”. Teraz najpierw użytkownik musi podać e-mail oraz kliknąć przycisk Dalej. W tym momencie następuje pierwszy etap weryfikacji – na przykład aplikacja sprawdza czy podane konto istnieje.
W przypadku gdy konto jest poprawne, użytkownik przechodzi do ekranu z hasłem, zaś gdy konto jest nieprawidłowe – wyświetlany jest komunikat błędu.
Nowe rozwiązanie pozwoliło mi na utworzenie trzech przypadków testowych:
- poprawny e-mail i poprawne hasło – weryfikacja zalogowania,
- niepoprawny e-mail – weryfikacja komunikatu błędu o nieprawidłowym koncie,
- poprawny e-mail i niepoprawne hasło – weryfikacja błędu o nieprawidłowym haśle.
W celu sprawdzenia kodu proponuję założenie konta i zastąpienie w kodzie wartości „validemail” na prawidłowy adres oraz „validpassword” na prawidłowe hasło.
Uruchomienie testu
Teraz nie pozostaje nam nic innego jak uruchomić nasz test. Jeżeli wszystko dobrze zainstalowaliśmy powinniśmy móc to zrobić z poziomu okna konsoli cmd lub za pomocą wbudowanego Terminala w PyCharm:

Ważne: używając parametrów, można modyfikować polecenie. Jako że przeglądarka w naszym teście jest zmienną, możemy użyć polecenia:
robot -v BROWSER:Firefox Onet.robot
W takim przypadku nasz test zostanie uruchomiony w przeglądarce Firefox.
Możemy także zmodyfikować folder, w którym będą przechowywane raporty i zrobimy to za pomocą plików z rozszerzeniem *.bat
Tworzymy w tym celu w folderze projektu plik Test Firefox.bat i, korzystając np. z notatnika, umieszczamy w nim tekst:
robot -d firefox_results -v BROWSER:Firefox Onet.robot
Gdy go uruchomimy, test zostanie wykonany w przeglądarce, a dodatkowo wynik testu zostanie zapisany w katalogu firefox_results (odpowiada za to parametr -d).
Rozwiązanie pomocne testerowi
Teraz chciałbym pokazać, moim zdaniem, ciekawe rozwiązanie, które może być pomocne testerowi. Wyobraźmy sobie, że w naszym projekcie dostaliśmy dane użytkowników do logowania dla 100 osób i, korzystając z naszego skryptu, mielibyśmy dla wszystkich tych użytkowników sprawdzić logowanie do poczty z poprawnymi danymi.

Hmmmm… jak to zrobić? ? W naszym skrypcie musimy dokonać zmiany, która spowoduje, że nazwa użytkownika i hasło będą zmiennymi, czyli w sekcji Variables dodajemy:
${username} = example@onet.pl
${password} = password
Aby to zadziało, musimy dokonać zmiany w keywords:
Input Username
Input Text id=f_login ${username}
Input password
Input Text id=f_password ${password}
Pozostaje nam dodać tag do naszego testu, który dzięki odpowiedniemu poleceniu w cmd pozwoli uruchomić ten konkretny przypadek testowy.
Pod przypadkiem testowym dodajemy linijkę:
Valid Login
[Tags] Valid
Dalej chcielibyśmy, żeby te dane zostały zamienione w przydatne dla nas polecenie, które moglibyśmy użyć w konsoli a następnie w pliku *.bat
Wykorzystanie Ecxcela
Z pomocą przyjdzie nam Excel – potężne narzędzie, które moim zdaniem w codziennej pracy testera jest bardzo często wykorzystywane i pomocne. Skorzystamy z formuły ZŁĄCZ.TEKST
Tworząc odpowiednią formułę dla jednej komórki, korzystając z opcji przeciągania, jesteśmy w stanie dla wszystkich nazw użytkowników i haseł stworzyć odpowiednie polecenie.
Przykładowe polecenie to:
robot -i Valid -d results\example1@onet.eu -v username:example1@onet.eu -v password:pass1234 Onet.robot
-i | wskazujemy nazwę przypadku testowego do uruchomienia zdefiniowana za pomocą tagu |
-d | definiujemy gdzie mają być przechowywane logi, raporty i zrzuty ekranu |
-v | definiujemy zmienne |
Wystarczy utworzyć plik *.bat i do niego wkleić wartości utworzone dzięki formule Excela i go uruchomić.
Jeżeli uruchomimy plik bat, zostanie wykonany tylko przypadek logowania z tagiem „Valid”, a dodatkowo dla każdego użytkownika zostanie stworzony osobny folder o nazwie użytkownika:
W przypadku uruchomienia ponownie testu pliki raportów i logów zostaną nadpisane i będą przechowywać wyniki ostatniego testu.
Warto więc dodać do naszego polecenia -T (timestamp), odpowiadający za to, że kolejne testy będą zapisywane do oddzielnych plików z datą i godziną utworzenia raportu.
Całe polecenie będzie wyglądać tak:
robot -i Valid -d results\example1@onet.eu -v username:example1@onet.eu -v password:pass1234 -T Onet.robot
Raport z testów

Na końcu testu jesteśmy poinformowani, że Robot utworzył dla nas raport i log z testu w plikach output.xml, log.html i report.html
Pamiętam, że w przypadku Pythona i Behave, aby uzyskać raport, który dobrze by wyglądał, musiałem posiłkować się zewnętrzną biblioteką Allure.
Tutaj od razu otrzymujemy dobrze prezentujący się raport z informacją o powodach, dlaczego test nie przeszedł. Robot dodatkowo w przypadku uzyskania FAIL automatycznie zrobi zrzut ekranu i dołączy go do raportu.

Podsumowanie
Wydaje mi się, że po napisanym szybko i w łatwy sposób automatycznym teście, tester może być zadowolony i wieczorem zasnąć z uśmiechem na twarzy.
Na zakończenie chciałbym pokazać jak w praktyce wygląda test z użyciem Robot-a 😉

Oczywiście artykuł stanowi wprowadzenie do zastosowania frameworku w testerskim życiu codziennym. Narzędzie to bardzo przypadło mi do gustu. Będę starał się poszerzyć wiedzę na jego temat oraz rozwinąć ten projekt o:
- zastosowanie w nim BDD,
- zaczerpnięcie danych do logowania z zewnętrznego pliku Excela,
- zmodyfikowanie testu, aby był uruchamiany jednocześnie na kilku przeglądarkach.
Projekt ten znajdziesz na moim GitHubie.

Dziękuję za uwagę i życzę miłego dnia 🙂
***
Chcesz lepiej zrozumieć aplikacje i systemy, które testujesz? Dołącz do ModernTester, poznaj najpotrzebniejsze narzędzia, frameworki oraz języki programowania i ćwicz na specjalnie przygotowanych środowiskach testowych: Platforma e-learningowa ModernTester
A jeśli chcesz dowiedzieć się więcej, jak jako programista i tester zaradzić potrzebom osób z niepełnosprawnością, zachęcamy do lektury innego artykułu autora.
Jak poprawić taki błąd
Onet
==============================================================================
Valid Login :: This test case check app when user use valid creden… | FAIL |
Parent suite setup failed:
No keyword with name 'Get Selection From User’ found.
——————————————————————————
Invalid Login :: This test case check app when user use invalid cr… | FAIL |
Parent suite setup failed:
No keyword with name 'Get Selection From User’ found.
——————————————————————————
Onet | FAIL |
Suite setup failed:
No keyword with name 'Get Selection From User’ found.
2 critical tests, 0 passed, 2 failed
2 tests total, 0 passed, 2 failed
==============================================================================
Output: /home/waldemar/Onet-robotframeworktest/output.xml
Log: /home/waldemar/Onet-robotframeworktest/log.html
Report: /home/waldemar/Onet-robotframeworktest/report.html
Hej 🙂 Kluczowe wydaje mi się to -> No keyword with name 'Get Selection From User’ found.
„Get selection from User” traktuje Ci jako Keyword a nim nie jest.
Musisz dokładnie sprawdzić czy nazwa kroku w ***Test cases*** jest identyczna z tą w ***Keywords***
Porównaj dwa pliki:
https://github.com/anditpl/Onet-robotframeworktest/blob/master/Onet.robot
https://github.com/anditpl/Onet-robotframeworktest/blob/master/Resources/Onet.robot
Z tego co widzę błąd Ci się wkradł tutaj https://github.com/anditpl/Onet-robotframeworktest/blob/master/Resources/Onet.robot:
Open the browser
${new_browser} = Get Selection From User In which browser you want to run the test? chrome firefox edge
Set Global Variable ${BROWSER} ${new_browser}
lub tutaj w pliku https://github.com/anditpl/Onet-robotframeworktest/blob/master/Onet.robot:
Suite Setup Open the browser
Poprawić mógłbym gdybym zobaczył kod. 😉
No no, zainteresowałeś nie tym frameworkiem. Świetny artykuł wprowadzający, dzięki.
Dzięki 🙂
Dla początkującego radziłbym używać RIDE a nie pyCharm do pisania testów.
Jasne RIDE może być dobrym rozwiązaniem dla początkujących 🙂 W pyCharm bardzo przyjemnie mi się pisało kod 😉
Hej, świetny artykuł. Mam jednak pytanie, czemu w sekcji Variables, tylko przy list jest znak '@’, a przy reszcie '$’?
Dzięki 🙂
Ogólnie z dokumentacji wynika konwencja użycia @ przy tworzeniu listy:
http://robotframework.org/robotframework/latest/libraries/BuiltIn.html
Create List *items
Returns a list containing given items.
The returned list can be assigned both to ${scalar} and @{list} variables.
Examples:
@{list} = Create List a b c
${scalar} = Create List a b c
${ints} = Create List ${1} ${2} ${3}
Można jednak też użyć $.
Super tekst.
„Jak widać poniżej użyłam do tego konstrukcję Title Should Be, Page should contain element oraz Should Contain Any.”
Popraw tylko forme osobowa bo czytajac mialem wrazenie ze pisaly go dwie osoby 😉
wylewam frustrację, jeden z najgorszych składniowo języków jakie widziałem, sam framework to raczej standard ale to jak pisze się testy to dramat, pewnie nie dla testera 😉
Vеry nice article, exactly what I needed.