Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00501 007745 11237382 na godz. na dobę w sumie
TDD w praktyce. Niezawodny kod w języku Python - ebook/pdf
TDD w praktyce. Niezawodny kod w języku Python - ebook/pdf
Autor: Liczba stron: 448
Wydawca: Helion Język publikacji: polski
ISBN: 978-83-283-1380-4 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> programowanie >> python - programowanie
Porównaj ceny (książka, ebook (-20%), audiobook).

„Ta książka to znacznie więcej niż tylko wprowadzenie do programowania sterowanego testami w Pythonie. To jest pełny kurs przedstawiający najlepsze praktyki, od początku do końca na przykładzie nowoczesnego programowania aplikacji sieciowej w Pythonie.”

— Kenneth Reitz, członek Python Software Foundation

Twórz niezawodne aplikacje w języku Python!

Każdy programista marzy o pracy z przejrzystym kodem, który został w całości pokryty testami. Niestety, rzeczywistość bywa często daleka od ideału. A może da się go jednak osiągnąć? Odpowiedzią na to pytanie jest TDD (ang. Test-Driven Development), czyli wytwarzanie oprogramowania sterowane testami. Jak zacząć stosować tę technikę? Na to i wiele innych pytań odpowiada ta książka.

Zacznij w praktyce realizować koncepcje płynące z TDD w połączeniu z językiem Python. Na początku dowiedz się, jak skonfigurować Django za pomocą testu funkcjonalnego, oraz skorzystaj z modułu unittest. Zdobądź też bezcenną wiedzę na temat testowania widoków, szablonów i adresów URL oraz naucz się testować układy strony i style. Sprawdź, jak zapewnić ciągłą integrację z wykorzystaniem systemu Jenkins oraz najlepszych praktyk w tworzeniu testowalnego kodu. Książka ta jest doskonałą lekturą dla wszystkich programistów tworzących aplikacje internetowe w języku Python. Twój kod może być naprawdę łatwy w utrzymaniu!

Poznaj techniki TDD w połączeniu z Pythonem!

Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

Tytuł oryginału: Test-Driven Development with Python Tłumaczenie: Robert Górczyński ISBN: 978-83-283-1377-4 © 2015 Helion S.A. Authorized Polish translation of the English edition of Test-Driven Development with Python, ISBN: 9781449364823 © 2014 Harry Percival. This translation is published and sold by permission of O’Reilly Media, Inc., which owns or controls all rights to publish and sell the same. Polish edition copyright © 2015 by Helion S.A. All rights reserved. All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from the Publisher. Wszelkie prawa zastrzeżone. Nieautoryzowane rozpowszechnianie całości lub fragmentu niniejszej publikacji w jakiejkolwiek postaci jest zabronione. Wykonywanie kopii metodą kserograficzną, fotograficzną, a także kopiowanie książki na nośniku filmowym, magnetycznym lub innym powoduje naruszenie praw autorskich niniejszej publikacji. Wszystkie znaki występujące w tekście są zastrzeżonymi znakami firmowymi bądź towarowymi ich właścicieli. Autor oraz Wydawnictwo HELION dołożyli wszelkich starań, by zawarte w tej książce informacje były kompletne i rzetelne. Nie biorą jednak żadnej odpowiedzialności ani za ich wykorzystanie, ani za związane z tym ewentualne naruszenie praw patentowych lub autorskich. Autor oraz Wydawnictwo HELION nie ponoszą również żadnej odpowiedzialności za ewentualne szkody wynikłe z wykorzystania informacji zawartych w książce. Wydawnictwo HELION ul. Kościuszki 1c, 44-100 GLIWICE tel. 32 231 22 19, 32 230 98 63 e-mail: helion@helion.pl WWW: http://helion.pl (księgarnia internetowa, katalog książek) Pliki z przykładami omawianymi w książce można znaleźć pod adresem: ftp://ftp.helion.pl/przyklady/tddwpr.zip Drogi Czytelniku! Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres http://helion.pl/user/opinie/tddwpr Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję. Printed in Poland. • Kup książkę • Poleć książkę • Oceń książkę • Księgarnia internetowa • Lubię to! » Nasza społeczność Spis tre(cid:316)ci Wprowadzenie ............................................................................................................ 13 Przygotowania i za(cid:293)o(cid:348)enia ......................................................................................... 19 Podzi(cid:253)kowania ............................................................................................................25 I Podstawy TDD i Django ..........................................................................27 1. Konfiguracja Django za pomoc(cid:233) testu funkcjonalnego .............................................29 S(cid:228)uchaj Testing Goat! Nie rób nic, dopóki nie przygotujesz testu ............................................. 29 Rozpocz(cid:246)cie pracy z frameworkiem Django ................................................................................. 32 Utworzenie repozytorium Git .......................................................................................................... 33 2. Rozszerzenie testu funkcjonalnego za pomoc(cid:233) modu(cid:293)u unittest .............................37 U(cid:276)ycie testu funkcjonalnego do przygotowania minimalnej aplikacji ..................................... 37 Modu(cid:228) unittest ze standardowej biblioteki Pythona .................................................................... 40 Ukryte oczekiwanie ............................................................................................................................ 42 Przekazanie plików do repozytorium ............................................................................................ 42 3. Testowanie prostej strony g(cid:293)ównej za pomoc(cid:233) testów jednostkowych ..................45 Nasza pierwsza aplikacja Django i test jednostkowy .................................................................. 46 Testy jednostkowe i ró(cid:276)nice dziel(cid:241)ce je od testów funkcjonalnych .......................................... 46 Testy jednostkowe w Django ........................................................................................................... 47 MVC w Django, adresy URL i funkcje widoku ............................................................................ 48 Wreszcie zaczynamy tworzy(cid:232) kod aplikacji .................................................................................. 49 urls.py ................................................................................................................................................... 51 Testy jednostkowe widoku ............................................................................................................... 53 Cykl test jednostkowy — tworzenie kodu ..............................................................................54 4. Do czego s(cid:293)u(cid:348)(cid:233) te wszystkie testy? ............................................................................57 Programowanie przypomina wyci(cid:241)ganie wiadrem wody ze studni ........................................ 58 U(cid:276)ycie Selenium do testowania interakcji u(cid:276)ytkownika ............................................................ 59 Regu(cid:228)a „nie testuj sta(cid:228)ych” i szablony na ratunek ........................................................................ 62 Refaktoryzacja w celu u(cid:276)ycia szablonu ....................................................................................62 5 Poleć książkęKup książkę Refaktoryzacja ..................................................................................................................................... 65 Nieco wi(cid:246)cej o stronie g(cid:228)ównej ......................................................................................................... 67 Przypomnienie — proces TDD ........................................................................................................ 68 5. Zapis danych wej(cid:316)ciowych u(cid:348)ytkownika ...................................................................73 Od formularza sieciowego do wykonania (cid:276)(cid:241)dania POST .......................................................... 73 Przetwarzanie (cid:276)(cid:241)dania POST w serwerze ..................................................................................... 76 Przekazanie zmiennych Pythona do wygenerowania w szablonie .......................................... 77 Do trzech razy sztuka, a pó(cid:274)niej refaktoryzacja ........................................................................... 81 Django ORM i nasz pierwszy model .............................................................................................. 82 Pierwsza migracja bazy danych ................................................................................................84 Zdumiewaj(cid:241)co du(cid:276)y post(cid:246)p w te(cid:264)cie ........................................................................................85 Nowa kolumna oznacza now(cid:241) migracj(cid:246) ..................................................................................85 Zapis w bazie danych informacji z (cid:276)(cid:241)dania POST ....................................................................... 86 Przekierowanie po wykonaniu (cid:276)(cid:241)dania POST .............................................................................. 89 Poszczególne testy powinny testowa(cid:232) pojedyncze rzeczy ...................................................89 Wygenerowanie elementów w szablonie ....................................................................................... 90 Utworzenie produkcyjnej bazy danych za pomoc(cid:241) polecenia migrate .................................... 92 6. Przygotowanie minimalnej dzia(cid:293)aj(cid:233)cej wersji witryny .............................................97 Gwarancja izolacji testu w testach funkcjonalnych ...................................................................... 97 Wykonanie tylko testów jednostkowych ...............................................................................100 Stawiaj na ma(cid:228)e projekty ................................................................................................................. 101 YAGNI! ........................................................................................................................................102 REST ..............................................................................................................................................102 Implementacja nowego projektu za pomoc(cid:241) TDD ..................................................................... 103 Iteracja w kierunku nowego projektu ........................................................................................... 105 Testowanie widoków, szablonów i adresów URL za pomoc(cid:241) testu klienta Django ........... 107 Nowa klasa testowa ...................................................................................................................107 Nowy adres URL ........................................................................................................................108 Nowa funkcja widoku ...............................................................................................................108 Oddzielny szablon do wy(cid:264)wietlania list ................................................................................109 Kolejny adres URL i widok pozwalaj(cid:241)cy na dodanie elementów listy .................................. 112 Klasa testowa dla operacji tworzenia nowej listy ................................................................112 Adres URL i widok przeznaczony do tworzenia nowej listy ............................................113 Usuni(cid:246)cie zb(cid:246)dnego kodu i dalsze testy ................................................................................114 Wskazanie formularzy w nowym adresie URL ...................................................................115 Dostosowanie modeli ....................................................................................................................... 116 Zwi(cid:241)zek klucza zewn(cid:246)trznego ................................................................................................117 Dostosowanie reszty (cid:264)wiata do naszych nowych modeli ..................................................118 Ka(cid:276)da lista powinna mie(cid:232) w(cid:228)asny adres URL ............................................................................. 120 Przechwytywanie parametrów z adresów URL ...................................................................121 Dostosowanie new_list do nowego (cid:264)wiata ............................................................................122 Jeszcze jeden widok pozwalaj(cid:241)cy na dodanie elementu do istniej(cid:241)cej listy .......................... 123 Uwaga na (cid:276)ar(cid:228)oczne wyra(cid:276)enia regularne! ...........................................................................124 Ostatni nowy adres URL ...........................................................................................................124 6 (cid:95) Spis tre(cid:316)ci Poleć książkęKup książkę Ostatni nowy widok ..................................................................................................................125 Jak mo(cid:276)na u(cid:276)y(cid:232) adresu URL w formularzu? ........................................................................126 Ostatnia refaktoryzacja za pomoc(cid:241) polecenia include ............................................................... 128 II Programowanie sieciowe ..................................................................... 131 7. Upi(cid:253)kszanie — jak przetestowa(cid:235) uk(cid:293)ad i style? ....................................................... 133 Jak(cid:241) funkcjonalno(cid:264)(cid:232) nale(cid:276)y testowa(cid:232) w przypadku uk(cid:228)adu i stylów? ................................... 133 Upi(cid:246)kszanie za pomoc(cid:241) frameworka CSS .................................................................................... 136 Dziedziczenie szablonu w Django ................................................................................................. 137 Integracja z frameworkiem Bootstrap ........................................................................................... 139 Wiersze i kolumny .....................................................................................................................139 Pliki statyczne w Django ................................................................................................................. 140 Zaczynamy u(cid:276)ywa(cid:232) klasy StaticLiveServerCase ..................................................................141 U(cid:276)ycie komponentów Bootstrap do poprawy wygl(cid:241)du witryny ............................................ 142 Jumbotron ....................................................................................................................................142 Ogromne pola danych wej(cid:264)ciowych .......................................................................................143 Nadanie stylu tabeli ...................................................................................................................143 U(cid:276)ycie w(cid:228)asnych arkuszy stylów CSS .......................................................................................... 143 Co zosta(cid:228)o zatuszowane — polecenie collectstatic i inne katalogi statyczne ........................ 144 Kilka tematów, które nie zosta(cid:228)y omówione ............................................................................... 147 8. TDD na przyk(cid:293)adzie witryny prowizorycznej ........................................................... 149 Techniki TDD i niebezpiecze(cid:254)stwa zwi(cid:241)zane z wdro(cid:276)eniem .................................................. 150 Jak zwykle zaczynamy od testu ..................................................................................................... 151 Pobranie nazwy domeny ................................................................................................................. 153 R(cid:246)czne przygotowanie serwera do hostingu naszej witryny ................................................... 153 Wybór hostingu dla witryny ....................................................................................................154 Uruchomienie serwera ..............................................................................................................154 Konto u(cid:276)ytkownika, SSH i uprawnienia ...............................................................................155 Instalacja Nginx ..........................................................................................................................155 Konfiguracja domen dla witryn prowizorycznej i rzeczywistej ........................................156 U(cid:276)ycie testów funkcjonalnych do potwierdzenia dzia(cid:228)ania domeny i serwera Nginx ....157 R(cid:246)czne wdro(cid:276)enie kodu .................................................................................................................. 157 Dostosowanie po(cid:228)o(cid:276)enia bazy danych ...................................................................................158 Utworzenie virtualenv ..............................................................................................................159 Prosta konfiguracja Nginx ........................................................................................................162 Utworzenie bazy danych za pomoc(cid:241) polecenia migrate ....................................................164 Wdro(cid:276)enie w (cid:264)rodowisku produkcyjnym ................................................................................... 164 U(cid:276)ycie Gunicorn .........................................................................................................................164 U(cid:276)ycie Nginx do obs(cid:228)ugi plików statycznych ......................................................................165 U(cid:276)ycie gniazd systemu Unix ...................................................................................................166 Przypisanie opcji DEBUG warto(cid:264)ci False i ustawienie ALLOWED_HOSTS ..................167 U(cid:276)ycie Upstart do uruchamiania Gunicorn wraz z systemem ..........................................168 Zachowanie wprowadzonych zmian — dodanie Gunicorn do pliku requirements.txt ....168 Automatyzacja ................................................................................................................................... 169 Zachowanie informacji o post(cid:246)pie ..........................................................................................172 Spis tre(cid:316)ci (cid:95) 7 Poleć książkęKup książkę 9. Zautomatyzowane wdro(cid:348)enie za pomoc(cid:233) Fabric .....................................................173 Analiza skryptu Fabric dla naszego wdro(cid:276)enia .......................................................................... 174 Wypróbowanie rozwi(cid:241)zania ........................................................................................................... 177 Wdro(cid:276)enie w (cid:264)rodowisku produkcyjnym .............................................................................179 Pliki konfiguracyjne Nginx i Gunicorn odtworzone za pomoc(cid:241) sed ...............................180 U(cid:276)ycie polecenia git tag do oznaczenia wydania ....................................................................... 181 Dalsza lektura .................................................................................................................................... 181 10. Weryfikacja danych wej(cid:316)ciowych i organizacja testu ............................................. 183 Testy funkcjonalne weryfikacji danych — ochrona przed pustymi elementami ................. 183 Pomini(cid:246)cie testu ..........................................................................................................................184 Podzia(cid:228) testów funkcjonalnych na wiele plików ..................................................................185 Wykonanie pojedynczego pliku testu ....................................................................................187 Podparcie testów funkcjonalnych ...........................................................................................188 Sprawdzenie warstwy modelu ...................................................................................................... 189 Refaktoryzacja testów jednostkowych na oddzielne pliki ..................................................189 Testy jednostkowe sprawdzania modelu oraz mened(cid:276)er kontekstu self.assertRaises() ....190 Dziwactwo Django — zapis modelu nie wywo(cid:228)uje operacji sprawdzenia poprawno(cid:264)ci ...191 Wy(cid:264)wietlanie w widoku b(cid:228)(cid:246)dów z weryfikacji modelu ............................................................ 192 Upewnienie si(cid:246), (cid:276)e nieprawid(cid:228)owe dane nie zostan(cid:241) zapisane w bazie danych ...........194 Wzorzec Django — przetwarzanie (cid:276)(cid:241)da(cid:254) POST w widoku generuj(cid:241)cym formularz ......... 196 Refaktoryzacja — przekszta(cid:228)cenie funkcjonalno(cid:264)ci new_item na view_list ....................197 Egzekwowanie w widoku view_list weryfikacji modelu ...................................................199 Refaktoryzacja — usuni(cid:246)cie na sta(cid:228)e zdefiniowanych adresów URL ..................................... 200 Znacznik szablonu { url } ...................................................................................................200 U(cid:276)ycie get_absolute_url w przekierowaniach ......................................................................201 11. Prosty formularz ........................................................................................................205 Przeniesienie do formularza logiki odpowiedzialnej za sprawdzanie poprawno(cid:264)ci danych .... 205 U(cid:276)ycie testu jednostkowego do analizy API formularzy ...................................................206 Przej(cid:264)cie do Django ModelForm .............................................................................................208 Testowanie i dostosowanie do w(cid:228)asnych potrzeb logiki weryfikacji formularza ..........209 U(cid:276)ycie formularza w widokach ..................................................................................................... 210 U(cid:276)ycie formularza w widoku za pomoc(cid:241) (cid:276)(cid:241)dania GET .....................................................211 Du(cid:276)a operacja znajd(cid:274) i zast(cid:241)p ..................................................................................................213 U(cid:276)ycie formularza w widoku obs(cid:228)uguj(cid:241)cym (cid:276)(cid:241)dania POST .................................................... 215 Adaptacja testów jednostkowych dla widoku new_list ......................................................215 U(cid:276)ycie formularza w widoku ..................................................................................................216 U(cid:276)ycie formularza w celu wy(cid:264)wietlenia b(cid:228)(cid:246)dów w szablonie ...........................................216 U(cid:276)ycie formularza w innym widoku ............................................................................................ 217 Metoda pomocnicza dla wielu krótkich testów ....................................................................218 U(cid:276)ycie metody save() formularza ................................................................................................. 220 12. Bardziej skomplikowane formularze ........................................................................223 Kolejny test funkcjonalny dotycz(cid:241)cy powielonych elementów ............................................... 223 Ochrona przed duplikatami w warstwie modelu ................................................................224 Ma(cid:228)a dygresja dotycz(cid:241)ca kolejno(cid:264)ci API Querystring i przedstawiania ci(cid:241)gu tekstowego ...226 8 (cid:95) Spis tre(cid:316)ci Poleć książkęKup książkę Przepisanie testu starego modelu ...........................................................................................228 Pewne b(cid:228)(cid:246)dy spójno(cid:264)ci ujawniaj(cid:241) si(cid:246) podczas zapisu .........................................................229 Eksperymenty w warstwie widoku sprawdzaj(cid:241)ce, czy s(cid:241) powielone elementy .................. 230 Bardziej skomplikowany formularz do obs(cid:228)ugi unikalno(cid:264)ci elementów ............................... 231 U(cid:276)ycie istniej(cid:241)cego formularza w widoku listy .......................................................................... 232 13. Zag(cid:293)(cid:253)biamy si(cid:253) ostro(cid:348)nie w JavaScript ....................................................................237 Rozpoczynamy od testów funkcjonalnych .................................................................................. 237 Konfiguracja prostego silnika wykonywania testów JavaScript .............................................. 238 U(cid:276)ycie jQuery i sta(cid:228)ych elementów div ................................................................................... 240 Utworzenie testu jednostkowego JavaScript dla (cid:276)(cid:241)danej funkcjonalno(cid:264)ci ............................ 243 Testowanie JavaScript w cyklu TDD ............................................................................................ 245 Zdarzenie onload i przestrzenie nazw ......................................................................................... 245 Kilka rozwi(cid:241)za(cid:254), które si(cid:246) nie sprawdzaj(cid:241) .................................................................................. 246 14. Wdro(cid:348)enie nowego kodu ..........................................................................................247 Wdro(cid:276)enie prowizoryczne .............................................................................................................. 247 Wdro(cid:276)enie rzeczywiste .................................................................................................................... 247 A je(cid:264)li wyst(cid:241)pi b(cid:228)(cid:241)d bazy danych? ................................................................................................ 248 Podsumowanie — git tag i nowe wydanie .................................................................................. 248 III Bardziej zaawansowane zagadnienia ............................................... 249 15. U(cid:348)ycie JavaScript do uwierzytelniania u(cid:348)ytkownika, integracji wtyczek i przygotowania imitacji ............................................................ 251 Mozilla Persona (BrowserID) ......................................................................................................... 252 Kod eksperymentalny, czyli „Spiking” ........................................................................................ 252 Utworzenie nowej ga(cid:228)(cid:246)zi dla Spike .........................................................................................253 (cid:227)(cid:241)czenie kodu JavaScript i interfejsu u(cid:276)ytkownika .............................................................253 Protokó(cid:228) Browser-ID ..................................................................................................................254 Kod po stronie serwera — niestandardowe uwierzytelnienie ..........................................255 Zamiana rozwi(cid:241)zania eksperymentalnego na zwyk(cid:228)e .............................................................. 260 Cz(cid:246)sto stosowana technika Selenium — wyra(cid:274)ne oczekiwanie ........................................262 Wycofanie kodu eksperymentalnego .....................................................................................264 Testy jednostkowe JavaScript obejmuj(cid:241)ce komponenty zewn(cid:246)trzne — nasze pierwsze imitacje ........................................................................................................... 265 Porz(cid:241)dkowanie — katalog plików statycznych dla ca(cid:228)ej witryny ....................................265 Imitacja: kto, co i dlaczego? ......................................................................................................266 Przestrzenie nazw ......................................................................................................................267 Prosta imitacja dla testów jednostkowych dla naszej funkcji inicjuj(cid:241)cej .........................267 Bardziej zaawansowane imitacje .............................................................................................272 Sprawdzenie wywo(cid:228)ania argumentów ..................................................................................275 Konfiguracja QUnit i testowanie (cid:276)(cid:241)da(cid:254) Ajax ........................................................................276 Wi(cid:246)cej zagnie(cid:276)d(cid:276)onych wywo(cid:228)a(cid:254) zwrotnych! Testowanie kodu asynchronicznego ....280 Spis tre(cid:316)ci (cid:95) 9 Poleć książkęKup książkę 16. Uwierzytelnianie po stronie serwera i imitacje w Pythonie ...................................283 Rzut oka na wersj(cid:246) eksperymentaln(cid:241) widoku logowania ........................................................ 283 Imitacje w Pythonie .......................................................................................................................... 284 Testowanie widoku za pomoc(cid:241) imitacji funkcji uwierzytelnienia ....................................284 Sprawdzenie, czy widok faktycznie loguje u(cid:276)ytkownika ..................................................286 Zmiana eksperymentalnej wersji uwierzytelniania na zwyk(cid:228)(cid:241) — imitacja (cid:276)(cid:241)dania internetowego .............................................................................................. 290 Polecenie if oznacza wi(cid:246)cej testów ..........................................................................................291 Poprawki na poziomie klasy ....................................................................................................292 Strze(cid:276) si(cid:246) imitacji w porównaniach warto(cid:264)ci boolowskich ................................................295 Utworzenie u(cid:276)ytkownika, je(cid:264)li to konieczne ........................................................................296 Metoda get_user() ......................................................................................................................296 Minimalny niestandardowy model u(cid:276)ytkownika ...................................................................... 298 Ma(cid:228)e rozczarowanie ...................................................................................................................300 Testy jako dokumentacja ..........................................................................................................301 U(cid:276)ytkownicy s(cid:241) uwierzytelnieni .............................................................................................301 Chwila prawdy — czy testy funkcjonalne zostan(cid:241) zaliczone? ................................................ 302 Zako(cid:254)czenie testu funkcjonalnego, przetestowanie wylogowania ......................................... 303 17. Konfiguracja testu, rejestracja i debugowanie po stronie serwera ........................307 Pomini(cid:246)cie procesu logowania przez wst(cid:246)pne utworzenie sesji ............................................. 307 Sprawdzamy rozwi(cid:241)zanie ........................................................................................................309 Dowód znajdziesz w praktyce — u(cid:276)ycie wersji prowizorycznej do wychwycenia b(cid:228)(cid:246)dów ... 310 Konfiguracja rejestracji danych ................................................................................................311 Usuni(cid:246)cie b(cid:228)(cid:246)du systemu Persona ...........................................................................................312 Zarz(cid:241)dzanie testow(cid:241) baz(cid:241) danych w serwerze prowizorycznym ........................................... 314 Polecenie Django s(cid:228)u(cid:276)(cid:241)ce do tworzenia sesji ........................................................................314 Test funkcjonalny uruchamiaj(cid:241)cy w serwerze narz(cid:246)dzie zarz(cid:241)dzania ............................315 Dodatkowy krok za pomoc(cid:241) modu(cid:228)u subprocess ................................................................317 Zachowanie kodu odpowiedzialnego za rejestracj(cid:246) danych .................................................... 320 U(cid:276)ycie konfiguracji hierarchicznej rejestracji danych .........................................................320 Podsumowanie .................................................................................................................................. 322 18. Ko(cid:295)czymy „Moje listy” — podej(cid:316)cie Outside-In ......................................................325 Alternatywa, czyli podej(cid:264)cie Inside-Out ...................................................................................... 325 Dlaczego preferowane jest podej(cid:264)cie Outside-In? ...................................................................... 326 Test funkcjonalny dla strony Moje listy ....................................................................................... 326 Warstwa zewn(cid:246)trzna — prezentacja i szablony ......................................................................... 327 Przej(cid:264)cie o jedn(cid:241) warstw(cid:246) w dó(cid:228) do funkcji widoku (kontroler) ............................................. 328 Kolejne zaliczenie — podej(cid:264)cie Outside-In .................................................................................. 329 Szybka restrukturyzacja hierarchii dziedziczenia szablonu ..............................................329 Projektowanie API za pomoc(cid:241) szablonu ...............................................................................330 Przej(cid:264)cie w dó(cid:228) do kolejnej warstwy — co widok przekazuje szablonowi? ...................331 Kolejne „wymaganie” z warstwy widoku — nowe listy powinny „zapami(cid:246)tywa(cid:232)” swego w(cid:228)a(cid:264)ciciela ........................................................................................................................... 332 Czy przej(cid:264)(cid:232) do kolejnej warstwy, gdy test ko(cid:254)czy si(cid:246) niepowodzeniem? ......................333 10 (cid:95) Spis tre(cid:316)ci Poleć książkęKup książkę 19. Przej(cid:264)cie w dó(cid:228) do warstwy modelu ............................................................................................. 333 Ostatni krok — uzyskanie z poziomu szablonu dost(cid:246)pu do w(cid:228)a(cid:264)ciciela za pomoc(cid:241) API .name .............................................................................................................335 Izolacja i „s(cid:293)uchanie” testów ....................................................................................337 Powrót do miejsca, w którym podj(cid:246)li(cid:264)my decyzj(cid:246) — warstwa widoku zale(cid:276)y od nieutworzonego jeszcze kodu modelu .................................................................... 337 Pierwsza próba u(cid:276)ycia imitacji w celu zapewnienia izolacji .................................................... 338 U(cid:276)ycie side_effect do sprawdzenia sekwencji zdarze(cid:254) ......................................................339 Pos(cid:228)uchaj testu — brzydki test oznacza konieczno(cid:264)(cid:232) refaktoryzacji ....................................... 341 Ponowne utworzenie testów dla widoku, tym razem w pe(cid:228)ni odizolowanych ................... 342 Pozostawienie starych zintegrowanych testów jako punktu odniesienia .......................342 Nowy zestaw w pe(cid:228)ni odizolowanych testów ......................................................................342 My(cid:264)limy w kategoriach wspó(cid:228)pracy .......................................................................................343 Przej(cid:264)cie w dó(cid:228) do warstwy formularzy ....................................................................................... 347 Nadal s(cid:228)uchaj testów — usuni(cid:246)cie kodu ORM z aplikacji ..................................................348 Wreszcie przechodzimy w dó(cid:228) do warstwy modelu ................................................................. 350 Powrót do widoków ..................................................................................................................352 Moment prawdy (i ryzyko zwi(cid:241)zane z imitacjami) ................................................................... 353 Potraktowanie interakcji mi(cid:246)dzy warstwami jak kontraktów ................................................. 354 Identyfikacja niejawnych kontraktów ....................................................................................355 Usuni(cid:246)cie przeoczonego problemu .........................................................................................356 Jeszcze jeden test ............................................................................................................................... 357 Porz(cid:241)dkowanie, czyli co zachowa(cid:232) z pakietu testów zintegrowanych? ................................ 358 Usuni(cid:246)cie powielonego kodu w warstwie formularzy .......................................................358 Usuni(cid:246)cie starej implementacji widoku .................................................................................359 Usuni(cid:246)cie zb(cid:246)dnego kodu w warstwie formularzy .............................................................359 Podsumowanie — testy odizolowane kontra zintegrowane .................................................... 360 Niech poziom skomplikowania b(cid:246)dzie Twoim przewodnikiem ......................................361 Czy powinienem tworzy(cid:232) oba rodzaje testów? ....................................................................361 Do przodu! ...................................................................................................................................362 20. Ci(cid:233)g(cid:293)a integracja ........................................................................................................363 Instalacja serwera Jenkins ............................................................................................................... 363 Konfiguracja zabezpiecze(cid:254) w Jenkins ....................................................................................365 Dodanie wymaganych wtyczek ..............................................................................................365 Konfiguracja projektu ...................................................................................................................... 367 Pierwsza kompilacja ......................................................................................................................... 368 Konfiguracja ekranu wirtualnego, aby testy funkcjonalne mo(cid:276)na by(cid:228)o wykonywa(cid:232) bez monitora ................................................................................................................................... 370 Wykonanie zrzutów ekranu ........................................................................................................... 371 Najcz(cid:246)stszy problem w Selenium — stan wy(cid:264)cigu .................................................................... 374 Wykonanie testów QUnit w Jenkins za pomoc(cid:241) PhantomJS ................................................... 376 Instalacja node ............................................................................................................................377 Dodanie kolejnych kroków kompilacji w Jenkins ................................................................378 Wi(cid:246)cej zada(cid:254) do wykonania za pomoc(cid:241) serwera ci(cid:241)g(cid:228)ej integracji ......................................... 380 Spis tre(cid:316)ci (cid:95) 11 Poleć książkęKup książkę 21. Token serwisów spo(cid:293)eczno(cid:316)ciowych, wzorzec strony i (cid:235)wiczenie dla czytelnika ... 381 Test funkcjonalny z wieloma u(cid:276)ytkownikami i funkcja addCleanup() ................................. 381 Implementacja w Selenium wzorca interakcja-oczekiwanie .................................................... 383 Wzorzec strony ................................................................................................................................. 384 Rozszerzenie testu funkcjonalnego na drugiego u(cid:276)ytkownika i stron(cid:246) „Moje listy” .......... 386 (cid:231)wiczenie dla czytelnika ................................................................................................................. 388 22. Szybkie testy, wolne testy i gor(cid:233)ca lawa ................................................................. 391 Teza — testy jednostkowe s(cid:241) niezwykle szybkie, maj(cid:241) tak(cid:276)e inne zalety ............................. 392 Szybsze testy oznaczaj(cid:241) szybsze tworzenie kodu ................................................................392 Uczucie b(cid:228)ogostanu ....................................................................................................................393 Wolne testy nie s(cid:241) wykonywane zbyt cz(cid:246)sto, co przek(cid:228)ada si(cid:246) na gorszej jako(cid:264)ci kod ....393 Teraz jest dobrze, ale wraz z up(cid:228)ywem czasu testy zintegrowane s(cid:241) wykonywane coraz wolniej ..............................................................................................393 Nie zabieraj mi tego ...................................................................................................................393 Testy jednostkowe pozwalaj(cid:241) przygotowa(cid:232) dobry projekt ................................................394 Problemy zwi(cid:241)zane z czystymi testami jednostkowymi ........................................................... 394 Testy odizolowane mog(cid:241) by(cid:232) trudniejsze w odczycie i zapisie ........................................394 Testy odizolowane nie testuj(cid:241) automatycznie integracji ....................................................394 Testy jednostkowe rzadko przechwytuj(cid:241) nieoczekiwane b(cid:228)(cid:246)dy .......................................394 Testy oparte na imitacji staj(cid:241) si(cid:246) (cid:264)ci(cid:264)le powi(cid:241)zane z implementacj(cid:241) ................................394 Jednak wszystkie wymienione problemy mo(cid:276)na pokona(cid:232) ................................................395 Synteza — jakie mamy oczekiwania wobec testów? ................................................................. 395 Poprawno(cid:264)(cid:232) .................................................................................................................................395 Czytelny, (cid:228)atwy w obs(cid:228)udze kod .............................................................................................395 Produktywna praca ....................................................................................................................395 Oce(cid:254) testy pod k(cid:241)tem korzy(cid:264)ci, jakich oczekujesz dzi(cid:246)ki ich u(cid:276)yciu ...............................396 Rozwi(cid:241)zania architektoniczne ........................................................................................................ 396 Porty i adaptery, czysta architektura i architektura heksagonalna ..................................397 Architektura Functional Core, Imperative Shell ...................................................................398 Podsumowanie .................................................................................................................................. 398 Kieruj si(cid:253) Testing Goat! ............................................................................................. 401 Dodatki ................................................................................................. 403 A PythonAnywhere .......................................................................................................405 B Widoki oparte na klasach Django .............................................................................409 C Przygotowanie serwera za pomoc(cid:233) Ansible ............................................................ 419 D Testowanie migracji bazy danych ............................................................................423 E Co dalej? .....................................................................................................................429 F (cid:315)ci(cid:233)ga .........................................................................................................................433 G Bibliografia ................................................................................................................437 Skorowidz ..................................................................................................................439 12 (cid:95) Spis tre(cid:316)ci Poleć książkęKup książkę ROZDZIA(cid:292) 5. Zapis danych wej(cid:316)ciowych u(cid:348)ytkownika Nasza aplikacja pobiera wpisany przez u(cid:276)ytkownika element listy rzeczy do zrobienia i prze- kazuje go do serwera. Dlatego te(cid:276) mo(cid:276)emy gdzie(cid:264) zapisa(cid:232) wspomniany element i wczyta(cid:232) go pó(cid:274)niej, gdy zajdzie potrzeba. Kiedy zaczyna(cid:228)em pisa(cid:232) ten rozdzia(cid:228), od pocz(cid:241)tku zastanawia(cid:228)em si(cid:246) nad odpowiednim roz- wi(cid:241)zaniem dla naszej aplikacji: wiele modeli dla list i elementów listy, wiele ró(cid:276)nych adre- sów URL przeznaczonych do dodawania nowych list i elementów, trzy nowe funkcje widoku i kilka nowych testów jednostkowych dla wymienionych wcze(cid:264)niej komponentów. W pewnym momencie zatrzyma(cid:228)em si(cid:246). Wprawdzie uzna(cid:228)em si(cid:246) za wystarczaj(cid:241)co sprytnego, aby jedno- cze(cid:264)nie ogarn(cid:241)(cid:232) wszystkie wymienione problemy, ale istota technik TDD polega na umo(cid:276)li- wieniu programi(cid:264)cie wykonywania zada(cid:254) pojedynczo, gdy zachodzi taka potrzeba. Zdecy- dowa(cid:228)em si(cid:246) wi(cid:246)c na celowy skrót i wykonywanie w danym momencie tylko tych zada(cid:254), które s(cid:241) niezb(cid:246)dne do posuni(cid:246)cia nieco naprzód testów funkcjonalnych. Pokazuj(cid:246) tutaj, jak techniki TDD mog(cid:241) obs(cid:228)ugiwa(cid:232) iteracyjny styl programowania. Nie jest to najszybsza droga, ale ostatecznie i tak by(cid:264) si(cid:246) spotka(cid:228) z tego rodzaju podej(cid:264)ciem. Pozytyw- nym efektem ubocznym przyj(cid:246)tego podej(cid:264)cia b(cid:246)dzie mo(cid:276)liwo(cid:264)(cid:232) wprowadzenia nowych kon- cepcji, takich jak modele, praca z (cid:276)(cid:241)daniami POST, znaczniki szablonów Django itd. Wymie- nione koncepcje b(cid:246)d(cid:246) móg(cid:228) przedstawia(cid:232) pojedynczo, zamiast jednocze(cid:264)nie zarzuci(cid:232) Ci(cid:246) nimi wszystkimi. To oczywi(cid:264)cie nie oznacza, (cid:276)e nie powiniene(cid:264) próbowa(cid:232) my(cid:264)le(cid:232) z wyprzedzeniem i by(cid:232) sprytnym. W nast(cid:246)pnym rozdziale w znacznie wi(cid:246)kszym stopniu wykorzystamy projektowanie oraz przygotowywanie interfejsu i przekonasz si(cid:246), jak to si(cid:246) wpisuje w stosowanie technik TDD. W tym rozdziale mo(cid:276)esz si(cid:246) nad tym jeszcze nie zastanawia(cid:232) i po prostu robi(cid:232) to, czego wy- magaj(cid:241) od nas testy. Od formularza sieciowego do wykonania (cid:348)(cid:233)dania POST Na ko(cid:254)cu poprzedniego rozdzia(cid:228)u komunikaty generowane przez testy wskazuj(cid:241) na brak mo(cid:276)liwo(cid:264)ci zapisu danych wej(cid:264)ciowych u(cid:276)ytkownika. Teraz wykorzystamy standardowe (cid:276)(cid:241)- danie POST w HTML. Wprawdzie to nieco nudne, ale jednocze(cid:264)nie elegancie i (cid:228)atwe do osi(cid:241)- gni(cid:246)cia rozwi(cid:241)zanie, a ponadto pozwoli nam na u(cid:276)ycie kodu HTML5 i JavaScript w dalszej cz(cid:246)(cid:264)ci ksi(cid:241)(cid:276)ki. 73 Poleć książkęKup książkę Aby przegl(cid:241)darka internetowa wygenerowa(cid:228)a (cid:276)(cid:241)danie POST, element input musi posiada(cid:232) atrybut name= i zosta(cid:232) opakowany znacznikiem form wraz z atrybutem method= POST . W takim przypadku przegl(cid:241)darka internetowa automatycznie zajmie si(cid:246) wygenerowa- niem (cid:276)(cid:241)dania POST. Spróbujmy dostosowa(cid:232) szablon lists/templates/home.html do wymienionych wymaga(cid:254). Plik lists/templates/home.html: h1 Twoja lista rzeczy do zrobienia /h1 form method= POST input name= item_text id= id_new_item placeholder= Wpisz rzecz do zrobienia / /form table id= id_list_table Teraz po wykonaniu naszych testów funkcjonalnych otrzymamy nieco zawi(cid:228)y i nieoczeki- wany b(cid:228)(cid:241)d: $ python3 functional_tests.py [...] Traceback (most recent call last): File functional_tests.py , line 39, in test_can_start_a_list_and_retrieve_it_later table = self.browser.find_element_by_id( id_list_table ) [...] selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: { method : id , selector : id_list_table } ; Stacktrace [...] Kiedy test funkcjonalny ko(cid:254)czy si(cid:246) nieoczekiwanym niepowodzeniem, wówczas mo(cid:276)emy podj(cid:241)(cid:232) wiele ró(cid:276)nych dzia(cid:228)a(cid:254), aby odszuka(cid:232) (cid:274)ród(cid:228)o b(cid:228)(cid:246)du: (cid:120) Dodanie polece(cid:254) print w celu wy(cid:264)wietlania na przyk(cid:228)ad tekstu bie(cid:276)(cid:241)cej strony. (cid:120) Usprawnienie komunikatu b(cid:228)(cid:246)du, aby wy(cid:264)wietla(cid:228) wi(cid:246)cej informacji o bie(cid:276)(cid:241)cym stanie. (cid:120) R(cid:246)czne odwiedzenie problematycznej witryny. (cid:120) U(cid:276)ycie wywo(cid:228)ania time.sleep() w celu zrobienia przerwy podczas wykonywania testu. W trakcie lektury ksi(cid:241)(cid:276)ki spotkasz si(cid:246) z wszystkimi wymienionymi powy(cid:276)ej dzia(cid:228)aniami. Wywo(cid:228)anie time.sleep() to opcja, z której osobi(cid:264)cie korzystam bardzo cz(cid:246)sto. Wypróbujmy wi(cid:246)c to rozwi(cid:241)zanie w omawianym przyk(cid:228)adzie. Przerw(cid:246) dodamy przed wyst(cid:241)pieniem b(cid:228)(cid:246)du. # Po naci(cid:286)ni(cid:266)ciu klawisza Enter strona zosta(cid:225)a uaktualniona i wy(cid:286)wietla # 1: Kupi(cid:252) pawie pióra jako element listy rzeczy do zrobienia. inputbox.send_keys(Keys.ENTER) import time time.sleep(10) table = self.browser.find_element_by_id( id_list_table ) W zale(cid:276)no(cid:264)ci od szybko(cid:264)ci dzia(cid:228)ania narz(cid:246)dzia Selenium w Twoim komputerze (cid:274)ród(cid:228)o pro- blemu mog(cid:228)e(cid:264) dostrzec ju(cid:276) wcze(cid:264)niej. Jednak po ponownym wykonaniu testów funkcjonal- nych masz wystarczaj(cid:241)co du(cid:276)o czasu na zobaczenie, co tak naprawd(cid:246) si(cid:246) dzieje. Na ekranie powiniene(cid:264) zobaczy(cid:232) stron(cid:246) podobn(cid:241) do pokazanej na rysunku 5.1 i wy(cid:264)wietlaj(cid:241)c(cid:241) wiele wy- generowanych przez Django informacji o b(cid:228)(cid:246)dzie. 74 (cid:95) Rozdzia(cid:293) 5. Zapis danych wej(cid:316)ciowych u(cid:348)ytkownika Poleć książkęKup książkę Rysunek 5.1. Framework Django wy(cid:264)wietla informacje o b(cid:228)(cid:246)dzie CSRF Zabezpieczenia — zaskakuj(cid:233)co zabawne! Je(cid:276)eli nigdy wcze(cid:264)niej nie s(cid:228)ysza(cid:228)e(cid:264) o atakach typu CSRF (ang. cross-site request forgery), to warto teraz nadrobi(cid:232) t(cid:246) zaleg(cid:228)o(cid:264)(cid:232). Podobnie jak w przypadku wszystkich luk w zabezpiecze- niach lektura o genialnych rozwi(cid:241)zaniach pozwalaj(cid:241)cych na wykorzystanie systemu w nie- oczekiwany sposób mo(cid:276)e dostarczy(cid:232) wiele rado(cid:264)ci… Kiedy wróci(cid:228)em na uniwersytet, aby uzyska(cid:232) dyplom z informatyki, zapisa(cid:228)em si(cid:246) na zaj(cid:246)cia z zakresu bezpiecze(cid:254)stwa. Pomy(cid:264)la(cid:228)em wtedy: có(cid:276), to prawdopodobnie b(cid:246)d(cid:241) bardzo nudne zaj(cid:246)cia, ale lepiej, je(cid:264)li b(cid:246)d(cid:246) w nich uczestniczy(cid:228). Okaza(cid:228)o si(cid:246), (cid:276)e to by(cid:228)y najbardziej fascynuj(cid:241)ce zaj(cid:246)cia, jakie mia(cid:228)em na ca(cid:228)ych studiach. W takcie tych zaj(cid:246)(cid:232) du(cid:276)o czasu po(cid:264)wi(cid:246)cili(cid:264)my na hacking oraz rozwa(cid:276)ania, jak systemy mo(cid:276)na wykorzystywa(cid:232) na zupe(cid:228)nie nieoczekiwane sposoby. Jako lektur(cid:246) mog(cid:246) poleci(cid:232) pozycj(cid:246), z której korzysta(cid:228)em podczas moich zaj(cid:246)(cid:232) — In(cid:276)ynieria za- bezpiecze(cid:254)1 napisana przez Rossa Andersona. W wymienionej ksi(cid:241)(cid:276)ce nie znajdziesz zbyt wiele o samej kryptografii, ale zosta(cid:228)a wype(cid:228)niona omówieniem innych interesuj(cid:241)cych tema- tów, takich jak wybór zabezpiecze(cid:254), podrabianie informacji generowanych przez bank, eko- nomia kartrid(cid:276)ów w drukarkach atramentowych, a tak(cid:276)e oszukiwanie my(cid:264)liwców RPA za pomoc(cid:241) ataków metod(cid:241) powtórzenia. To jest do(cid:264)(cid:232) obszerna pozycja, ale zapewniam Ci(cid:246), (cid:276)e nie b(cid:246)dziesz móg(cid:228) si(cid:246) od niej oderwa(cid:232). 1 http://helion.pl/ksiazki/inzynieria-zabezpieczen-ross-anderson,a_000w.htm Od formularza sieciowego do wykonania (cid:348)(cid:233)dania POST (cid:95) 75 Poleć książkęKup książkę Oferowane przez framework Django zabezpieczenia przed atakami typu CSRF obejmuj(cid:241) mi(cid:246)dzy innymi umieszczenie w ka(cid:276)dym wygenerowanym formularzu niewielkiego tokenu. Dzi(cid:246)ki temu (cid:276)(cid:241)danie POST mo(cid:276)na zidentyfikowa(cid:232) jako pochodz(cid:241)ce z pierwotnej witryny. Jak dot(cid:241)d oma- wiany szablon sk(cid:228)ada si(cid:246) wy(cid:228)(cid:241)cznie z kodu HTML. Kolejnym krokiem jest wi(cid:246)c wykorzystanie po raz pierwszy oferowanej przez Django magii szablonów. W celu dodania tokenu CSRF u(cid:276)yjemy tak zwanego znacznika szablonu sk(cid:228)adaj(cid:241)cego si(cid:246) z nawiasu klamrowego i znaku procentu. Wymie- niony znacznik jest znany jako najbardziej irytuj(cid:241)ca na (cid:264)wiecie kombinacja dwóch klawiszy. Plik lists/templates/home.html: form method= POST input name= item_text id= id_new_item placeholder= Wpisz rzecz do zrobienia / { csrf_token } /form Podczas generowania strony Django zast(cid:241)pi dodany znacznik elementem input type= hidden zawieraj(cid:241)cym token CSRF. Ponowne wykonanie testu zako(cid:254)czy si(cid:246) teraz oczekiwanym nie- powodzeniem: AssertionError: False is not true : Nowy element nie znajduje si(cid:218) w tabeli. Poniewa(cid:276) w kodzie nadal znajduje si(cid:246) wywo(cid:228)anie time.sleep(), wykonywanie testu zostanie przerwane na pewien czas i b(cid:246)dziesz móg(cid:228) zobaczy(cid:232), (cid:276)e nowy element listy znika po wys(cid:228)aniu formularza, a strona zostaje od(cid:264)wie(cid:276)ona i ponownie wy(cid:264)wietla pusty formularz. Po prostu nie skonfigurowali(cid:264)my jeszcze serwera do obs(cid:228)ugi (cid:276)(cid:241)da(cid:254) POST. Dlatego te(cid:276) s(cid:241) one ignorowane, a przegl(cid:241)darka internetowa wy(cid:264)wietla zwyk(cid:228)(cid:241) stron(cid:246) g(cid:228)ówn(cid:241). Teraz mo(cid:276)emy ju(cid:276) usun(cid:241)(cid:232) wywo(cid:228)anie time.sleep(). Plik functional_tests.py: # 1: Kupi(cid:252) pawie pióra jako element listy rzeczy do zrobienia. inputbox.send_keys(Keys.ENTER) table = self.browser.find_element_by_id( id_list_table ) Przetwarzanie (cid:348)(cid:233)dania POST w serwerze Poniewa(cid:276) w formularzu sieciowym nie u(cid:276)yli(cid:264)my atrybutu action=, po jego wys(cid:228)aniu nast(cid:246)- puje domy(cid:264)lnie przej(cid:264)cie do adresu URL, w którym nast(cid:241)pi(cid:228)o wygenerowanie formularza (na przyk(cid:228)ad /). W omawianym przypadku wy(cid:264)wietlanie strony jest obs(cid:228)ugiwane przez funkcj(cid:246) home_page(). Przystosujmy wi(cid:246)c widok do obs(cid:228)ugi (cid:276)(cid:241)dania POST. To oznacza konieczno(cid:264)(cid:232) utworzenia nowego testu jednostkowego dla widoku home_page. Otwórz plik lists/tests.py i dodaj now(cid:241) metod(cid:246) do HomePageTest. Osobi(cid:264)cie skopiowa(cid:228)em po- przedni(cid:241) metod(cid:246), a nast(cid:246)pnie przystosowa(cid:228)em j(cid:241) do obs(cid:228)ugi (cid:276)(cid:241)dania POST i upewni(cid:228)em si(cid:246), (cid:276)e zwrócony kod HTML zawiera tekst nowego elementu listy rzeczy do zrobienia. Plik lists/tests.py (ch05l005): def test_home_page_returns_correct_html(self): [...] def test_home_page_can_save_a_POST_request(self): request = HttpRequest() request.method = POST request.POST[ item_text ] = Nowy element listy response = home_page(request) self.assertIn( Nowy element listy , response.content.decode()) 76 (cid:95) Rozdzia(cid:293) 5. Zapis danych wej(cid:316)ciowych u(cid:348)ytkownika Poleć książkęKup książkę Czy zastanowi(cid:228)y Ci(cid:246) puste wiersze w kodzie nowej metody? Na pocz(cid:241)tku zgrupo- wa(cid:228)em trzy wiersze zawieraj(cid:241)ce konfiguracj(cid:246) testu. Jeden wiersz w (cid:264)rodku to fak- tyczne wywo(cid:228)anie testowanej funkcji, natomiast na ko(cid:254)cu mamy asercj(cid:246). Wprawdzie stosowanie takiego rozwi(cid:241)zania nie jest obligatoryjne, ale pomaga w dostrze(cid:276)eniu struktury testu. Konfiguracja, sprawdzenie i asercja to typowa struktura testu jed- nostkowego. Jak mo(cid:276)esz zobaczy(cid:232), w kodzie u(cid:276)yli(cid:264)my dwóch atrybutów specjalnych obiektu HttpRequest: .method i .POST (ich nazwy powinny wyra(cid:274)nie wskazywa(cid:232) przeznaczenie atrybutów, ale i tak warto zajrze(cid:232) do po(cid:264)wi(cid:246)conej im dokumentacji2 w witrynie Django). Nast(cid:246)pnie sprawdzamy, czy tekst przekazany w (cid:276)(cid:241)daniu POST znajduje si(cid:246) w wygenerowanym kodzie HTML. Wynikiem jest oczekiwane niepowodzenie testu: $ python3 manage.py test [...] AssertionError: Nowy element listy not found in html [...] Test mo(cid:276)e zosta(cid:232) zaliczony przez dodanie polecenia if i dostarczenie zupe(cid:228)nie innego kodu przeznaczonego do obs(cid:228)ugi (cid:276)(cid:241)da(cid:254) POST. W typowym stylu TDD rozpoczynamy od celowego zdefiniowania zupe(cid:228)nie nieprawid(cid:228)owej warto(cid:264)ci zwrotnej. Plik lists/views.py: from django.http import HttpResponse from django.shortcuts import render def home_page(request): if request.method == POST : return HttpResponse(request.POST[ item_text ]) return render(request, home.html ) W ten sposób test jednostkowy zostaje zaliczony, ale tak naprawd(cid:246) to nie jest rozwi(cid:241)zanie, które nas interesuje. Naszym celem jest umieszczenie w tabeli wy(cid:264)wietlanej na stronie g(cid:228)ównej danych przekazanych przez (cid:276)(cid:241)danie POST. Przekazanie zmiennych Pythona do wygenerowania w szablonie Mieli(cid:264)my ju(cid:276) przedsmak, a teraz zaczniemy w pe(cid:228)ni wykorzystywa(cid:232) pot(cid:246)(cid:276)ne mo(cid:276)liwo(cid:264)ci sk(cid:228)adni szablonów Django, co pozwoli na przekazywanie zmiennych z kodu widoku Pythona do sza- blonów HTML. Na pocz(cid:241)tek musisz zobaczy(cid:232), jak sk(cid:228)adnia szablonu pozwala na umieszczenie w nim obiektu Pythona. Notacja w postaci {{ ... }} wy(cid:264)wietla obiekt jako ci(cid:241)g tekstowy. Plik lists/templates/home.html: body h1 Twoja lista rzeczy do zrobienia /h1 form method= POST input name= item_text id= id_new_item placeholder= Wpisz rzecz do zrobienia / { csrf_token } /form 2 https://docs.djangoproject.com/en/1.7/ref/request-response/ Przekazanie zmiennych Pythona do wygenerowania w szablonie (cid:95) 77 Poleć książkęKup książkę table id= id_list_table tr td {{ new_item_text }} /td /tr /table /body W jaki sposób mo(cid:276)na sprawdzi(cid:232), czy widok otrzymuje prawid(cid:228)ow(cid:241) warto(cid:264)(cid:232) dla new_item_text? Jak w ogóle mo(cid:276)na przekaza(cid:232) zmienn(cid:241) do szablonu? Mo(cid:276)emy si(cid:246) o tym przekona(cid:232), faktycznie wykonuj(cid:241)c test jednostkowy. Funkcji render_to_string() u(cid:276)yli(cid:264)my w poprzednim te(cid:264)cie jed- nostkowym w celu r(cid:246)cznego wygenerowania szablonu i porównania go z kodem HTML wy- generowanym przez widok. Teraz dodamy zmienn(cid:241), która ma zosta(cid:232) przekazana. Plik lists/tests.py: self.assertIn( Nowy element listy , response.content.decode()) expected_html = render_to_string( home.html , { new_item_text : Nowy element listy } ) self.assertEqual(response.content.decode(), expected_html) Jak mo(cid:276)esz zobaczy(cid:232), funkcja render_to_string() pobiera jako drugi argument mapowanie nazw zmiennych na warto(cid:264)ci. Szablon otrzymuje zmienn(cid:241) o nazwie new_item_text, której warto(cid:264)ci(cid:241) powinien by(cid:232) tekst pobrany z (cid:276)(cid:241)dania POST. Po wykonaniu testu jednostkowego funkcja render_to_string() zast(cid:241)pi wewn(cid:241)trz elementu td notacj(cid:246) {{ new_item_text }} warto(cid:264)ci(cid:241) Nowy element listy. Rzeczywisty widok nie wyko- nuje takiej operacji, a wi(cid:246)c powinni(cid:264)my spodziewa(cid:232) si(cid:246) niepowodzenia testu: self.assertEqual(response.content.decode(), expected_html) AssertionError: Nowy element listy != html \n head \n [...] Doskonale. Celowo ustalona wcze(cid:264)niej nieprawdziwa warto(cid:264)(cid:232) zwrotna nie b(cid:246)dzie d(cid:228)u(cid:276)ej oszukiwa(cid:228)a testów. Mo(cid:276)emy wi(cid:246)c zmodyfikowa(cid:232) kod widoku i nakaza(cid:232) mu przekazanie pa- rametru POST do szablonu. Plik lists/views.py (ch05l009): def home_page(request): return render(request, home.html , { new_item_text : request.POST[ item_text ], }) Teraz ponownie wykonujemy test jednostkowy: ERROR: test_home_page_returns_correct_html (lists.tests.HomePageTest) [...] new_item_text : request.POST[ item_text ], KeyError: item_text Wynikiem testu jest oczekiwane niepowodzenie. Je(cid:276)eli przypomnisz sobie regu(cid:228)y odczytu stosu wywo(cid:228)a(cid:254), to zauwa(cid:276)ysz, (cid:276)e niepowodzeniem zako(cid:254)czy(cid:228) si(cid:246) inny test. Uda(cid:228)o nam si(cid:246) osi(cid:241)gn(cid:241)(cid:232) zaliczenie testu, nad którym pracowali(cid:264)my. Natomiast wybrane testy jednostkowe spowodowa(cid:228)y powstanie nieoczekiwanych konse- kwencji w postaci regresji — uszkodzili(cid:264)my funkcjonalno(cid:264)(cid:232) kodu przeznaczonego do obs(cid:228)ugi sytuacji, gdy nie wyst(cid:246)puje (cid:276)(cid:241)danie POST. Teraz ju(cid:276) widzisz, jak wa(cid:276)ne jest przygotowywanie testów. Wprawdzie w omawianym przypadku mo(cid:276)na si(cid:246) by(cid:228)o spodziewa(cid:232) uszkodzenia funkcjonalno(cid:264)ci, ale wyobra(cid:274) sobie sytu- acj(cid:246), gdy masz z(cid:228)y dzie(cid:254) lub po prostu nie zwróci(cid:228)e(cid:264) wystarczaj(cid:241)cej uwagi. Wówczas testy 78 (cid:95) Rozdzia(cid:293) 5. Zapis danych wej(cid:316)ciowych u(cid:348)ytkownika Poleć książkęKup książkę uchroni(cid:241) przed uszkodzeniem funkcjonalno(cid:264)ci aplikacji, a poniewa(cid:276) stosujemy techniki TDD, to dowiemy si(cid:246) o tym natychmiast. Nie trzeba czeka(cid:232) na reakcj(cid:246) dzia(cid:228)u odpowiedzialnego za kontrol(cid:246) jako(cid:264)ci lub te(cid:276) przechodzi(cid:232) do przegl(cid:241)darki internetowej i r(cid:246)cznie sprawdza(cid:232) witryn(cid:246). Problem mo(cid:276)na usun(cid:241)(cid:232) od razu, a rozwi(cid:241)zanie przedstawiono poni(cid:276)ej. Plik lists/views.py: def home_page(request): return render(request, home.html , { new_item_text : request.POST.get( item_text , ), }) Je(cid:276)eli nie jeste(cid:264) pewien, jak dzia(cid:228)a powy(cid:276)sze rozwi(cid:241)zanie, spójrz na dict.get(). Test jednostkowy powinien zosta(cid:232) teraz zaliczony. Zobaczmy, jak przedstawia si(cid:246) wynik testu funkcjonalnego: AssertionError: False is not true : Nowy element nie znajduje si(cid:218) w tabeli. Có(cid:276), komunikat b(cid:228)(cid:246)du nie okazuje si(cid:246) szczególnie u(cid:276)yteczny. Wykorzystamy wi(cid:246)c kolejn(cid:241) techni- k(cid:246) usuwania b(cid:228)(cid:246)dów z testów funkcjonalnych, czyli poprawimy komunikat b(cid:228)(cid:246)du. To jest praw- dopodobnie najbardziej konstruktywna technika, poniewa(cid:276) poprawione komunikaty b(cid:228)(cid:246)dów ju(cid:276) pozostan(cid:241) w aplikacji i b(cid:246)d(cid:241) pomocne podczas usuwania b(cid:228)(cid:246)dów w
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

TDD w praktyce. Niezawodny kod w języku Python
Autor:

Opinie na temat publikacji:


Inne popularne pozycje z tej kategorii:


Czytaj również:


Prowadzisz stronę lub blog? Wstaw link do fragmentu tej książki i współpracuj z Cyfroteką: