Strona główna> Bez kategorii Blog free time practice>Selenium WebDriver – pierwsze testy

02.201514

adasdasd

Selenium WebDriver – pierwsze testy

Od >> poprzedniego wpisu << minęło trochę czasu, mam nadzieję, że teraz już wpisy pojawiać się będą częściej. Zakładam, że podstawy Pythona zostały opanowane to bierzemy się za pisanie testów. :)

Poprzedni wpis skończył się na włączeniu PyDeva w Eclipse. Teraz musimy utworzyć swój projekt. Wciśnij File > New > PyDev Project. W polu „Project Name” wpisz nazwę swojego projektu. Wciśnij link „Click here to configure an interpreter not listed.”. W sekcji „Python Interpreters” wciśnij „New”. W polu „Interpreter Executable” wpisz ścieżkę do python.exe w folderze wirtualnego środowiska, który utworzyłeś w poprzednim artykule (albo wyklikaj ścieżkę klikając najpierw na przycisk „Browse” a potem na odpowiednie foldery). W moim przypadku jest to „C:\Robota\python\Tests\Scripts\python.exe”. Kliknij OK, ponownie OK gdy wyświetli się lista folderów i jeszcze raz OK, żeby wszystko zatwierdzić. Z listy „Interpreter” wybierz dodaną przed chwilą ścieżkę. Zatwierdź wszystko klikając „Finish”. U mnie wyglądało to >> tak <<.

Ok, projekt utworzony, teraz czas na stworzenie paczki i modułu. Kliknij prawym przyciskiem myszy na utworzonym projekcie i wybierz New > PyDev Package. W polu „Name” wpisz nazwę paczki i zatwierdź klikając „Finish”. Teraz prawym na paczce i wybierz New > PyDev Module. I znowu – w polu „Name” nazwa, zatwierdzamy klikając na „Finish”. U mnie wyglądało to >> tak <<.

Wszystko gotowe, można się wziąć za pisanie testów. Zacznijmy od wklejenia do utworzonego modułu tego kodu:

 

import unittest 

from selenium import webdriver

 

 

class OpenPageTest(unittest.TestCase):
    
    
    def test_check_url(self):
        self.driver = webdriver.Chrome()
        driver = self.driver
        driver.implicitly_wait(10)
        driver.maximize_window()
        driver.get("http://testspring.pl")
        self.assertEqual(driver.current_url, "http://testspring.pl/",
                         "Page url is not correct: " + driver.current_url)
        driver.quit()

 

 

if __name__ == "__main__":
    unittest.main()

 

Żeby odpalić test można albo wcisnąć prawy przycisk myszy na teście i wybrać Run As > Python Run, albo nacisnąć przycisk w kształcie białej strzałki w zielonym kółku. Wygląda to >> tak <<. Teraz po kolei wyjaśnienie co się dzieje w teście.

 

import unittest 

 

class OpenPageTest(unittest.TestCase):

 

if __name__ == "__main__":
    unittest.main()

 

W tych artykułach będziemy wykorzystywać bibliotekę unittest. Nie jest to jedyna opcja, ale z innych nie korzystałem ;) Każdy moduł testu musi na początku zaimportować unittest, w klasie posiadać unittest.TestCase i kończyć się if __name__ … Taki jest wymóg tego narzędzia, trzeba z tym żyć.

 

def test_check_url(self):

 

Kolejny wymóg unittesta: wszystkie nazwy testów MUSZĄ zaczynać się od „test_”.

 

from selenium import webdriver

 

self.driver = webdriver.Chrome()
driver = self.driver

 

I tu zaczyna się robić ciekawiej, bo dochodzimy do testu właściwego. Najpierw importujemy webdrivera. Webdriver zajmuje się odgrywaniem użytkownika w danej przeglądarce. On będzie za nas klikał, uzupełniał formularze, itp. Pierwsze co musimy zrobić to wybrać w jakiej przeglądarce chcemy odpalić nasze testy. webdriver.Chrome() wybiera właśnie Chrome’a jako przeglądarkę, ale równie dobrze mógłby być tam webdriver.Firefox(). Zmienna driver została utworzona, by kod był bardziej przejrzysty – wygodniej wpisuje się samo driver ;).

 

driver.implicitly_wait(10)

 

Metoda implicitly_wait(int) mówi driverowi ile ma czekać na pojawienie się elementu na stronie (przycisku, pola itp.). Argument int wyrażony w sekundach, w naszym przypadku 10 sekund. W jednym teście wystarczy raz wywołać tę metodę by ustawienia zostały zapamiętane do końca testu.

 

driver.maximize_window()

 

Metoda maximize_window() maksymalizuje okno przeglądarki. Łatwiej dzięki temu zobaczyć lokalnie co się dzieje podczas testu i znaleźć źródło ewentualnych problemów.

 

driver.get("http://testspring.pl")

 

Metoda get(String) otwiera stronę o podanym URL. Musi tu zostać podany pełny URL, jak w przykładzie. Jeśli podanym URLem będzie np. „www.testspring.pl” podczas wykonywania testu w tym miejscu się on wywali. ;) „/” na końcu URL nie jest wymagane.

 

self.assertEqual(driver.current_url, "http://testspring.pl/",
                         "Page url is not correct: " + driver.current_url)

 

Tu pojawiają się dwie nowe metody. current_url zwraca jako String URL strony, która obecnie jest otworzona w przeglądarce. Tak jak przy metodzie get() jest to cały adres stron.

Metoda assertEqual(obj1, obj2, String) to tak naprawdę jedna z metod, które są całą istotą tej zabawy. Wykonując jakiś test coś chcemy sprawdzić, osiągnąć jakiś wynik. W naszym przypadku chcemy sprawdzić czy URL strony, na którą kazaliśmy wejść driverowi jest taki jakiego oczekiwaliśmy. assertEqual nam na to pozwoli. W wywołaniu tej metody wprowadzamy dwa argumenty (ich kolejność nie jest istotna), które są porównywane. Jeśli są IDENTYCZNE asercja kończy się z wynikiem pozytywnym i test jest kontynuowany. W przeciwnym wypadku test kończy się w tym miejscu błędem asercji.

Trzeci argument (String) to wiadomość jaka pojawi się w konsoli jeśli asercja się nie powiedzie. Dobrze w tym miejscu opisać co porównywaliśmy, łatwiej będzie potem znaleźć powód, przez który test się wywalił. Argument ten jednak nie jest wymagany. O asercji będzie jeszcze za chwilę.

 

driver.quit()

 

Metoda quit() zamyka zarówno wszystkie otwarte przez drivera okna przeglądarki  jak i jego samego.

 

Ok, wróćmy do asercji. Wspomniałem, że w assertEqual dwa pierwsze argumenty muszą być dokładnie takie same, żeby asercja zakończyła się powodzeniem. Spróbujmy wywalić test. Po usunięciu „/” z końca drugiego argumentu, 14sta linia wyglądałaby tak:

 

self.assertEqual(driver.current_url, "http://testspring.pl",

 

Po odpaleniu testu w tym miejscu pojawia się błąd asercji:

 

AssertionError: Page url is not correct: http://testspring.pl/

 

Jak widać pojawiła się wiadomość podana przez nas wiadomość, w której pojawia się faktyczny URL. Test zakończył się niepowodzeniem i pozostało nam otwarte okno przeglądarki. Jak już wspomniałem test jest przerywany w miejscu pojawienia się błędu (o ile nie określimy inaczej, ale o tym kiedy indziej ;)). Metoda quit() zamykająca przeglądarkę pojawia się po asercji, zatem nie została wykonana. Żeby mieć pewność, że zawsze jakaś czynność zostanie wykonana po teście, nieważne w którym momencie zostanie on przerwany wykorzystuje się metodę tearDown. Test wygląda wtedy tak:

 

import unittest 

from selenium import webdriver

 

 

class OpenPageTest(unittest.TestCase):

    def test_check_url(self):
        self.driver = webdriver.Chrome()
        driver = self.driver
        driver.implicitly_wait(10)
        driver.maximize_window()
        driver.get("http://testspring.pl")
        self.assertEqual(driver.current_url, "http://testspring.pl",
                         "Page url is not correct: " + driver.current_url)

    def tearDown(self):
        self.driver.quit()

if __name__ == "__main__":
    unittest.main()

 

Po odpaleniu tego testu ponownie mamy błąd asercji, ale przeglądarka zostaje zamknięta. Metoda tearDown zostanie użyta przy wszystkich testach w danej klasie. Żeby to udowodnić dodajmy drugi test, tym razem sprawdzający tytuł strony. Jeśli ktoś nie wie tytuł strony to tekst znajdujący się pomiędzy znacznikami <title></title> w źródle strony i pojawiający się na zakładkach przeglądarki. Kod wygląda tak:

 

# -*- coding: utf-8 -*-
import unittest 

from selenium import webdriver

 

 

class OpenPageTest(unittest.TestCase):
    
    
    def test_check_url(self):
        self.driver = webdriver.Chrome()
        driver = self.driver
        driver.implicitly_wait(10)
        driver.maximize_window()
        driver.get("http://testspring.pl")
        self.assertEqual(driver.current_url, "http://testspring.pl",
                         "Page url is not correct: " + driver.current_url)
        
    def test_check_title(self):
        self.driver = webdriver.Chrome()
        driver = self.driver
        driver.implicitly_wait(10)
        driver.maximize_window()
        driver.get("http://testspring.pl")
        self.assertEqual(driver.title,
                         "Testspring | testerzy, testowanie oprogramowania, "
                         + u"outsourcing testów, "
                         + "profesjonalny software testing",
                         "Page title is not correct: " + driver.title)
        
    def tearDown(self):
        self.driver.quit()

if __name__ == "__main__":
    unittest.main()

 

Najpierw omówienie nowości, które pojawiły się w teście:

 

# -*- coding: utf-8 -*- 

u"outsourcing testów, "

 

Pierwszy problem – w tytule strony głównej pojawia się polski znak diaktryczny, przez co na początku strony musimy dodać kodowanie, w tym wypadku utf-8. W asercji przed Stringiem, w którym ten znak się pojawia dodałem u – dzięki temu String ten zostanie zakodowany w odpowiednim formacie.

 

driver.title

 

Metoda title zwraca tytuł bieżącej strony jako String.

Jak zauważyliście po obydwu testach przeglądarka została zamknięta, co jasno dowodzi użyteczności metody tearDown.

W obydwu testach początek jest taki sam:

 

self.driver = webdriver.Chrome()
driver = self.driver
driver.implicitly_wait(10)
driver.maximize_window()
driver.get("http://testspring.pl")

 

Skoro w obydwu testach pojawiają się te same czynności możemy użyć metody setUp, by były one wykonywane przed każdym testem. W naszym przypadku (i po poprawieniu asercji w teście test_check_url) nasz test wygląda tak:

 

# -*- coding: utf-8 -*-
import unittest 

from selenium import webdriver

 

 

class OpenPageTest(unittest.TestCase):
    
    
    def setUp(self):
        self.driver = webdriver.Chrome()        
        self.driver.implicitly_wait(10)
        self.driver.maximize_window()
        self.driver.get("http://testspring.pl")
    
    def test_check_url(self):
        driver = self.driver
        self.assertEqual(driver.current_url, "http://testspring.pl/",
                         "Page url is not correct: " + driver.current_url)
        
    def test_check_title(self):
        driver = self.driver
        self.assertEqual(driver.title,
                         "Testspring | testerzy, testowanie oprogramowania, "
                         + u"outsourcing testów, "
                         + "profesjonalny software testing",
                         "Page title is not correct: " + driver.title)
        
    def tearDown(self):
        self.driver.quit()

if __name__ == "__main__":
    unittest.main()

 

Po odpaleniu, obydwa testy powinny zakończyć się powodzeniem. ;)

Tyle na dzisiaj, w następnej części zaczniemy poruszać się po stronie. Komentarze i pytania jak zawsze mile widziane. :)

 

Andrzej Poniedziałek

  • Bartłomiej Kaliński

    Ok, zacznę :P Zacząłem powoli poznawać Selenium korzystając z tego tutoriala -> http://selenium-python.readthedocs.org/en/latest/getting-started.html.

    W tekście pojawia się taki oto fragment:

    „The driver.get method will navigate to a page given by the URL. WebDriver will wait until the page has fully loaded (that is, the “onload” event has fired) before returning control to your test or script.”.

    W związku z tym do czego potrzebna jest metoda „driver.implicitly_wait(10)”?

    Chciałem przy okazji zapytać czy znacie jeszcze jakieś ciekawe źródła na temat Selenium z których można się poczuć.
    Dodatkowo do pisania testów mogę polecić edytor PyCharm. Świetna sprawa:)

    • Andrzej Poniedziałek

      Co do implicitly_wait to nie dotyczy tylko metody get a całego testu, np. klikniesz w przycisk uruchamiając jakiś skrypt, który ma ci pokazać jakiś element – wtedy driver poczeka 10s aż się pojawi.

      Jeśli chodzi o ciekawe źródła to http://stackoverflow.com/ :P Tam jest wszystko :D Nie znam darmowych kursów o Selenium WebDriver, ja uczyłem się podpatrując kolegów i przeszukując stacka. Stąd właśnie pomysł na ten cykl – zebrać co wiem i opisać w jednym miejscu, jak ktoś mnie wtedy zapyta jak zacząć to odeślę go tu, a jak czegoś nie będzie to będzie znaczyło, że trzeba dopisać ;)

      • Bartłomiej Kaliński

        Niestety jestem jednoosobowym działem testerskim w swojej firmie i nie ma się od kogo uczyć. Na szczęście stack to faktycznie kopalnia wiedzy i przy okazji szukania odpowiedzi na jedno pytanie można natknąć się na coś o wiele ciekawszego;)

  • jots2

    Darmowy newsletter: http://elementalselenium.com/

    Prowadzący Dave swego czasu napisał książkę którą warto przeczytać: https://seleniumguidebook.com/ .
    Były też dwie książki z Packtu na temat selenium które nie były złe. Imho warto zacząć jednak od książek bo dostaniesz ustrukturyzowana wiedzę np. na temat page object pattern przez co unikniesz robienia projektowi krzywdy skacząc od pytania do pytania na stackoverflow ;-)

  • Damian Kowalski

    A ja mam proste pytanie. Co automatyzować w pierwszej kolejności?

    • Andrzej Poniedziałek

      Z której strony jest proste? :D Jeśli jesteś testerem to automatyzujesz to za co ci zapłacą :P Ciężko wyznaczyć ogólną zasadę, tu potrzeba indywidualnego podejścia biznesowego. Według mnie powinno się zacząć od najbardziej krytycznych obszarów aplikacji i systematycznie rozwijać bazę testów, by pokryć jak największą część. Ważne jest, żeby nie automatyzować na siłę – pewno, że fajnie mieć automaty, które uwolnią testerów od przeklikiwania aplikacji podczas regresji po raz n-ty, co jest nużące, ale jeśli takie klikanie zajmuje godzinę tygodniowo, a przygotowanie automatów zajęłoby pół roku, to raczej z biznesowego punktu widzenia nie ma to sensu ;) Jeżeli w firmie ciężko podjąć decyzję czy i od czego zacząć może dobrym pomysłem jest zaangażować zewnętrzną osobę. Podczas pracy przy projekcie można się od niego zbyt przyzwyczaić, osoba niezwiązana zadając pytania o działanie aplikacji może pomóc wskazać co tak naprawdę opłaca się automatyzować.

      Generalnie nie ma dobrej odpowiedzi dla wszystkich, każdy musi wypracować własną :D

  • justi

    Puszczając ostatni skrypt mam : „SyntaxError: Non-ASCII character ‚xf3′ in file C:Users ” w linii + u”outsourcing testów, ” wyrzuca 2 błędy: FAIL: test_check_title (__main__.OpenPageTest) : „Page title is not correct: ” + driver.title)
    AssertionError: Page title is not correct: Testspring | testerzy, testowanie oprogramowania, outsourcing testxf3w, profesjonalny software testing
    oraz FAIL: test_check_url (__main__.OpenPageTest) „Page url is not correct: ” + driver.current_url)
    AssertionError: Page url is not correct: http://testspring.pl/.
    Tu pewnie chodzi o „/” oraz tytuł błędny,bo wyrzucone „u”outsourcing testów,”? Co w przypadku tego syntax error

  • justi

    już udało mi się, pojawia się błąd jedynie ze złym URLEM :)

    • Andrzej Poniedziałek

      Czyli jest ok czy nie? Bo się pogubiłem :D Jak coś to wrzuć proszę, co zostało z komunikatów po teście.

  • Olala

    Ja też mam błąd: SyntaxError: Non-ASCII character ‚xf3′ in file …pierwszy_test.py on line 35, but no encoding declared;

testowanie oprogramowania | outsourcing testów | software testing | testerzy