Okulary położone na biurku przed monitorem

Jak pisać testy end-to-end aplikacji React z frameworkiem Cypress

Przyszedł czas na zdobycie wierzchołka testerskiej piramidy. Zabierzemy się za testy e2e (end-to-end). W teorii to najlepszy sposób na upewnienie się, że aplikacja działa jak należy. Możliwość dokładnego odtworzenia zachowań użytkownika w środowisku przeglądarki jest nadzwyczaj obiecująca. Niestety, praktyka szybko obnaża ukryte słabości tego podejścia do testowania. Testy e2e są czasochłonne i niezwykle wrażliwe na zmiany w aplikacji. Czy to oznacza, że lepiej byłoby dać sobie z nimi spokój? Bynajmniej. Możemy mieć z nich nie lada użytek, wystarczy zachować umiar przy tworzeniu przypadków testowych i wyposażyć się w dobre narzędzia. Właśnie o jednym z takich narzędzi będzie mowa w dzisiejszym wpisie. Zobaczymy, jak sprawdza się w akcji zyskujący popularność framework cypress.io.

Disclaimer

W myśl zasady DRY: nie będę się zajmował wyjaśnianiem terminologii i omawianiem procesu planowania przypadków testowych. Szeroko omówiłem tę tematykę w poprzednich wpisach z serii Testowanie komponentów React. Jeżeli nie miałeś okazji ich przeczytać, zachęcam do nadrobienia zaległości.

New kid on the block

Cypress pozwala na testowanie każdej aplikacji uruchamianej w przeglądarce. Jest to rozwiązanie kompletne, zawiera wszystko, co potrzebne do pisania i uruchamiania testów.

Ponadto, mamy do dyspozycji następujące funkcjonalności ułatwiające pracę: snapshoty, hot reloading testów, mechanizm oczekiwania i kilkukrotnego wyszukiwania węzłów DOM (testy kodu asynchronicznego nigdy nie były tak łatwe!). To wszystko składa się w całkiem zgrabną całość.

Zdecydowałem się na wybór tego narzędzia zamiast popularniejszcych technologii bazujących na Selenium (np. Nightwatch.js) ze względu na niski próg wejścia i świetną dokumentację. No dobra, nie ma co ukrywać, nowinkowa chciwość również maczała w tym palce.

Jeżeli to Twoja pierwsza styczność z cypressem, to masz do dyspozycji poradnik w formie tekstowej oraz darmowy kurs video. Z pomocą tych materiałów poznasz sam framework oraz, co ważniejsze, wiele zasad poprawnego pisania testów e2e. Gorąco polecam.

Ja skupię się przede wszystkim na prezentacji podstaw korzystania z cypressa. Po przeczytaniu tego artykułu będziesz gotowy do samodzielnego testowania kluczowych elementów swojego projektu.

Tradycyjnie naszym królikiem doświadczalnym będzie projekt crypto-tracker (demo znajdziesz tutaj).

Zapraszamy cypressa na pokład

Bez niespodzianek zaczynamy od instalacji pakietu:

A następnie dodajemy do package.json nowy skrypt npm:

W przeciwieństwie do skryptów, z których korzystaliśmy przy pracy z Jest i Enzyme, ten nie spowoduje uruchomienia testów. Jego zadaniem jest utworzenie folderu /cypress zawierającego domyślną strukturę plików oraz uruchomienie graficznego panelu zarządzania frameworkiem.

Struktura plików

Przyjrzyjmy się folderom dodanym do projektu:

  • fixtures to odpowiednik __mocks__ znanego nam z Jest. To miejsce do przechowywania sztucznych danych wykorzystywanych jako atrapy w testach.
  • integration to folder, w którym będziemy przechowywali specyfikacje testów.
  • plugins to miejsce na pliki wtyczek. Ich wykorzystanie jest niezbędne do obsługi TypeScripta czy nowości z ES7+.
  • support zawiera plik index.js, wykonywany przed każdym testem. Przypomina trochę setupTests.js z Jest. Możemy w nim zadeklarować zmienne globalne udostępniane we wszystkich przypadkach testowych.

Centrum dowodzenia

Wszystkie przeprowadzane przez nas testy e2e zaczną i skończą się w graficznym panelu zarządzania.

Panel zarządzania Cypress

Jego obsługa jest dziecinnie prosta. Kliknięcie w nazwę testu powoduje uruchomienie go (suprise no. 1). Mamy również możliwość odpalenia wszystkich testów za pomocą „Run all specs” (suprise no. 2). Zaraz obok znajduje się dropdown, w którym wybieramy testowaną przeglądarkę. Niestety, wybór jest czysto symboliczny. Do dyspozycji mamy jedynie Chrome… To niewątpliwie największa wada tego narzędzia. Wsparcie dla pozostałych przeglądarek jest w drodze, postęp prac można śledzić w tym wątku.

Dla poszukiwaczy niesamowitych wrażeń, w zakładce „Runs” możecie nagrywać swoje testerskie wyczyny.

Proces pisania testów

Smoke test na rozgrzewkę

Sprawdzimy, czy crypto-tracker uruchamia się jak należy pod domyślnym adresem url serwera developerskiego.

W tym celu utworzymy nowy przypadek testowy pod ścieżką cypress/integration/app-init.spec.js.

Dzięki hot reloadingowi, test case od razu pojawi się w naszym panelu zarządzania, więc możemy go odpalić…

Komunikat błędu spowodowany brakiem uruchomienia serwera

Woops, falstart. Na szczęście komunikat błędu nie pozostawia wątpliwości co do natury naszego problemu. Zapomniałem o jednej istotnej sprawie. Przed rozpoczęciem testowania, wypadałoby uruchomić wspomniany serwer, którego URL wskazałem w cy.visit(). Wklepanie yarn start do terminala załatwia sprawę.

Smoke-test zakończony sukcesem

Jak widzisz, test wykonał się w okrojonej wersji Chrome. Po lewej widzisz panel testów, a po prawej podgląd aplikacji.

Właściwe przypadki testowe będą odwzorowaniem testów integracyjnych, które przygotowałem w ramach poprzedniego wpisu: Jak pisać testy integracyjne w React z Jest i Enzyme. crypto-tracker jest prostą aplikacją, co nie pozostawiło mi wiele pola do manewrów ;). W swoich projektach stosuj następującą heurystykę: testuj wyłącznie najistotniejsze scenariusze wykorzystania aplikacji i unikaj sprawdzania szczegółów podatnych na częste zmiany (np. stylowanie elementów).

Liczymy kryptowaluty

Dodajmy do testu pierwszą asercję. Wypadałoby sprawdzić, czy faktycznie udało się pobrać z serwera dane kryptowalut i wyświetlić je na ekranie.

Pierw wywołujemy metodę cy.server(), która pozwali nam obsługę komunikacji klient-serwer.

Kontrolę nad konkretnymi zapytaniami umożliwia nam metoda cy.route(). Za jej pomocą nadałem zapytaniu GET alias fetchCryptos.

Aliasy pozwalają na odwoływanie się do zapytania w kolejnych metodach. Ja skorzystałem z tej możliwości przy wywołaniu cy.wait().

Dzięki temu cypress zaczeka z asercją do momentu otrzymania odpowiedzi z serwera (lub upłynięcia czasu wskazanego w timeout).

Jak widzisz, zrezygnowałem z mockowania na rzecz wykonania prawdziwego zapytania do serwera.

Herezja? To zależy.

Testy e2e będą uruchamiane dużo rzadziej niż testy jednostkowe i integracyjne, w których dbaliśmy o mockowanie wszystkich zależności. Dzięki temu możemy zadać sobie pytanie: czy kosztem niewielkiej inwestycji czasu zyskamy pewność co do poprawnej integracji z serwerem?

W przypadku crypto-trackera, gdzie pobieram dane tylko raz, podczas inicjalizacji aplikacji, zdecydowałem się na zrezygnowanie z mockowania.

Oczywiście w aplikacjach, które wykonują tych zapytań więcej, mocki to nadal „way to go”. Mockowanie w cypress jest proste, szczegóły poznasz tutaj.

Jeżeli nie jesteś pewien, jak powinieneś podejść do tego tematu, skorzystaj z analizy plusów i minusów stubowania dostępnej tutaj.

Więcej na temat tego, jak radzić sobie z AJAXem znajdziesz w sekcji dokumentacji Network requests.

Asercje

Wróćmy do przypadku testowego. Jest jeszcze kilka rzeczy, które mogą Cię zastanawiać. Skąd taki selektor, za pomocą którego odwołałem się do węzłów DOM reprezentujących komponent Coin?

Samo dodanie selektora do kontenera komponentu było niezbędne. Cypress to nie Enzyme, nie był tworzony wyłącznie z myślą o Reactcie. Nie mamy możliwości bezpośredniego wyszukiwania komponentów, musimy radzić sobie z tym, co trafia do DOM.

Zamiast dodawać zbędne klasy CSS, skorzystałem z rozwiązania zaproponowanego w kolejnym jasnym punkcie dokumentacji cypressa czyli liście najlepszych praktyk.

Jak słusznie wskazują twórcy cypressa, klasy CSS mają to do siebie, że są podatne na zmiany. Szkoda, żeby refaktoryzacja czy zmiana metodyki była powodem do dodatkowej pracy przy testach. Lepiej wydzielić sobie oddzielny atrybut, który będzie zadeklarowany na wyłączność testów. Stąd właśnie data-cy=coin.

Jeżeli czytałeś mój wpis o testach jednostkowych, na pewno zauważyłeś, że oprócz selektora sama asercja wygląda trochę inaczej. Cypress wykorzystuje bibliotekę asercji Chai, a my do tej pory korzystaliśmy z matcherów Jest. Porównajmy je ze sobą na tym samym przykładzie:

Wystarczy chwilę przyjrzeć się tym dwóm linijkom, żeby stwierdzić, że różnice są tak naprawdę kosmetyczne.

Jedyne, czego nam trzeba, to zapoznać się z metodą should oraz listą dostępnych matcherów asercji.

Podróże w czasie z snapshotami

Zobaczymy w praktyce jeden z ciekawszych feature’ów cypressa czyli snapshoty. Dzięki nim możemy cofać się w czasie do kluczowych momentów wykonywanego przypadku testowego.

Po kliknięciu w (XHR) GET 200 możemy cofnąć się do momentu, w którym doszło do wywołania zapytania GET. Rzecz niesamowicie przydatna przy debugowaniu.

Nie trzeba wiele

Pozostałe trzy przypadki testowe zajęły się weryfikowaniem integracji paska wyszukiwania i listy Coinów. ich kod znajdziesz tutaj. Każdy z nich zamyka się w 10 linijkach kodu. Jedyne dodatkowe metody, z którymi musiałem się zapoznać to type() i clear().

Świetny dowód na to, że nie trzeba wiele zainwestować, żeby wyciągnąć wartość z testów e2e w Cypress.

Podsumowanie

Testy e2e z cypress okazały się dla mnie pozytywnym zaskoczeniem. Myślałem, że będzie znacznie więcej do ogarnięcia niż w przypadku Jest i Enzyme – wyszło na odwrót.

Jeżeli nie masz jeszcze doświadczenia w testowaniu, możesz śmiało zacząć od szczytu testerskiej piramidy. Cypress jest bardzo wyrozumiały dla początkujących. Ciężko o uczucie przytłoczenia, z którym możesz się zderzyć przy pierwszych kontaktach z Enzyme. Kiedy już nabierzesz rozpędu, łatwiej będzie zabrać się za testy jednostkowe i integracyjne.

To tyle w temacie testowania Reacta z mojej strony. Wielu czytelników głosowało za rozpoczęciem tej serii, dajcie znać w komentarzach, na ile jesteście usatysfakcjonowani z tego, co dla Was przygotowałem.

Co dalej?

Przy wyborze kolejnej tematyki wpisów sugerowałem się wynikami majowej ankiety.

Wyniki ankiety odnośnie tematyki wpisów. 1 miejsce: Testy, 2 miejsce: Wzorce, 3 miejsce: Redux

Podobnym zainteresowaniem co testowanie cieszyły się wzorce w React. To właśnie o nich będzie kolejna seria na blogu.

Na początek, zgodnie z tradycją, artykuł wprowadzający. Znajdziecie w nim zarys tematu i rozpiskę tematyki kolejnych wpisów. Jeżeli chciałbyś, abym omówił jakiś interesujący Cię wzorzec, śmiało dawaj znać w komentarzu.

Zapowiada się, że kolejna seria będzie naprawdę wartościowa. Dzięki wzorcom przeniesiemy nasz React game na kolejny poziom.

Podobał Ci się dzisiejszy artykuł? Udostępnij go w Twoich ulubionych mediach społecznościowych. Na pewno znajdzie się ktoś, dla kogo również będzie wartościowy.

Bądź na bieżąco. Wystarczy polubić fanpage AlgoSmart na fejsie, obserwować mój profil na Twitterze i regularnie odwiedzać portal Polski Front-end.

Zdjęcie tytułowe autorstwa: unsplash-logoKevin Ku

Piątka ludzi dająca sobie żółwika nad biurkiem z sprzętem elektronicznym

Jak pisać testy integracyjne komponentów React z Jest i Enzyme

Podczas testowania interfejsu użytkownika ograniczanie się sprawdzania odizolowanych od siebie komponentów nie zdaje egzaminu. Funkcjonalności dostarczane przez aplikację zawsze są wypadkową właściwej współpracy kilku jednostek w środowisku przeglądarki. Dopiero kiedy upewnisz się, że podsystemy są właściwie ze sobą zintegrowane, znacznie wzrośnie prawdopodobieństwo, że aplikacja spełni swoje zadanie w akcji. Dzisiaj przeprowadzę Cię przez podstawowy proces planowania i implementacji testów integracyjnych komponentów React w środowisku Jest i Enzyme.

Swoją drogą, istnieje liczna grupa programistów, z Kentem C. Doddsem na czele, która twierdzi, że pisanie dużej liczby testów jednostkowych jest mniej efektywne niż kilka solidnych testów integracyjnych. Efektem takiej filozofii jest zastąpienie klasycznej piramidy testowania takim oto osobliwym kształtem:
Model testowania z naciskiem na testy integracyjne autorstwa Kenta C. Doddsa

Czy taki model faktycznie lepiej sprawdzi się w każdym projekcie? Najzwyczajniej brak mi doświadczenia, żeby udzielić zdecydowanej odpowiedzi. Argumenty Kenta przemawiają do mnie na tyle, że na pewno sprawdzę skuteczność jego podejścia w praktyce.

Niezależnie od całej dyskusji, warto sprawnie radzić sobie zarówno z pisaniem testów jednostkowych, jak i integracyjnych. Ten wpis jest bezpośrednią kontynuacją poprzedniego: Jak pisać testy jednostkowe komponentów w React z Jest i Enzyme. Będę nawiązywał do pojęć, które wyjaśniłem ostatnio, więc jeżeli masz zaległości, zachęcam do ich nadrobienia :).

Jak zorganizować dobrą integrację?

Tak jak mieliśmy do czynienia z kontraktem pojedynczego komponentu, tak możemy wyznaczyć kontrakt podsystemu, który poddamy testom integracyjnym.

Jak wyznaczyć granice podsystemu? Na ogół jego korzeniem jest komponent kontenerowy. W przypadku tak małych projektów jak crypto-tracker, mamy tak naprawdę jeden podsystem, który składa się na całą aplikację. Naszym korzeniem jest komponent App (kod źródłowy znajdziesz tutaj). Dzięki przeprowadzonym wcześniej testom jednostkowym wiemy, że wypełnia swoje zadania w izolacji. Teraz pozostało sprawdzić, jak radzi sobie w zarządzaniu współpracą renderowanych przez niego dzieci: SearchBar i CoinList.

Większość informacji o tym, jak przebiega wspomniana kooperacja, dostarczy nam analiza kodu źródłowego oraz testów jednostkowych.

Umożliwianie współpracy pomiędzy rodzicem a jego dzieckiem to główna odpowiedzialność props, więc właśnie ten obiekt dostarczy nam dużo użytecznych informacji o tym co wymaga przetestowania. W testach jednostkowych mamy informacje co do tego, jakie propsy komponent otrzymuje od swoich przodków oraz co przekazuje swoim dzieciom. Jeżeli tych testów jednostkowych nie ma w naszym projekcie zbyt wiele, to najlepiej przejść przez proces wyznaczania kontraktu każdego komponentu wchodzącego w skład podsystemu. Łatwo będzie wychwycić punkty wspólne dla kilku komponentów, czyli naszą tytułową integrację.

Nie zaszkodzi również odpalić demo aplikacji oraz spojrzeć na nią z punktu widzenia użytkownika. To pozwoli nam nabrać większego dystansu do kodu, co pozytywnie wpłynie na implementację samych przypadków testowych. W testach integracyjnych warto odejść od wewnętrznej logiki komponentów na rzecz efektów końcowych ich pracy: czy (a nie jak) osiągnęliśmy oczekiwane rezultaty przy wyświetlaniu zawartości bądź obsłudze zdarzenia?

Zastosowanie powyższych wskazówek pozwoliło mi wypisać następujące wymagania co do crypto-trackera:

  • Aplikacja wyświetla animację ładowania, dopóki dane nie zostaną pobrane z serwera
  • Aplikacja wyświetla listę kryptowalut pobranych z serwera po ich załadowaniu
  • Aplikacja pozwala na przeszukiwanie listy za pomocą paska wyszukiwania

Okej, skoro już wiemy co musimy przetestować, to czas ubrudzić sobie ręce. Wracamy do Jest i Enzyme.

Dziel i rządź

Zanim zabierzemy się za implementacje przypadków testowych, rozdzielimy testy jednostkowe i integracyjne na osobne pliki. Taka separacja otworzy nam furtkę do uruchamiania wyłącznie wybranego rodzaju testów. Przy fixowaniu buga ograniczenie się do wielokrotnego wykonywania testów jednostkowych zaoszczędzi nam dużo cennego czasu. Często testy integracyjne zostawia się na koniec, gdy wszystko śmiga już w odizolowanym środowisku.

Zacznijmy od stworzenia folderu src/containers/tests, przenieśmy do niego App.test.js i zmieńmy jego nazwę na App.unit.test.js. Następnie utwórzmy plik przeznaczony do testów integracyjnych: App.int.test.js.

To nie wszystko, musimy jeszcze zmodyfikować npm scripts w package.json. Przyda nam się argument konsolowy Jest: --testPathPattern:

Jak widzisz, mamy również do dyspozycji skrypt test, który pozwoli na odpalenie wszystkich testów. Jesteśmy gotowi na każdą ewentualność.

Przed wyruszeniem w drogę należy… przygotować rusztowanie

Klasycznie czeka nas jeszcze jeden przystanek przed prawdziwym testerskim szaleństwem. Musimy przygotować funkcje pomocnicze, hooki i inne tego typu historie.

Tym razem będziemy korzystali z mount renderingu. Do sprawdzenia współpracy App i jego podopiecznych, musimy wyrenderować całe drzewo tego komponentu. Shallow rendering, wykorzystywany w testach jednostkowych, nie zdałby tutaj egzaminu, bo zwraca jedynie płytką wersję root komponentu.

Praca zespołowa pod lupą

Jesteśmy gotowi na implementację testów, które zaplanowaliśmy. Do dzieła.

  • Aplikacja wyświetla animacje ładowania, dopóki dane nie zostaną pobrane z serwera.

Tutaj wystarczą dwie asercje. Pierwsza sprawdzi, czy komponent obsługujący animację ładowania Spinner został wyrenderowany. Druga upewni nas, że lista nie wyświetla jakiegokolwiek Coina.

  • Aplikacja wyświetla listę kryptowalut pobranych z serwera po ich załadowaniu

Zacznijmy od upewnienia się, że Spinner znika po załadowaniu danych.

Mimo że kod testu sprawia wrażenie poprawnego, wysypuje się, twierdząc, że Spinner nadal jest wyświetlany przez CoinList.

Na początku byłem przekonany, że wynika to z błędu w logice samej aplikacji. W końcu od tego są testy. Jednak szybka randka z debuggerem (oprócz niesamowitych wspomnień) doprowadziła mnie do innych wniosków. Wszystko działa jak należy. Zabrałem się za debugowanie samych testów: stan appWrappera w momencie wykonywania asercji jasno wskazywał, że state.cryptos ma przypisane zmockowane dane, a isLoading jest ustawione na false.

Teraz największy hit, który wprowadził mnie w stan absolutnego zdezorientowania.

W ramach dalszego śledztwa postanowiłem porzucić wyszukane metody. Pozostała mi ostatnia deska ratunku, najpopularniejszy sposób na uzyskanie odpowiedzi na pytanie „co się tutaj od.. dzieje?” w ekosystemie JS. W ruch poszedł console.log().

Z perskeptywy czasu, nie wiem, czy to był dobry pomysł. Zgadnijcie, co zwrócił console.log(coinListWrapper.text()) – tekst wygenerowany na podstawie zmockowanych kryptowalut i ani śladu po Spinnerze.

Zrozumiałem, co się wyprawia (częściowo) dopiero po przeczytaniu tego wątku na GitHubie.

W skrócie: wrappery dzieci są „odcięte” od rodzica. Zmiany w rodzicu nie są automatycznie odzwierciedlane w wrapperze dziecka. coinListWrapper to referencja do wrappera sprzed wywołania appWrapper.update().

Byłoby to całkiem sensowne, tylko skąd taki wynik wywołania w coinListWrapper.text()>, który jednak oddaje aktualny stan rodzica. Tego nie było dane mi pojąć. Jeżeli znasz rozwiązanie tej zagadki, koniecznie daj znać w komentarzach :).

Aby uniknąć całego tego zamieszania, musimy inaczej zabrać się za uzyskiwanie dostępu do CoinList. Jak już ustaliliśmy, w asercji interesuje nas aktualny stan wrappera, a nie studiowanie zaburzeń czasoprzestrzeni. Stąd zamiast zmiennej, przyda nam się funkcja, która będzie zwracała świeżo odszukany wrapper.

Od tej pory odwołuję się do CoinList za pomocą wywołań getCoinListWrapper().

Okej, teraz jest zielono, kryzys zażegnany.

Przejdźmy do sprawdzenia, czy liczebność Coinów pokrywa się z liczebnością zmockowanych danych.

Kolejny punkt na naszej liście odhaczony.

  • Aplikacja pozwala na przeszukiwanie listy za pomocą paska wyszukiwania

Powyższe wymaganie rozbijemy na kilka przypadków testowych.

  • Aplikacja dopasowuje do frazy wyszukiwania tylko jedną walutę

  • Aplikacja dopasowuje do frazy wyszukiwania kilka walut

  • Aplikacja wyświetla wiadomość informującą o braku wyników przy braku dopasowań

  • Aplikacja wyświetla wszystkie dostepne dane po usunięciu frazy wyszukiwania

I to by było na tyle. Cały kod testów integracyjnych znajdziecie tutaj.

Podsumowanie

Gdyby nie ta zagadka rodem z Sherlocka Holmesa, to testy integracyjne poszłyby naprawdę gładko. Umiejętności, które zdobyliśmy przy pisaniu testów jednostkowych oraz znajomość API Enzyme, mocno zaprocentowało przy testach integracyjnych.

Najważniejsze sprawy, o których powinieneś pamiętać:

  • Testy integracyjne nie muszą być liczne, aby dostarczyć dużo wartości
  • Pisz funkcje pomocnicze odszukujące wrappery dzieci, zaoszczędzisz sobie nieprzyjemnych niespodzianek

Przed nami ostatni przystanek na testerskiej wyprawie: testy end-to-end. Porzucamy Enzyme i Jest na rzecz cypress. Zmieni się forma i narzędzie, ale wszystko sprowadzi się do odtworzenia w przeglądarce scenariusza zbudowanego na podstawie przeprowadzonych dzisiaj testów integracyjnych.

Podobał Ci się dzisiejszy artykuł? Udostępnij go w Twoich ulubionych mediach społecznościowych. Może znajdzie się ktoś, dla kogo również będzie wartościowy.

Bądź na bieżąco. Wystarczy polubić fanpage AlgoSmart na fejsie, obserwować mój profil na Twitterze i regularnie odwiedzać portal Polski Front-end.

Zdjęcie tytułowe autorstwa: unsplash-logorawpixel

Jak pisać testy jednostkowe komponentów React z Jest i Enzyme

Jak to bywa z początkami, są trudne. Przypomniałem sobie o tym podczas pisania pierwszych testów jednostkowych w React. Dręczyło mnie wiele pytań: co powinienem testować? A co zostawić w spokoju? Czy moje testy zbytnio skupiają się na wewnętrznej mechanice komponentu? A może przez brak doświadczenia pomijam istotne elementy
interfejsu? Takie wątpliwości w połączeniu z rozbudowanym API Jest i Enzyme to idealna recepta na sparaliżowanie nawet najśmielszego adepta testowania. W tym artykule zaprezentuję metodę, która pozwoliła przełamać testerską blokadę i ruszyć z praktyką. (więcej…)

Lista materiałów, których potrzebujesz do skutecznej nauki Reacta

Stawiasz pierwsze kroki w ekosystemie Reacta? A może początki masz już za sobą, ale część zagadnień jest dla Ciebie problematyczna? Tak się składa, że w czasie wolnym od tworzenia kolejnych komponentów, udało mi się odszukać wiele wartościowych materiałów. Pozwolą Ci na skuteczną naukę, niezależnie od dotychczasowego poziomu umiejętności.

(więcej…)

Przejście otoczone stosem książek

Co musisz wiedzieć, żeby zacząć testowanie komponentów React?

Wprowadzenie testów to najlepszy sposób na podniesienie jakości i niezawodności tworzonego przez Ciebie oprogramowania. Jak pokazała przeprowadzona przeze mnie ankieta, czytelnicy bloga świetnie zdają sobie sprawę. Mimo najlepszych chęci, pierwsze kroki w świecie testowania mogą być przytłaczające. Terminologia, konfiguracja środowiska, o samym pisaniu testów nie mówiąc. Tym razem udowadniam, że to żadne rocket science. Po przeczytaniu tego wpisu będziesz mógł zabrać się za testowanie komponentów React.

(więcej…)

Śledzenie kursów kryptowalut czyli AJAX w React – PPwRJS #10

Zbliżamy się do zakończenia pracy nad trackerem kryptowalut. Jedyne, czego brakuje do zrealizowania założeń, to wprowadzenie aktualnych danych o kursach z zewnętrznego serwera. Do realizacji tego celu posłuży nam AJAX oraz API CoinMarketCap. React jest biblioteką skoncentrowana na View, stąd na próżno szukać wbudowanego rozwiązania do obsługi asynchronicznego JSa. Otwiera to przed nami szereg możliwości, co ma tyle samo wad (co wybrać?!), co zalet (to co Ci odpowiada! ;)). Zacznę od omówienia dwóch najpopularniejszych sposobów na AJAX w React czyli natywnego fetch i biblioteki axios. Następnie przejdziemy do dopieszczania trackera kryptowalut świeżymi danymi wprost z serwerownii.

(więcej…)

Zatłoczone skrzyżowanie w Tokio

Cykl życia komponentu – PPwRJS #9

W czym każdy z nas, programistów, przypomina komponent React? Człowiek przechodzi przez dzieciństwo, dojrzałość i starość. Tak się składa, że bardzo podobny cykl życia charakteryzuje komponenty. Możemy w ich przypadku wydzielić okresy Mounting (dzieciństwo), Updating (dojrzałość) i Unmounting (starość). Taki systematyczny podział, wspólny dla każdego przedstawiciela swojego rodzaju, pozwala podzielić obowiązki, którym każda jednostka będzie musiała sprostać w poszczególnych okresach swojego żywota. Zdecydowanie łatwiej poradzić sobie w skomplikowanym świecie z informacją, że nauka chodzenia (w przypadku ludzi) czy inicjalizacja stanu (w przypadku komponentów) powinna być jedną z pierwszych spraw, którym poświęcimy uwagę. W internecie roi się od rad odnośnie do tego, jak radzić sobie z cyklem życia homo sapiens. Ja ograniczę się do złotych rad zapewniających właściwy rozwój Twoich komponentów.

(więcej…)

Odwrócona dziewczyna w żółtej bluzie, z różowym plecakiem, siedząca na murku

Stylowanie w React – PPwRJS #8

React wywrócił świat front-endu do góry nogami. Pierw za sprawą JSX doszło do zatarcia granic pomiędzy warstwą struktury (HTML), a warstwą zachowania (JS). Nie trzeba było długo czekać, aby ten trend rozprzestrzenił się na warstwę prezentacji. Zamieszanie na linii React-CSS trwa w najlepsze od trzech lat. Najpopularniejsze sposoby na stylowanie aplikacji w ekosystemie Reacta opisałem na przykładzie trackera kryptowalut.

(więcej…)

Dłoń wyjmująca plik płyt winylowych z pudełka.

Wyszukiwarka kryptowalut (część 2): Obsługa zdarzeń

Przyszedł czas na zbudowanie najciekawszego komponentu w całym trackerze kryptowalut. Jest nim SearchBar. Całe działanie tego komponentu opiera się o obsługę zdarzeń. Z wpisu dowiesz się, jakie są różnice pomiędzy zdarzeniami w React i DOM API. Dużo uwagi poświęciłem wiązaniu this, które może sprawić Ci niemiłą niespodziankę przy przekazywaniu referencji do funkcji w props. Najlepsze zostawiłem na koniec, w ostatniej części wpisu implementujemy algorytm wyszukiwarki.

(więcej…)

Przecinające się mosty widziane z lotu ptaka

Wyszukiwarka kryptowalut (część 1): Wyświetlanie warunkowe

Marny użytek z trackera kryptowalut bez możliwości przeszukiwania jego zawartości. Czas zrobić z tym porządek i tchnąć w aplikację odrobinę życia. Zbudujemy komponent wyszukiwarki. To świetna okazja, żeby rzucić okiem na wyświetlanie warunkowe oraz obsługę zdarzeń. Są to tematy znane każdemu programiście JS, przekonamy się jak prezentują się w świecie Reacta.

(więcej…)