Pokazywanie postów oznaczonych etykietą python. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą python. Pokaż wszystkie posty

sobota, 17 czerwca 2017

Unit test w Pythonie

Przypadek testowy

Część pewnej majowej niedzieli postanowiłam spędzić na pisaniu testów automatycznych w Selenium. Zamysł wydawał się prosty: stworzyć na githubie repozytorium z testami sprawdzającymi stronę mojego własnego bloga. Wymyśliłam, że przetestuję jakąś małą funkcjonalność tej strony, czyli np. czy ikonka Facebooka i Twittera zabierają użytkownika do odpowiednich stron internetowych podłączonych do tychże ikon. W manualnym testowaniu taki przypadek testowy wyglądałby mniej więcej tak:

Tytuł: Nawigacja do linka na Facebook
Środowisko: Windows 10, Przeglądarka Chrome
Warunek wstępny: Użytkownik ma dostęp do internetu i przeglądarkę Chrome

Kroki:
  1. Otwórz przeglądarkę Chrome.
  2. Wejdź na stronę martamaracje.blogspot.com.
  3. Kliknij na ikonę Facebook z prawej strony ekranu pod nagłówkiem "Tutaj jestem".
Rezultat oczekiwany: Otwiera się strona facebook.com/martamaracje/.

Proste? Proste! Co w tym trudnego? Łatwo wykonać te kroki manualnie.

Test automatyczny

Wynalazłam moje notatki z zajęć z testowania automatycznego w Pythonie przy użyciu Selenium oraz zajrzałam do repozytorium na githubie zapewnionym przez naszego WSB-owego wykładowcę tego tematu i skopiowałam zarys formuły do stworzenia testu jednostkowego.
W testach jednostkowych w Pythonie można za pomocą metody setUp spowodować, że Selenium przed wykonaniem konkretnego testu lub zestawu testów otwiera przeglądarkę Chrome - może to być oczywiście dowolna inna przeglądarka.
def setUp(self):
    self.driver=webdriver.Chrome()
Następnie, kolejna funkcja musi zaczynać się od słowa "test" i wykonuje kolejne kroki naszego przypadku testowego. Kilka poleceń dla webdrivera mogłam skopiować z przykładów, które robiłam na zajęciach w WSB, a reszty szukałam w googlu. Większość odpowiedzi na to, jak pokierować webdriverem znalazłam na stackoverflow.com. Po godzinach wymyślania, szukania i sprawdzania, doszłam do czegoś takiego:
def test_when_facebook_link_clicked_then_navigate_to_facebook(self):
    #Arrange
    driver=self.driver
    driver.get("http://martamaracje.blogspot.com")
    expected_url="https://www.facebook.com/martamaracje/"
    social_media_link=driver.find_element_by_css_selector(
           "#fawesomeicons > a[href='" + expected_url + "']")
    initial_tabs=len(driver.window_handles)
        
    #Act
    social_media_link.click()
    sleep(2) #wait for navigation
    opened_tabs=len(driver.window_handles)
    driver.switch_to.window(driver.window_handles[opened_tabs-1])

    #Assert
    self.assertGreater(opened_tabs, initial_tabs)
    self.assertIn(expected_url, driver.current_url)
Nazwa testu opisuje w zwięzły sposób, co ma on sprawdzać (when_facebook_link_clicked_then_navigate_to_facebook). Wiem, że to nie jest zdanie, jak z Szekspira i ma lekko zachwianą gramatykę, ale zawiera kluczowe słowa "when" i "then" ważne w programowaniu np. w składni gherkin. Wszystkie kroki pogrupowane są wg zasady:
  • Arrange - przygotuj
  • Act - wykonaj
  • Assert - sprawdź

W sekcji Arrange webdriver otwiera stronę martamaracje.blogspot.com. Stworzyłam sobie zmienną expected_url, żeby móc jej później użyć dla sprawdzenia twittera, podmieniając jedynie wartość expected_url na mój twiterrowy adres. Zmienna social_media_link będzie miała przypisany element w kodzie html, który webdriver znajdzie na podstawie selektora css zawierającego oczekiwany adres internetowy, przypisany wcześniej do zmiennej expected_url. Ponieważ link do facebooka otwiera się w nowej zakładce, musiałam też stworzyć zmienną initial_tabs, która zliczy ilość zakładek otwartych zanim kliknie się na link.

Po tych warunkach wstępnych zlecam driverowi następujące działania (Act): po pierwsze kliknąć na to, co znalazł i co przypisane zostało do zmiennej social_media_link. Następnie, po 2 sekundach funkcja len zlicza jeszcze raz ilość otwartych zakładek i przypisuje ją do zmiennej opened_tabs. Na koniec driver ma za zadanie przejść do ostatnio otwartej zakładki (to będzie ta otwarta kliknięciem na link facebooka).

I nadchodzi czas na sprawdzenie (Assert), czy otworzyła się poprawna strona z linka. Najpierw, więc test sprawdzi, czy ilość otwartych po kliknięciu zakładek (opened_tabs) jest większa od początkowej ilości zakładek (initial_tabs). To sprawdzenie daje pojęcie, czy coś nowego się otworzyło. Ale jeszcze przydałoby się sprawdzić, czy adres internetowy obecnie otwartej zakładki zgadza się z tym oczekiwanym i przypisanym do zmiennej expected_url. Do tego użyłam funkcji assertIn, która oceni, czy adres https://www.facebook.com/martamaracje/ występuje w url-u, do którego posłałam webdrivera poleceniem driver.switch_to.window().

Uruchomiony na moim komputerze test nawigacji do linków na facebooku i twitterze zadziałał: webdriver sam otwierał przeglądarkę, klikał, gdzie mu wskazałam i sprawdzał wyniki tych działań, wracając do mnie z komentarzem "OK". Całość kodu do tego testu jednostkowego można obejrzeć na github.com/martamaracje/blogtests. Jestem z siebie dumna. To może mały krok dla ludzkości, ale duży skok dla martamaracje:).

czwartek, 1 grudnia 2016

Pierwsze próby praktyczne

Pierwszy dzień - rodzaje testów

Jestem już po drugim zjeździe w WSB. Mimo, że nie poczyniłam wielkich postępów w nauce od zeszłego miesiąca, to czułam się na zajęciach pewniej. Znów poznałam sporo teorii dotyczącej tym razem podziału testów według ich funkcjonalności. Nie było w tym nic skomplikowanego. Natomiast część zajęć miała wreszcie wymiar praktyczny.

Po wysłuchaniu wykładu w około siedmioosobowych grupach mieliśmy za zadanie wymyślić przypadki testowe dla strony internetowej wizzair. Pracowaliśmy razem na dokumencie googlowskim, więc każdy mógł śledzić, co nowego dopisują inni. Magia techniki - coś się pojawia na moim ekranie w momencie, kiedy ktoś inny pisze to na swoim komputerze.

Wyzwaniem stało się nie tyle wymyślenie przypadków testowych, co próba zorganizowania pracy z zupełnie nieznanymi ludźmi. Większość z nas widziała się przecież w sobotę drugi raz w życiu, a tu mieliśmy za zadanie na podstawie kilku podpowiedzi i przykładów przygotować plan działania i podzielić się jakoś pracą w grupie.

Nie lubię takiego chaosu, jaki zapanował po wydaniu polecenia, że mamy napisać przypadki testowe. Starałam się więc nad nim zapanować przyjmując rolę organizatora, spisując kategorie funkcjonalności, które chcemy przetestować. Wydawało mi się, że wiele osób nie do końca wie, co ma robić i jak się za to zabrać. Ale trzeba było coś wyprodukować i to szybko, więc coś tam nam wyszło. W idealnym świecie poświęciłabym więcej czasu na zawiązanie jakichś relacji w naszym zespole i gruntowniejsze przedyskutowanie planu naszej pracy.

Samo nauczenie się sporządzania scenariuszy testowych wydaje mi się teraz tylko kwestią dalszej praktyki. Na przykład, żeby przetestować przypadek użycia strony wizzair do rejestracji użytkownika, można stworzyć sytuację o tytule "rejestracja użytkownika z użyciem poprawnych danych". Wypisujemy wtedy wszystkie kroki, które należałoby przejść w celu efektywnego zarejestrowania użytkownika na stronie wizzair. W analogiczny sposób można stworzyć scenariusze dla sytuacji wyjątkowych, jak np. niepoprawne dane dla formularza rejestracji i napisać, co powinno się wydarzyć w takim wypadku.

Ważne, żeby poszczególne kroki w każdym przypadku testowym były jak najbardziej szczegółowe. Zamiast pisać "Wpisz niepoprawne dane", zdecydowanie lepiej będzie napisać "Wpisz w pole <Imię> ciąg cyfr <1234>" Podobnie można by przetestować inne scenariusze dla takich przypadków użycia strony jak logowanie, wyszukiwanie lotów, wyszukiwanie hoteli, rezerwacja samochodu, czy zamawianie newslettera.

Ten rodzaj testowania, bez zagłębiania się w sferę kodu kryjącego się za tym, co widzimy np. w przeglądarce internetowej, nazywa się testowaniem czarnoskrzynkowym. Nie jest w nim potrzebna znajomość programowania, więc może ją wykonywać każdy informatyczny laik. Nie jest to trudne, dam sobie z tym na pewno radę.

Drugi dzień - przygotowywanie środowiska programistycznego i pierwsze próby Pythona

Na moim kierunku studiów mam kolegę w grupie bardziej zaawansowanej, który zajęcia z programowania miał w sobotę, a rodzaje testów poznawał w niedzielę - odwrotnie niż ja. Podczas przerwy obiadowej w sobotnich zajęciach wyglądał na bardzo zmarnowanego. Sam też przyznał, że czuje się przytłoczony tempem pracy i ilością wiedzy do przyswojenia. Nieco mnie to zestresowało, bo mogło być przepowiednią tego, co mnie czeka w niedzielę. Jednak tempo mojej grupy jest zdecydowanie bardziej komfortowe. Czułam, że nadążam z instalowaniem całego potrzebnego oprogramowania (Linux, Virtual Box). Poznałam kilka podstawowych komend potrzebnych do tworzenia, przeglądania i modyfikowania plików na konsoli Linuxa. Po przygotowaniu środowiska do pracy z Pythonem miałam też okazję sama wypróbować tworzenie zmiennych i poćwiczyć na nich instrukcje takie, jak sprawdzanie długości listy lub ciągu znaków, dodawanie elementów do list, działanie pętli i instrukcji warunkowych. Same podstawowe rzeczy. Ponieważ bardzo podobne zadania robiłam podczas kursu online w Codecademy (w którym wykorzystywałam symulację konsoli w przeglądarce), nie miałam większych problemów z tą częścią zajęć. Po dniu praktycznych ćwiczeń na wirtualnej maszynie byłam z siebie zadowolona.

Im więcej dowiaduję się o testowaniu, tym łatwiejsze mi się wydaje. Mimo, że mam wykształcenie humanistyczne, nie czuję się całkiem zagubiona w tym odłamie technicznego świata. Oswajam Pythona i oswajam się z myślą, że dam sobie radę z testowaniem.

czwartek, 3 listopada 2016

Pierwszy zjazd w WSB

Dzień pierwszy

15 i 16 października 2016 odbył się pierwszy zjazd w WSB. Czekając na zajęcia w korytarzu przed salą spoglądałam na całą grupę ludzi z mojego kierunku i czułam się bardzo stremowana. Poziom mojej wiedzy o programowaniu i testowaniu był bliski zeru. Wydawało mi się, że każdy dookoła wygląda na bardziej rozgarniętego technicznie ode mnie.

Zajęcia zaczęły się od krótkiego testu, który miał dać prowadzącym rozeznanie, jak najlepiej podzielić 50 osób na dwie grupy przybliżone poziomem wiedzy. Testu się nie krępowałam. Wiedziałam, że nic nie umiem, więc więcej skorzystam w grupie początkującej, niż w tej mającej już jakieś rozeznanie w kodowaniu lub testowaniu. Tam też mnie przydzielono. I dobrze.

W pierwszy dzień sporo było podstawowej teorii odnośnie tego, czym jest testowanie i jakie są zadania testera. Poruszane tematy nie były trudne, choć przedstawione zostały w mało jeszcze usystematyzowany i nieco chaotyczny sposób. Do tej pory nie rozumiem różnicy między walidacją a weryfikacją na podstawie przykładu formularza internetowego z danymi osobowymi. Nie będę się tym teraz przejmować, bo podręcznikowe definicje tych dwóch pojęć jako takich rozumiem. Czego nie zrozumiem na zajęciach, mogę doczytać w domu. Zawsze mogę też zwrócić się o pomoc do wujka Googla, no i do męża informatyka.

Certyfikacja

Dostałam sylabus, którego muszę nauczyć się, żeby poradzić sobie ze zdaniem międzynarodowego egzaminu dla testerów ISQTB na poziomie podstawowym. Uczyłam się trochę w zeszły weekend i mam mieszane uczucia co do tego sylabusa i samego testu. Zalatuje to nieco zasadą "zakuć, zdać i zapomnieć", bo jak inaczej wyjaśnić to, że trzeba się nauczyć, jakie dokładnie zwroty wchodzą w skład procesu testowania, a jak się jakieś słowo przekręci albo połączy element z jednego etapu procesu z elementem z drugiego etapu, to odpowiedź nie jest zaliczona jako prawidłowa. Konkretny przykład:

Według sylabusa*:
Podstawowy proces testowy składa się z następujących czynności:
  • planowanie i nadzór nad testami
  • analiza i projektowanie testów
  • implementacja i wykonanie testów
  • ocena kryteriów zakończenia i raportowanie
  • czynności zamykające test
A pytanie testowe nawiązujące do tego zagadnienia brzmi:

Który z poniższych jest czynnością w podstawowym procesie testowym:
  1. Analiza i wykonanie testów
  2. Planowanie i nadzór
  3. Planowanie i analiza testów
  4. Ocena wykonania testów

W tym przypadku odpowiedzią prawidłową ma być 2, bo jako jedyna kropka w kropkę odpowiada opisowi z sylabusa. Trochę może człowieka rozboleć głowa podczas rozwiązywania takich testów, kiedy sobie próbuje przypomnieć, jak dokładnie były sformułowane definicje w sylabusie, żeby nie popełnić jakiegoś zonka na teście.

No, ale trudno... Test wyboru nie jest idealną formą sprawdzenia wiadomości, natomiast jest formą najszybszą. Tak więc muszę się z tym pogodzić i wyuczyć na pamięć tych wszystkich zwrotów. Nie jest to bynajmniej nic gorszego do przejścia niż rzeczy, których musiałam się uczyć na przykład na wstępie do literaturoznawstwa na filologii angielskiej.

Dzień następny

Drugiego dnia przedstawiono nam podstawowe zagadnienia dotyczące Pythona. Bardzo mi pomogło to, że widziałam ten język na kursie online i trochę w nim pisałam. Owszem nie rozumiałam wszystkiego, co pokazywał prowadzący, ale zdecydowaną większość tak. Resztę mam nadzieję zrozumieć w trakcie ćwiczeń na następnych zjazdach.

Panowie prowadzący zajęcia w WSB twierdzą, że zostanie testerem nie jest trudne dla ludzi spoza branży informatycznej. Pan Adam Przybyła, który uczy nas Pythona wręcz upiera się, że znając angielski można się nauczyć języka programowania dużo szybciej. Mój mąż też tak twierdzi, a i ja po pierwszym zjeździe zaczynam coraz bardziej w to wierzyć.


*Cytowane fragmenty pochodzą z sylabusa pt. "Certyfikowany tester. Plan poziomu podstawowego" wersja 2011.1.1, copyright Stowarzyszenie Jakości Systemów Informatycznych (SJSI).

niedziela, 30 października 2016

Ujarzmić Pythona

Będąc osobą nie związaną dotychczas z informatyką (a jedynie z informatykiem, co w żaden sposób nie poprawiało mojej wiedzy programistycznej) poprosiłam WSB o sugestie, jak mogę się przygotować do zajęć. Kierownik merytoryczny studiów zaproponował, abym pouczyła się jednego z języków programowania: ruby, Python, swift lub golang. Wszystkie brzmiały dla mnie jednakowo obco. Skoro jednak na zajęciach mieliśmy używać Pythona, zdecydowałam się zacząć właśnie od niego. Według moich wstępnych poszukiwań - przeprowadzonych z pomocą profesora Googla - Python miał być dobrym i prostym językiem na start, umożliwiającym tworzenie aplikacji webowych, gier, wyszukiwarek, etc. Dodatkowo jego nazwa pochodzi od Latającego Cyrku Monty Pythona, co wydało mi się zachęcające, bo wskazywało, że jego twórca miał poczucie humoru.

Trochę zwlekałam z rozpoczęcia przygody z Pythonem. Mail od WSB z poradami dla laików zawierał kilka linków do książek i internetowych tutoriali. Najtrudniej było wybrać jeden ze sposobów nauki tak, aby wreszcie zacząć się uczyć. Instynktownie nie mam zaufania do uczenia się programowania z książek. W moim przypadku szybko mogłabym się zniechęcić. Jeśli na papierze coś wydawałoby mi się zbyt skomplikowane, nie wierzyłabym, że można tego spróbować w wirtualnym świecie. Większość proponowanych tutoriali działała na zasadzie "zanim zaczniemy, zainstaluj to czy tamto, wejdź tu, wpisz to etc." Już to było trochę zniechęcające, a do tego teoria znajdowałaby się na jednej stronie, a ćwiczenia musiałabym wykonywać gdzie indziej.

Kurs internetowy przygotowany przez Codecademy nie wymagał instalowania żadnego programu. Na dodatek w warstwie wizualnej łączył w sobie:
  • teorię,
  • opis zadania do wykonania,
  • edytor kodu,
  • konsolę, która wyświetlała rezultaty z wyprodukowanego przeze mnie kodu.
Wszystko w jednym miejscu - idealnie!

W kursie Codecademy podobało mi się to, że lekcje były dosyć krótkie. Miałam poczucie, że udaje mi się w czasie jednej sesji zakończyć dany temat lub zyskać konkretną umiejętność. Jest to ważne dla podtrzymywania motywacji, kiedy człowiek uczy się zupełnie nowych, czasami trudnych rzeczy. Każda lekcja w kursie miała krótką część teoretyczną, a następnie sporą dozę sprawdzania teorii w praktyce. Nie bez znaczenia było też to, że twórcy kursu wykazywali się poczuciem humoru i nawiązywali, gdzie tylko się da do Monty Pythona. To sprawiało, że nauka stawała się przyjemniejsza. No i kurs jest zintegrowany z forum użytkowników, więc gdy się utknie na jakimś zadaniu i nie wie się, jak iść dalej, można sprawdzić, jak wybrnęli z podobnych opałów inni. Ostatecznym kołem ratunkowym był telefon do męża informatyka.

Humanistyczne zdolności językowe pomagały mi zrozumieć, że w programowaniu istnieją pewne zasady, jak w gramatyce i trzeba się ich trzymać, żeby komputer zrobił to, co chcemy - żeby nas zrozumiał. Żeby coś zadziałało, trzeba w odpowiednim miejscu zrobić wcięcie w tekście albo nie można tego wcięcia zastosować, bo będzie jakaś katastrofa. Jest pewien zestaw poleceń i funkcji, jak słówek i zwrotów w żywym języku, które muszą zostać użyte, żeby "dogadać się" z naszą maszyną i uzyskać oczekiwany efekt.

Ale programowanie to też sporo arytmetyki - musiałam sobie przypomnieć, że istnieją liczby całkowite (integers), liczby ułamkowe (floats), reszty z dzielenia (modulo) itp. i co z nimi można robić. Na co dzień mało się nad tym zastanawiam, nawet robiąc zakupy. Wyzwaniem były też dla mnie rozważania logiczne (booleans), czy coś jest Prawdą czy Fałszem i wykorzystanie tego przy tworzeniu funkcji, która miała powodować pojawienie się jakiegoś wyniku. Niektórych tematów związanych stricte z arytmetyką nie udało mi się przejść w ogóle (np. wykorzystanie silni czy mediany), ale około 90% kursu zdołałam zaliczyć poznając podstawowe pojęcia i zagadnienia Pythona. Miałam okazję realizować zadania matematyczne takie, jak obliczanie podatku i napiwku w restauracji lub obliczanie kosztów wczasów. Próbowałam też stworzyć prowizoryczną stronę dla sklepu internetowego, a nawet zagrać z komputerem w statki.

Nie potrafię stwierdzić, czy nauczyłam się Pythona. Powiedziałabym, że się z nim zapoznałam i mnie nie udusił. Przynajmniej potrafię zrozumieć, co różne dziwne zwroty w kodzie oznaczają i rozszyfrować, co mają za zadanie zrobić. Wydaje mi się, że mogę nauczyć się programowania jedynie ćwicząc dalej i poznając kolejne języki. Myślę, że teraz spróbuję pouczyć się np. Ruby. Ciekawe czy są jakieś podobieństwa i czy znając już trochę Pythona będę mogła szybciej nauczyć się Ruby. Zanim wyjechałam do Skandynawii podszkalałam się z niemieckiego, bo wiedziałam, że gramatyka niemiecka jest podobna do skandynawskiej. Rzeczywiście było mi łatwiej uczyć się zupełnie obcego, niszowego języka, bo rozumiałam coś z innego znanego mi nieco języka i bazowałam na tych podobieństwach. Mam nadzieję, że w kodowaniu będzie podobnie.