Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00045 005324 19042278 na godz. na dobę w sumie
Programowanie w języku Ruby. Mikrousługi i konteneryzacja - książka
Programowanie w języku Ruby. Mikrousługi i konteneryzacja - książka
Autor: Liczba stron: 248
Wydawca: Helion Język publikacji: polski
ISBN: 978-83-283-5241-4 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> programowanie >> ruby - programowanie
Porównaj ceny (książka, ebook (-35%), audiobook).

Poznaj Ruby on Rails od praktycznej strony!

Ruby to nowoczesny, wieloparadygmatowy, interpretowany język programowania. Wraz z platformą Rails stanowi jedno z najpopularniejszych rozwiązań służących do szybkiego tworzenia aplikacji sieciowych; wspiera wiele znanych serwisów dostępnych w internecie. Ruby on Rails od lat utrzymuje się w ścisłej czołówce platform klasy MVC - dzięki rozbudowanym funkcjom, wysokiej wydajności oraz łatwości pisania kodu, a także możliwości stosowania dużej liczby rozszerzeń.

Jeśli chcesz się dowiedzieć, jak wykorzystać tę platformę w swoich projektach, jesteś na dobrym tropie! Dzięki tej książce poznasz możliwości i konstrukcje języka Ruby oraz mechanizm działania platformy Rails, a w szczególności interfejs Rack. Dowiesz się, jak zapewniać odpowiednią jakość swoich rozwiązań, nauczysz się je uruchamiać przy użyciu technologii wirtualizacji VMware ESXi oraz konteneryzacji Docker na platformach OpenShift Origin, OKD i Nomad. Prześledziwszy praktyczne przykłady, zdobędziesz wiedzę na temat architektury mikrousług, poznasz też sposoby wykorzystania oprogramowania GitLab w funkcji repozytorium kodu, systemu zgłoszeń, bazy wiedzy i narzędzia CI/CD.

Naucz się tworzyć wydajne aplikacje sieciowe z Ruby on Rails!

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

Darmowy fragment publikacji:

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. Redaktor prowadzący: Małgorzata Kulik Projekt okładki: Studio Gravite / Olsztyn Obarek, Pokoński, Pazdrijowski, Zaprucki Grafika na okładce została wykorzystana za zgodą Shutterstock.com 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) Drogi Czytelniku! Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres http://helion.pl/user/opinie/prumik Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję. ISBN: 978-83-283-5241-4 Copyright © Helion 2019 Printed in Poland. • Kup książkę • Poleć książkę • Oceń książkę • Księgarnia internetowa • Lubię to! » Nasza społeczność Spis treści Wstęp ....................................................................................................................11 Rozdział 1. Ruby ......................................................................................................17 Interpreter ....................................................................................................................................... 17 Rozwój ...................................................................................................................................... 18 rvm ............................................................................................................................................ 18 Clojures ............................................................................................................................................ 20 Blok ........................................................................................................................................... 20 Lambda ..................................................................................................................................... 21 Proc ........................................................................................................................................... 21 Różnice między blokami a Proc ............................................................................................ 22 Różnice między Proc a lambdą ............................................................................................. 23 yield ........................................................................................................................................... 24 ObjectSpace ..................................................................................................................................... 25 each_object ............................................................................................................................... 25 finalizer ..................................................................................................................................... 26 Drzewo klas .............................................................................................................................. 26 Statystyka obiektów ................................................................................................................ 27 Metody obiektów .................................................................................................................... 28 Bezpieczeństwo ............................................................................................................................... 29 Poziomy $SAFE ....................................................................................................................... 29 Przykłady .................................................................................................................................. 29 Analiza wydajności ......................................................................................................................... 30 Wydajność mierzona bibliotekami Benchmark i MiniTest .............................................. 30 Profilowanie z ruby-prof ........................................................................................................ 34 Zarządzanie pamięcią ..................................................................................................................... 36 Retencja obiektów ................................................................................................................... 36 Biblioteka get_process_mem ................................................................................................. 37 Wypełnienie pamięci .............................................................................................................. 37 Poleć książkęKup książkę 6 Programowanie w języku Ruby. Mikrousługi i konteneryzacja Abstrakcyjny model pamięci ..................................................................................................39 Odśmiecanie .............................................................................................................................40 Wizualizacja stosu ...................................................................................................................43 Współbieżność .................................................................................................................................47 Biblioteka ..................................................................................................................................47 Wątki .........................................................................................................................................48 Procesy ......................................................................................................................................50 Fibers .........................................................................................................................................52 Wielowątkowość a interpretery .............................................................................................54 Komunikacja między procesami ...........................................................................................54 Przykład ....................................................................................................................................59 Rozszerzenia ....................................................................................................................................65 Konstrukcja ..............................................................................................................................66 Przykład praktyczny ................................................................................................................67 Osadzanie interpretera ............................................................................................................72 Paradygmaty ....................................................................................................................................72 Programowanie strukturalne .........................................................................................................73 Założenia ...................................................................................................................................73 Stan początkowy ......................................................................................................................75 Plik 2d.rb ...................................................................................................................................75 Plik 3d.rb ...................................................................................................................................79 Plik main.rb ..............................................................................................................................82 Programowanie obiektowe ............................................................................................................84 Blockchain ................................................................................................................................84 Metaprogramowanie ......................................................................................................................91 Korzyści .....................................................................................................................................91 Przykład ....................................................................................................................................91 Rozdział 2. Rails ......................................................................................................95 Platforma .......................................................................................................................................... 95 Rozwój ....................................................................................................................................... 97 Konwencja ponad konfigurację ............................................................................................. 98 Instalacja ................................................................................................................................... 98 Minimalistyczne aplikacje w Rails ................................................................................................ 99 Najmniejsza aplikacja ............................................................................................................100 Drugi przykład .......................................................................................................................100 Trzeci przykład ......................................................................................................................102 Rack i middleware .........................................................................................................................103 Rack .........................................................................................................................................103 Rails .........................................................................................................................................104 Poleć książkęKup książkę Spis treści 7 RabbitMQ .......................................................................................................................................106 Tryby pracy .............................................................................................................................107 Komunikacja jednokierunkowa ...........................................................................................107 Komunikacja dwukierunkowa .............................................................................................107 Komunikacja mieszana .........................................................................................................110 Powszechne błędy ..........................................................................................................................110 ActionController::RoutingError ..........................................................................................110 NoMethodError: Undefined Method [] for Nil:NilClass ................................................111 ActionController::InvalidAuthenticityToken ....................................................................111 Net::ReadTimeout ..................................................................................................................112 ActiveRecord::RecordNotUnique: PG::UniqueViolation ................................................112 NoMethodError: Undefined Method id for nil:NilClass ................................................113 ActionController::ParameterMissing ..................................................................................113 ActionView::Template::Error: Undefined Local Variable or Method ............................113 ActionController::UnknownFormat ...................................................................................113 Praktyka a konwencje ...................................................................................................................113 Za dużo logiki w kontrolerach .............................................................................................114 Za dużo logiki w widokach ...................................................................................................114 Za dużo logiki w modelach ...................................................................................................114 Pozostały kod ..........................................................................................................................114 Za dużo bibliotek ....................................................................................................................115 Brak automatycznych testów ................................................................................................115 Tryb API .........................................................................................................................................115 Middleware .............................................................................................................................115 Nowa aplikacja .......................................................................................................................116 find_in_batches ......................................................................................................................116 Rozdział 3. Zapewnienie jakości .............................................................................119 Wprowadzenie ...............................................................................................................................119 Teoria i praktyka ....................................................................................................................119 Metodyki .........................................................................................................................................120 Definicja błędu .......................................................................................................................120 Definicja niezawodności .......................................................................................................121 Przyczyny błędów ..................................................................................................................121 TDD .........................................................................................................................................122 TIP ............................................................................................................................................123 Eksploracja ..............................................................................................................................123 Wykrywanie defektów ..................................................................................................................124 Bierne wykrywanie defektów ................................................................................................124 Czynne wykrywanie defektów ..............................................................................................124 Poleć książkęKup książkę 8 Programowanie w języku Ruby. Mikrousługi i konteneryzacja Tolerancja na błędy ...............................................................................................................127 Izolacja defektów ...................................................................................................................127 Testowanie Rack ............................................................................................................................127 Mikrousługi: lb .......................................................................................................................128 Rack .........................................................................................................................................129 Sinatra .....................................................................................................................................132 Testowanie Rails ............................................................................................................................134 Instalacja .................................................................................................................................135 Funkcje pomocnicze .............................................................................................................136 Przypadki testowe ..................................................................................................................138 Uruchomienie ........................................................................................................................139 Rozdział 4. Wdrożenie ...........................................................................................141 Wprowadzenie ...............................................................................................................................141 Definicja ..................................................................................................................................141 Podejście procesowe ..............................................................................................................142 Proces wdrożeniowy ..............................................................................................................142 Wirtualizacja ..................................................................................................................................143 Rodzaje wirtualizacji .............................................................................................................143 VMware vSphere Hypervisor ...............................................................................................143 Konteneryzacja ..............................................................................................................................148 Docker .....................................................................................................................................148 Inne rozwiązania ....................................................................................................................148 Prywatne chmury obliczeniowe ...........................................................................................148 Publiczne rozwiązania ...........................................................................................................149 Nomad na tle konkurencji ....................................................................................................149 Przykładowa struktura .................................................................................................................150 Środowisko pomocnicze .......................................................................................................151 Utworzenie wirtualnej maszyny ..........................................................................................151 Instalacja systemu operacyjnego .........................................................................................153 OpenShift Origin / OKD ..............................................................................................................154 Wprowadzenie .......................................................................................................................155 Struktura klastra ....................................................................................................................158 Serwer DNS ............................................................................................................................159 Przygotowanie węzłów klastra .............................................................................................161 Przygotowanie instalacji .......................................................................................................164 Instalacja klastra ....................................................................................................................166 Konfiguracja klastra 3.7/3.9 .................................................................................................169 Dodanie nowych węzłów klastra .........................................................................................172 Poleć książkęKup książkę Spis treści 9 Aktualizacja do nowej wersji ................................................................................................173 Administrowanie klastrem ...................................................................................................173 Minishift .........................................................................................................................................174 Instalacja ..................................................................................................................................175 Uruchomienie .........................................................................................................................175 Nomad .............................................................................................................................................178 Wprowadzenie ........................................................................................................................179 Środowisko narzędziowe .......................................................................................................180 Środowisko aplikacyjne .........................................................................................................181 Środowisko uruchomieniowe ...............................................................................................185 GitLab CI/CD .................................................................................................................................193 Wprowadzenie ........................................................................................................................193 Instalacja systemu GitLab .....................................................................................................193 Integracja z systemem OpenShift/OKD .............................................................................194 Wdrażanie aplikacji do systemu OpenShift/OKD ............................................................202 Integracja z systemem Nomad .............................................................................................203 Rozdział 5. Mikrousługi ..........................................................................................205 Wprowadzenie ...............................................................................................................................205 Infrastruktura funkcjonalna .................................................................................................206 Przepływ danych ....................................................................................................................206 DNS ..........................................................................................................................................208 Urządzenie IoT ..............................................................................................................................208 ESP8266 ...................................................................................................................................209 Program testowy ....................................................................................................................210 Program docelowy .................................................................................................................211 NGINX ............................................................................................................................................212 nginx.conf ................................................................................................................................212 Podsumowanie .......................................................................................................................213 lb .......................................................................................................................................................213 config.ru ..................................................................................................................................214 Dockerfile ................................................................................................................................215 Gemfile ....................................................................................................................................216 .gitlab-ci.yml ...........................................................................................................................216 .nomad .....................................................................................................................................217 check_dns .......................................................................................................................................219 check_dns.rb ...........................................................................................................................219 .nomad .....................................................................................................................................219 Poleć książkęKup książkę 10 Programowanie w języku Ruby. Mikrousługi i konteneryzacja rack ..................................................................................................................................................220 config.ru ..................................................................................................................................221 .nomad ....................................................................................................................................222 csp.consumer .................................................................................................................................223 consumer.rb ............................................................................................................................223 Dockerfile ...............................................................................................................................225 fluent.conf ...............................................................................................................................225 Gemfile ....................................................................................................................................226 csp.processor ..................................................................................................................................226 processor.rb ............................................................................................................................226 Rozdział 6. Projekt ................................................................................................229 Wprowadzenie ...............................................................................................................................229 Problem i oczekiwane efekty ................................................................................................229 Źródłowa baza danych ..........................................................................................................230 Stos technologiczny ......................................................................................................................230 Metaprogramowanie .............................................................................................................230 Biblioteki .................................................................................................................................230 Realizacja ........................................................................................................................................231 Prototyp ..................................................................................................................................231 Struktura .................................................................................................................................236 Kontrola dostępu ...................................................................................................................238 UI .............................................................................................................................................240 Użycie ......................................................................................................................................242 Podsumowanie .....................................................................................................243 Wnioski ..........................................................................................................................................243 Rails .........................................................................................................................................243 Orkiestracja ............................................................................................................................243 Ruby .........................................................................................................................................243 Popularność ............................................................................................................................244 Na koniec .......................................................................................................................................244 Przyszłość .......................................................................................................................................244 Bibliografia ..........................................................................................................245 Skorowidz ............................................................................................................246 Poleć książkęKup książkę Rozdział 3. Zapewnienie jakości Quality is not an act, it is a habit. Arystoteles W tym rozdziale: (cid:81) Metodyki (cid:81) Wykrywanie defektów (cid:81) Testowanie Rack (cid:81) Testowanie Rails Wprowadzenie Nieodłącznym elementem tworzenia oprogramowania jest zapewnienie, aby funkcjonowało ono poprawnie i bez istotnych defektów. Pomimo szeregu narzędzi wspomagających unikanie i usuwanie błędów te nadal występują. Dzieje się tak, ponieważ różne są definicje błędu. Najdokładniej planowanym i najobficiej finansowanym oprogramowaniem w historii były programy zbudowane dla obsługi lotów księżycowych Apollo. Przedsięwzięcie to obejmowało najlepszych programistów w kraju, zorganizowanych w dwa współzawodniczące zespoły. Przy sprawdzaniu oprogramowania wykorzystano cały istniejący w tej dziedzinie zasób umiejętności. W sumie oprogramowanie systemu Apollo kosztowało ok. 660 mln dol. Mimo to każde poważniejsze niebezpieczeństwo w trakcie lotów, od fałszywych alarmów do prawdziwych nieszczęść, było bezpośrednio spowodowane błędami w oprogramowaniu. [20] Teoria i praktyka W tym rozdziale omawiam elementy teorii pozwalające zrozumieć, na czym problem polega i skąd się bierze. Właściwe rozpoznanie przyczyn pozwala efektywnie tworzyć oprogramowanie o mniejszej ilości defektów. Poza elementami teoretycznymi przedstawiam konkretne rozwiąza- nia programistyczne na przykładzie testów automatycznych. Poleć książkęKup książkę 120 Programowanie w języku Ruby. Mikrousługi i konteneryzacja Metodyki Podstawy teoretyczne Definicja błędu Wyróżniamy co najmniej kilka definicji błędu, zwanego też usterką lub defektem. Do katastrofy lądownika bezzałogowego na Wenus przyczynił się taki oto błąd w programie napisanym w ję- zyku FORTRAN: DO 3 I = 1.3 Zamiast jako pętla zostało to zinterpretowane jako przypisanie zmiennej DO3I wartości 1.3. Zamiast przecinka użyta została kropka. Błąd oprogramowania występuje wówczas, gdy oprogramowanie nie spełnia sensownych oczekiwań użytkownika. Awaria oprogramowania jest to wystąpienie błędu oprogramowania. [20] Specyfikacja Powszechnie przyjęło się, że błąd jest to sytuacja, gdy oprogramowanie nie zachowuje się zgodnie ze specyfikacją. Oczywiście przy założeniu, że sama specyfikacja i jej zrozumienie przez każdego z zainteresowanych są poprawne. Czynniki zewnętrzne Innego rodzaju definicja wskazuje sytuację trudniejszą w ocenie, mianowicie gdy oprogramo- wanie działa zgodnie ze specyfikacją, ale wystąpiły szczególne okoliczności, które sprawiają, że nie potrafi ono dostarczyć oczekiwanych rezultatów. Przy założeniu, że program i jego moduły powinny być odporne na nieoczekiwane warunki zewnętrzne, taka sytuacja rzeczywiście ma charakter usterki. Dokumentacja Kolejnym elementem, który nosi znamiona błędu, jest niezgodna ze stanem rzeczywistym do- kumentacja techniczna lub użytkownika. Sam program może być zgodny z pierwotnymi założe- niami i specyfikacją. Błędem jest wtedy sama dokumentacja. Oczekiwania Ostatnim powszechnie stosowanym opisem dla błędu jest brak realizacji oczekiwań użytkow- ników. Występuje wtedy zapewne zgodność ze specyfikacją projektu, odporność na otoczenie, a dokumentacja odzwierciedla stan faktyczny funkcjonowania programu. Problemem są tutaj nieprecyzyjnie wyartykułowane wymagania użytkownika podczas zamawiania programu lub w momencie uzgadniania specyfikacji funkcjonalnej. Użytkownik końcowy lub zamawiający mogą stwierdzić, że program działa wadliwie, ponieważ mają co do niego inne oczekiwania. Proces wytwarzania zawodzi wówczas na całej linii. Poleć książkęKup książkę Rozdział 3. (cid:139) Zapewnienie jakości 121 Definicja niezawodności Kolejny termin wart przeanalizowania to niezawodność. Kiedy już wiemy, jak zdefiniować błąd, choć co prawda na kilka różnych sposobów, chcemy dowiedzieć się, jak mierzyć odporność oprogramowania na usterki. Niezawodność oprogramowania jest prawdopodobieństwem, że oprogramowanie działa bez awarii w określonym przedziale czasu, opatrzonym wagą odpowiadającą kosztom poniesionym przez użytkownika z powodu każdej zaistniałej awarii. [20] Przyczyny błędów Proces budowy oprogramowania jest bardzo złożony przede wszystkim z racji występowania w nim czynnika ludzkiego, który jest zawodny. Możemy zatem uogólnić i przytoczyć następują definicję dotyczącą przyczyn występowania usterek: Główną przyczyną błędów oprogramowania są błędy w tłumaczeniu informacji. [20] Badając temat, możemy stwierdzić, że występują dwa rodzaje modeli procesu tłumaczenia. Pierwszy, makroskopowy, zakłada, że projekt programistyczny jest to dziedzina interdyscypli- narna, wymagająca integracji szeregu czynników, w której problemem w głównej mierze jest komunikacja. Drugi zaś, mikroskopowy, opiera się na stwierdzeniu, że niemal każda informacja występująca w takim projekcie jest przetwarzana przez człowieka i to jego niedoskonałości powodują rozbieżności, braki i konflikty. Model makroskopowy Proces, czy też model, obejmuje swoim zasięgiem wyartykułowanie potrzeb przez zamawiają- cego, następnie opracowanie założeń i specyfikacji, powstanie kodu i dokumentacji, a także uzyskanie informacji zwrotnej od użytkowników. (1) Najpierw przedstawiane są wymagania użytkownika, którego jednocześnie możemy nazwać zamawiającym lub sponsorem projektu programistycznego. Na tym etapie głównym pro- blemem jest brak możliwości poprawnego i pełnego przedstawienia potrzeb lub ich błędna interpretacja. (2) Kolejny etap to tłumaczenie wymagań użytkownika na język założeń. Jak nietrudno zgadnąć, błędy popełnione już w poprzednim kroku będą w sposób kumulacyjny dotyczyły kolejnych kroków. Tak też jest w tym przypadku, a dodatkowo sam proces materializacji wymagań w opisie założeń jest źródłem dodatkowych błędów. (3) Etap następny to przekształcenie założeń na specyfikację wysokopoziomową. Jest to doku- mentacja o dużym poziomie abstrakcji, nie zawierająca szczegółów implementacyjnych. (4) Specyfikacja funkcjonalna o wysokim poziomie szczegółowości to kolejny etap w procesie. Informacje tutaj zawarte są istotne z punktu widzenia włączenia wymagań i założeń poprzez język specyfikacji ogólnej do tego, nad czym będzie pracował zespół produkcyjny. Poleć książkęKup książkę 122 Programowanie w języku Ruby. Mikrousługi i konteneryzacja (5) Kolejny etap to programowanie, czyli tłumaczenie specyfikacji na kod źródłowy. Jest to etap, w którym błędy są obecne i stanowią niezbywalną część procesu. Są też relatywnie proste w obsłudze. Model mikroskopowy Człowiek jako uczestnik procesu twórczego angażuje swoje zdolności poznawcze, przyjmując, zapamiętując, wyszukując i przekazując informacje. Istotą zrozumienia problematyki źródeł błędów jest fakt, że człowiek jest po prostu omylny, a swoje działania opiera na subiektyw- nych doświadczeniach, które nie zawsze pasują do każdej napotkanej sytuacji podczas procesu tworzenia oprogramowania. Rolą modeli i poszczególnych procesów dotyczących zapewnienia jakości jest wprowadzenie odpowiednich regulacji, tak aby czynnik ludzki dawał z siebie to co najlepsze w kreatywnym kontekście, jednocześnie nie będąc problematycznym w testowaniu, które jest ewidentnie procesem destruktywnym. TDD Test Driven Development polega na takiej organizacji pracy z kodem aplikacji, że w pierwszej kolejności staramy się stworzyć specyfikację funkcjonalną i idące za tym zestawy testowe. Kod testów biegnie przynajmniej równolegle, idealnie zaś jest, gdy wyprzedza właściwy kod aplikacyjny. Weźmy za przykład poniższy zestaw testowy (Cucumber), definiujący opera- cje związane z fakturowaniem w aplikacji księgowej: Feature: Invoices Scenario: List invoices Given I am logged in as a user Given I am on /invoices page Then page should have notice Faktury Scenario: New invoice Given I am logged in as a user And There is a contractor called PPHU And There is a tax rate of 23 called 23 - naliczony with account 264-2-1 at side WN for year of 2014 And There is a tax type called Podlega opodatkowaniu with code PO And There is a invoice template called Testowy at Fakturowanie And document type Faktura zakupu is linked with Testowy template And I am on /invoices page When I press Nowa Faktura Then page should have notice Nowa Faktura When I fill in invoice[name] with Testowa faktura FV And I select invoice_document_type_id with Faktura zakupu And I press Zapisz Then page should have notice Utworzono now(cid:200) faktur(cid:218) And page should have notice Dokument wprowadzany do systemu And page should have notice Pozycje Faktury When I fill in invoice_invoice_entries_attributes_0_net with 100 And I select invoice_invoice_entries_attributes_0_tax_rate_id with 23 - naliczony And I select invoice_invoice_entries_attributes_0_tax_type_id with Podlega opodatkowaniu And I press Zapisz Then page should have notice Faktura zosta(cid:239)a zaktualizowana When I click on add_element_div And I fill in invoice_invoice_entries_attributes_1_net with 200 Poleć książkęKup książkę Rozdział 3. (cid:139) Zapewnienie jakości 123 And I select invoice_invoice_entries_attributes_1_tax_rate_id with 23 - naliczony And I select invoice_invoice_entries_attributes_1_tax_type_id with Podlega opodatkowaniu And I press Zapisz Then page should have notice Faktura zosta(cid:239)a zaktualizowana When I ensure the confirm box returns OK And I press Zatwierd(cid:283) Then page should have notice Pomy(cid:258)lnie zatwierdzono faktur(cid:218), utworzono dokument w ksi(cid:218)gowo(cid:258)ci And page should have notice Dokument w ksi(cid:218)gowo(cid:258)ci And page should have notice Zatwierdzony And page should not have notice Zapisz And page should not have notice Zatwierd(cid:283) Scenario: Check link between invoicing module and main ledger Given I am logged in as a user And I ensure the confirm box returns OK And I am on /invoices page When I select invoices_grid_document_state_id with Zatwierdzony And I press Szukaj Given I ensure the confirm box returns OK When next to Testowa faktura FV I press Edytuj Then page should have notice Dokument w ksi(cid:218)gowo(cid:258)ci Scenario: Create and move to main ledger Given there is invoice called Testowa faktura FV When I click link Dokument w ksi(cid:218)gowo(cid:258)ci Then page should have notice Faktura w fakturowaniu And page should have notice Rejestr VAT (tylko do odczytu) And page should have notice Dokument wprowadzany do systemu Przykład składa się z weryfikacji listy dokumentów, wystawienia nowej faktury, przeniesienia jej do modułu księgowego oraz sprawdzenia poprawności tej operacji. Należy samodzielnie ocenić, czy na podstawie tak zdefiniowanego testu jesteśmy w stanie opracować kod aplikacji. TIP Testing in Production oznacza wyjście poza strefę komfortu testowanej aplikacji bądź grupy aplikacji. Sprawdzanie poprawności działania w systemie produkcyjnym wiąże się przede wszystkim ze zwiększonym ryzykiem, odpowiedzialnością, potencjalnym wpływem na działanie u klientów itd. Możemy jednak przyjąć, że testowanie tego rodzaju to odwzorowanie zachowań klientów, wtedy rzeczywiście działanie to nie będzie bardzo intruzywne i ujawni zdecydowanie nową kategorię problemów w porównaniu z podejściem tradycyjnym, które zakłada testowanie w środowisku zamkniętym i odseparowanym. Eksploracja Eksploracja, czyli Chaos Testing, oferuje cały zbiór praktyk, którymi możemy się posługiwać, aby sprawdzać odporność systemu na zaburzenia jego funkcjonowania. Przykładowo restartu- jemy bazę danych lub serwer komunikatów. Wytwarzamy w systemie wadliwe komunikaty, sprawdzając, jak zachowają się aplikacje je przetwarzające. Obciążamy system, aby wystąpiły opóźnienia na każdej z możliwych warstw uruchomieniowych. Ostatecznie wyłączamy system, Poleć książkęKup książkę 124 Programowanie w języku Ruby. Mikrousługi i konteneryzacja a potem sprawdzamy, co się stanie, kiedy wróci on do działania. CT to koncepcja, która pozwala na bardzo kreatywne podejście do procesu testowania, daleko wychodzące poza regularne ramy. Wykrywanie defektów Właściwością człowieka jest błądzić, głupiego — w błędzie trwać. Cyceron Nie należy nigdy zakładać, że tworzone oprogramowanie będzie pozbawione błędów. Jako twórcy programów możemy wykrywać, poprawiać i tolerować błędy. Z pewnością najtrudniejsze, ale i najbardziej efektywne jest unikanie usterek na etapie gromadzenia wymagań i ich przekłada- nia na język specyfikacji. Projektowanie oprogramowania powinno domyślnie obejmować mechanizmy obsługi usterek. Optymalnym podejściem jest eliminowanie potencjalnych przyszłych problemów na etapie ana- lizy i wczesnego projektowania. Wyróżniamy dwa podejścia w obsłudze wykrywania defek- tów, a mianowicie bierne i czynne. Bierne wykrywanie defektów Komponenty programu powinny być względnie niezależne i zachowywać wzajemną podejrzli- wość co do założeń swojego funkcjonowania. Anomalie w działaniu chcemy wykrywać jak naj- wcześniej, tak aby ich skutki nie nabrały charakteru awarii, lecz jedynie zwykłego błędu. Wobec tego powinniśmy przeprowadzać wiele walidacji, czyli sprawdzeń poprawności wykorzystania poszczególnych fragmentów programu. Stosowanie zasady ograniczonego zaufania do zewnętrz- nych zasobów, danych, kodu, sprzętu też jest bardzo dobrą praktyką w tym zakresie. Dodat- kowo, jeśli dany system składa się z szeregu komponentów działających równolegle i wymienia- jących się komunikatami, nie możemy być nigdy pewni co do jakości i czasu takiej transmisji. Czynne wykrywanie defektów Innym podejściem do wykrywania defektów jest mechanizm, który cyklicznie analizuje stan programu i generowanych przez niego danych. Opiera się zatem na predefiniowanych zakre- sach, których przekroczenie oznacza konieczność wykonania korekty. Możemy taki mechanizm nazwać monitorem lub systemem kontrolnym. Stosowanie tego podejścia zda egzamin szczególnie w przypadku utrzymywania oprogramowania wytworzonego w poprzednich latach i którego działanie nie jest do końca poznane i zrozumiałe dla operatora. Mikrousługi zakładają dużą dekompozycję struktury aplikacji. Bazy danych dedykowane są po- szczególnym komponentom systemu, a ich liczba przekłada się na ilość problemów w zarządza- niu ich strukturą i zmianami oraz panowaniu nad jakością znajdujących się w nich danych. Pytanie zatem nie brzmi, czy baza ma usterki, lecz ile ich jest i jak szybko możemy je zidentyfikować. Poleć książkęKup książkę Rozdział 3. (cid:139) Zapewnienie jakości 125 Poniższy przykład to program służący do analizy tabel bazy danych. Stosuje on podstawowe funkcje statystyczne. Plik 01_db_quality.rb: #******************************************************************************* # Biblioteki #******************************************************************************* require rubygems require json require active_record require active_support require active_support/core_ext require json #******************************************************************************* # Parametryzacja #******************************************************************************* PARAM_DB_NAME = ARGV[0] PARAM_DB_USER = ARGV[1] PARAM_DB_PASS = ARGV[2] #******************************************************************************* # Po(cid:225)(cid:261)czenie #******************************************************************************* conn = ActiveRecord::Base.establish_connection(:adapter= postgresql , :encoding= unicode , :pool= 1, :database= #{PARAM_DB_NAME} , :username= #{PARAM_DB_USER} , :password= #{PARAM_DB_PASS} , :host= 172.28.128.11 ) if conn.nil? then raise !: NO -AR- CONNECTION end #******************************************************************************* # Dynamiczne mapowanie klas ActiveRecord #******************************************************************************* tables = conn.connection.tables tables.each do |table| class_name = table.classify begin eval DYNAMIC class #{class_name} ActiveRecord::Base self.table_name = #{table} self.inheritance_column = :_type_disabled end DYNAMIC rescue end # begin/rescue end # tables def top_bottom(t) val = if !t[0].to_s.blank? then val = t[0].to_s.delete( \n ).to_s[0..19].gsub( , ) end # if return { #{val} : t[1].to_s } end # top_bottom Poleć książkęKup książkę 126 Programowanie w języku Ruby. Mikrousługi i konteneryzacja #******************************************************************************* # Statystyka #******************************************************************************* ActiveSupport::Deprecation.silenced = true Time::DATE_FORMATS[:no_timezone] = Y- m- d H: M: S $stdout.sync = true json = {} tables.each do |table| if table == files then next end tbl = {} fields = [] cnt = table.classify.constantize.count tbl[:count] = cnt limit = 29 table.classify.constantize.new.attributes.map { |x| attrs = {} field = x[0] if !field.blank? then last_nn_val = table.classify.constantize .select(field).last[field].to_s[0..limit] rescue N\A null_count = table.classify.constantize .where( #{field} IS NULL ).count rescue N/A min_val = table.classify.constantize .where( #{field} IS NOT NULL ).minimum( #{field} ).to_s[0..limit] rescue N/A max_val = table.classify.constantize .where( #{field} IS NOT NULL ).maximum( #{field} ).to_s[0..limit] rescue N/A avg_val = table.classify.constantize .where( #{field} IS NOT NULL ).average( #{field} ).to_s[0..limit] rescue N/A top10 = table.classify.constantize .group( #{field} ).order( COUNT(#{field}) DESC ).limit(10).count bottom10 = table.classify.constantize .group( #{field} ).order( COUNT(#{field}) ASC ).limit(10).count distinct = table.classify.constantize.select( DISTINCT #{field} ).count attrs[:name] = x[0] attrs[:uniq] = distinct attrs[:last] = last_nn_val attrs[:null] = #{null_count} (#{((null_count.to_f/cnt.to_f)*100) rescue - } ) attrs[:min] = min_val attrs[:max] = max_val attrs[:avg] = avg_val tops = [] bottoms = [] top10.each do |t| tops top_bottom(t) end # top10 bottom10.each do |t| bottoms top_bottom(t) end # bottom10 attrs[:tops] = tops attrs[:bottoms] = bottoms else raise !: FIELD IS BLANK end # if fields attrs } # fields tbl[:fields] = fields Poleć książkęKup książkę Rozdział 3. (cid:139) Zapewnienie jakości 127 json[table] = tbl end # tables puts json.to_json Powyższy przykład wykorzystuje funkcje COUNT, MIN, MAX, AVG i DISTINCT jako podstawowy zestaw informacji na każdej z kolumn tabeli. Cała struktura pobierana jest za pośrednictwem bi- blioteki ActiveRecord, a modele są tworzone dynamicznie za pomocą biblioteki ActiveSupport. Prezentowane są wartości ostatnie, najpopularniejsze oraz najmniej popularne. Oto fragment przykładowego wyniku w formacie JSON: name : content , uniq : 939, last : 4 , null : 0 (0.0 ) , min : 10 , Tolerancja na błędy W ramach każdego projektu możemy zdefiniować pewną kategorię problemów, których obec- ność nie będzie powodowała przestojów całego systemu, lecz jedynie drobne niedogodności. Warto zatem zbudować bazę wiedzy dotyczącą priorytetyzacji poszczególnych kategorii usterek i taką dokumentacją zasilić zespoły odpowiedzialne za utrzymanie systemu w ruchu oraz grupy kontaktujące się z użytkownikami końcowymi. Należy bowiem przyjąć, że pewne sytuacje krań- cowe występują, a koszt i czas ich korekty przewyższa potencjalne zyski w tym zakresie. Izolacja defektów Od strony projektowania oprogramowania możemy wskazać programowanie obiektowe i struktu- ralne jako fundamenty, na których zbudujemy niezależne względem siebie jednostki, ko- munikujące się na zasadzie ograniczonego zaufania. To podejście pozwala unikać pewnych problemów. Testowanie Rack Przegl(cid:261)d rozwi(cid:261)za(cid:276) Aplikacje wykonane z wykorzystaniem interfejsu Rack przeważnie są niewielkich rozmiarów i słu- żą do ograniczonych zastosowań. Można je spotkać jako element architektury mikrousług. Ofe- rują w większości przypadków jedynie interfejs HTTP, zatem testowanie opiera się głównie na tej właśnie warstwie abstrakcji. Przedstawiam tutaj przykłady testowania aplikacji z interfejsem Rack i jego wariantem w postaci platformy Sinatra. Zaczniemy jednak od przykładu opartego na jednej spośród aplikacji z pro- ponowanego zestawu mikrousług, lb. Poleć książkęKup książkę 128 Programowanie w języku Ruby. Mikrousługi i konteneryzacja Mikrousługi: lb Komponent ten odpowiedzialny jest za rozdzielanie ruchu pomiędzy poszczególne instancje aplikacji z interfejsem Rack uruchomionych na portach z wysokiego zakresu dynamicznie przy- dzielanych przez orkiestratora. config.ru Definiujemy tutaj, że chcemy załadować plik z głównym programem oraz wywołać metodę run, która inicjalizuje cały przepływ żądań. Aplikacja w tej formie jest uruchamiana za pośrednic- twem polecenia rackup. load app_proxy.rb run AppProxy.new app_proxy.rb Zawartość tego pliku jest identyczna jak w przykładzie podanym w części dotyczącej mikro- usług, komponentu lb. Zamiast jednak znaleźć się w pliku config.ru tutaj jest to wydzielone w celu uzyskania możliwości załączania tego pliku do zestawu testowego. test/test.rb Jest to plik z testem przeprowadzonym z wykorzystaniem biblioteki MiniTest. Załączamy minitest/autorun i rack/test. Ładujemy plik z programem app_proxy.rb. Wczytywane są metody pomocnicze Rack::Test. Test definiuje metodę app, która udostępnia instancję naszej aplikacji do poszczególnych przypadków testowych. require rubygems require bundler/setup require rack/test require minitest/autorun load app_proxy.rb class RackProxyTestSuite MiniTest::Test include Rack::Test::Methods def app() AppProxy.new end # app def test_success get / , nil, { SERVER_NAME = rack.home.lab } assert_equal (last_response.status).to_i, 200 end # test_success def test_no_backend_available begin get / , nil, { SERVER_NAME = no-backend.home.lab } assert_equal (last_response.status).to_i, 200 rescue Exception = e assert_equal !: no backend available , e.to_s end # begin/rescue end # test_no_backend_available end # RackProxyTestSuite Poleć książkęKup książkę Rozdział 3. (cid:139) Zapewnienie jakości 129 Zestaw dostarcza dwa przypadki testowe. Pierwszy z nich, test_success, oczekuje poprawnego wywołania całej ścieżki, począwszy od przetwarzania nazwy domenowej, ekstrakcji subdomeny, sprawdzania serwerów DNS oraz wyszukiwania dostępnych instancji aplikacji docelowej. Drugi przypadek testowy, wywołując żądanie typu get, ustawia jednocześnie adres domenowy, pod którym nie jest znana żadna instancja aplikacji w klastrze i w katalogu Consul (wykorzystamy bowiem Nomad jako orkiestrator). Przechwytując wyjątek, sprawdzamy zwrotny tekst z aplika- cji, oczekując, że będzie on określał właśnie takie zachowanie. Uruchomienie Aby wykonać zestaw testowy, należy wykonać następujące polecenie: [sobczam@home lb]$ ruby test/test.rb Run options: --seed 16224 # Running: .. Finished in 0.056790s, 35.2174 runs/s, 35.2174 assertions/s. 2 runs, 2 assertions, 0 failures, 0 errors, 0 skips Uzyskujemy informacje o czasie wykonywania, wydajności testów oraz ilości przypadków testo- wych z podziałem na poprawnie i błędnie wykonane. Rack Poprzedni przykład, dotyczący aplikacji lb, odnosił się do biblioteki rack/proxy i nie był zbyt reprezentatywny dla większości przypadków standardowych aplikacji opartych na interfejsie Rack. W tej sekcji omówię aplikację wzorcową oraz kilka różnych zestawów testowych przygo- towanych z wykorzystaniem biblioteki RSpec (gem install rspec). application.rb Jest to standardowa aplikacja oparta na interfejsie Rack, która definiuje metodę call. Obsługuje żądania HTTP, mając dostęp do obiektu środowiskowego env, który dostarcza informacji o szczegółach żądania. class Application def call(env) handle_request(env[ REQUEST_METHOD ], env[ PATH_INFO ]) end # call private def handle_request(method, path) if method == GET get(path) else method_not_allowed(method) end end # handle_request def get(path) [200, { Content-Type = text/html }, [ You have requested the path #{path}, using GET ]] Poleć książkęKup książkę 130 Programowanie w języku Ruby. Mikrousługi i konteneryzacja end # get def method_not_allowed(method) [405, {}, [ Method not allowed: #{method} ]] end # method_not_allowed end # Application Obsługa żądania polega na zwróceniu w ścieżce przetwarzania tablicy z odpowiedzią w postaci kodu odpowiedzi, nagłówków oraz samej treści. W przykładzie użyte są kody 200 i 405. test_0_spec.rb Pierwszy przypadek testowy operuje na surowych obiektach i wywołaniach. Tworzymy instancję aplikacji wywołaniem Application.new. Definiujemy metodę żądania jako GET oraz ścieżkę wywołania. load application.rb describe Application do context get to /some/url do it returns the body do app = Application.new env = { REQUEST_METHOD = GET , PATH_INFO = /some/url } response = app.call(env) body = response[2][0] expect(body).to eq You have requested the path /some/url, using GET end # it end # context end # Application Odpowiedzi oczekujemy po wywołaniu metody call, do której przekazujemy konfigurację środowiskową env. Treść odpowiedzi znajduje się w response[2][0]. Przypadek testowy zakłada, że treścią odpowiedzi będzie You have requested the path /some/url, using GET. test_1_spec.rb Poprzedni przykład operował na żądaniu i odpowiedzi wprost. W tym przypadku wykorzystu- jemy metodę let, która pozwoli nam wprowadzić modularność tych wywołań. load application.rb describe Application do context get to /ruby/url do let(:app) { Application.new } let(:env) { { REQUEST_METHOD = GET , PATH_INFO = /some/url } } let(:response) { app.call(env) } let(:status) { response[0] } let(:body) { response[2][0] } it returns the status 200 do expect(status).to eq 200 end # it it returns the body do expect(body).to eq You have requested the path /some/url, using GET end # it end # context end # Application Poleć książkęKup książkę Rozdział 3. (cid:139) Zapewnienie jakości 131 Logika samego testu pozostaje niezmienna. Dochodzi jeden przypadek testowy, który weryfikuje kod HTTP odpowiedzi. Oczekujemy, że będzie to 200. Mamy zatem w sumie dwa przypad- ki testowe w zestawie. test_2_spec.rb Jeśli chcemy, aby kod był bardziej modularny, warto stosować metody pomocnicze z Rack:: Test::Methods. Nie musimy dzięki temu budować żądań i przetwarzać odpowiedzi w sposób całkowicie manualny. load application.rb require rack/test describe Application do include Rack::Test::Methods context get to /some/url do let(:app) { Application.new } it returns the status 200 do get /some/url expect(last_response.status).to eq 200 end # it it returns the body do get /some/url expect(last_response.body).to eq You have requested the path /some/url, using GET end # it end # context end # Application Inicjalizujemy app za pomocą Application.new. Same przypadki testowe wykorzystują get i asercje, które określają, co faktycznie chcemy sprawdzać. test_3_spec.rb Kolejnym przykładem jest jeszcze bardziej kompaktowa wersja, która również wykorzystuje Rack::Test::Methods i let. Wprowadza to jednak ułatwienie polegające na tym, że w kolejnych przypadkach testowych mamy już dostępną odpowiedź. load application.rb require rack/test describe Application do include Rack::Test::Methods context get to /some/url do let(:app) { Application.new } let(:response) { get /some/url } it { expect(response.status).to eq 200 } it { expect(response.body).to include /some/url, using GET } end # context end # Application Cały zestaw testowy operuje na tym samym żądaniu. Można zatem tę część uwspólnić. Jest to zdecydowane ułatwienie. Poleć książkęKup książkę 132 Programowanie w języku Ruby. Mikrousługi i konteneryzacja test_4_spec.rb Przykład ten różni się od poprzedniego wprowadzeniem konfiguracji RSpec przed samym zesta- wem testowym. Konfiguracja jest wspólna dla całego zestawu. Reszta pozostaje bez zmian. load application.rb require rack/test RSpec.configure do |config| config.include Rack::Test::Methods end # configure describe Application do context get to /some/url do let(:app) { Application.new } let(:response) { get /some/url } it { expect(response.status).to eq 200 } it { expect(response.body).to include /some/url, using GET } end # context end # Application test_5_spec.rb Rozwinięciem jednego z poprzednich przykładów jest poniższy, który różnicuje wykonywane żądania, raz na /some/url, innym razem na /. Oczekujemy kodu 200 dla pierwszego przy- padku i 405 dla drugiego. load application.rb require rack/test describe Application do let(:app) { Application.new } context get to /some/url do let(:response) { get /some/url } it { expect(response.status).to eq 200 } it { expect(response.body).to include /some/url, using GET } end # context context post to / do let(:response) { post / } it { expect(response.status).to eq 405 } it { expect(response.body).to eq Method not allowed: POST } end # context end # describe Jesteśmy dzięki temu w stanie weryfikować poprawność nie tylko treści odpowiedzi, ale także całego cyklu życia obiektów i ich statusów odzwierciedlonych właśnie w kodach HTTP. Sinatra Jednym z przykładów praktycznego zastosowania interfejsu Rack (poza Rails) jest platforma Sinatra. Bardziej jest to jednak DSL przeznaczony do tworzenia aplikacji serwerowych opartych na interfejsie Rack. W poniższym przykładzie stosujemy najprostszą z możliwych aplikacji. Poleć książkęKup książkę Rozdział 3. (cid:139) Zapewnienie jakości 133 hello_world.rb Aplikacja, na której podstawie wykonamy kilka zestawów testowych, znajduje się poniżej. Jest to bodaj najprostszy z możliwych przykładów. require sinatra get / do Hello World #{params[:name]} .strip end Załączamy bibliotekę (gem install sinatra) za pomocą require oraz definiujemy endpoint w postaci /, z którym należy się komunikować za pośrednictwem GET. Metoda get odpowiada tekstem Hello World i parametrem name z żądania. test_1_unit.rb Pierwszy przypadek testowy wykorzystuje bibliotekę test/unit. Zestaw testowy dziedziczy po klasie Test::Unit::TestCase. Załączamy metody pomocnicze znajdujące się w Rack::Test::Methods. ENV[ RACK_ENV ] = test require_relative hello_world require test/unit require rack/test class HelloWorldTest Test::Unit::TestCase include Rack::Test::Methods def app Sinatra::Application end # app def test_it_says_hello_world get / assert last_response.ok? assert_equal Hello World , last_response.body end # test_it_says_hello_world def test_it_says_hello_to_a_person get / , :name = Michal assert last_response.body.include?( Michal ) end # test_it_says_hello_to_a_person end # HelloWorldTest Zestaw testowy składa się z dwóch przypadków. Oba wykonują żądania typu GET na ścieżkę /. Pierwszy test sprawdza obecność tekstu Hello World w odpowiedzi, drugi natomiast przekazuje parametr name z tekstem, który sprawdzamy, czy znajduje się w odpowiedzi. test_2_spec.rb Do testowania również w tym wypadku możemy zastosować RSpec w połączeniu z pomocni- czymi metodami z rack/test. Przypadek testowy to żądanie na /, gdzie oczekujemy be_ok, czyli kodu 200. Pożądaną treścią odpowiedzi jest Hello World. ENV[ RACK_ENV ] = test require_relative hello_world # -
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

Programowanie w języku Ruby. Mikrousługi i konteneryzacja
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ą: