Testowanie Twojej natywnej aplikacji React (część 1)

(21 grudnia 2020 r.)

Wprowadzenie

Większość programistów uważa, że ​​testowanie jest nudne i trudne do napisania, ale wiesz co? Potrzeba wielkich umiejętności i doświadczenia, aby wiedzieć, jak pisać znaczące i możliwe do utrzymania testy. Wiedza, którą zdobędziesz podczas nauki testowania kodu, zmieni również sposób pisania kodu w programowaniu. Ten artykuł powinien pomóc Ci rozpocząć przygodę z testowaniem.

Wskazówki dotyczące lepszego testowania

Oto niektóre wskazówki, których nauczyłem się po zbadaniu, jak inni programiści testują swój kod. Postępowanie zgodnie z tymi wskazówkami ułatwiło mi pisanie i utrzymywanie testów w całym kodzie.

1. Nie testuj implementacji swojego kodu

Aby zrozumieć, dlaczego jest to ważne, przejdźmy do scenariusza. Załóżmy, że napisałeś funkcję, która jako dane wejściowe przyjmuje n i wyświetla wynik dodania pierwszego elementu n liczby.

Załóżmy, że testujesz getSumOfFirstN dla n=2, stwierdzając, że add nazywa się 2 times z argumentami odpowiednio (0, 2) i (2, 1) oraz wynikiem getSumOfFirstN to 3.

Później dowiadujesz się, że istnieje lepszy sposób na znalezienie sumy pierwszych n numery i przepisz powyższy kod.

Twój test zacznie się kończyć, ponieważ nie dzwonisz już pod numer add

To był prosty przykład, a to y może wydawać się sprzeczne z intuicją, ale widziałem wielu programistów przeprowadzających dokładnie tego rodzaju testy, w których błąd nie jest tak łatwy do zauważenia.

2. Nie pozwól, aby testy stały się kolejnym długiem technicznym

Testowanie jest ważne, ale musisz także dostarczyć kod odpowiednim interesariuszom na czas. Jeśli za każdym razem, gdy napiszesz nową funkcję lub zmodyfikujesz istniejącą, zepsuje to stare przypadki testowe lub w końcu spędzisz znaczną ilość przydzielonego czasu na naprawie starych przypadków testowych, zamiast budować wymagane funkcje, ostatecznie skończysz usuwając wszystkie stare testy i ryzykujesz, że projekt zakończy się niepowodzeniem w produkcji.

Postępowanie zgodnie z tymi wskazówkami powinno pomóc w zapewnieniu, że testy są łatwe do naprawienia lub w ogóle nie psują się, gdy zmieni się baza kodu.

3. Podczas testowania interfejsu użytkownika pisz testy w sposób symulujący rzeczywiste zachowanie użytkownika.

Załóżmy, że testujesz czy ten przycisk został wyrenderowany i działa zgodnie z oczekiwaniami, czy nie, a następnie pomyśl najpierw, w jaki sposób użytkownik znalazłby ten przycisk i jak z nim wchodził. Mam nadzieję, że zobaczą tekst „Prześlij”, a następnie go naciśną i tak właśnie będziemy symulować. W naszym przypadku testowym najpierw wyszukamy tekst „Prześlij”, a następnie zasymulujemy zdarzenie „onPress”, a następnie stwierdzimy, co miało zrobić.

W niektórych przypadkach może to nie być łatwo jednoznacznie zidentyfikować komponent, na który chcesz kierować reklamy. W takim przypadku możesz użyć właściwości testID, ale pamiętaj, że nie będziesz symulować pełnego zachowania użytkownika, jeśli użyjesz testID, ponieważ użytkownicy nie kierują reklam na komponenty na podstawie ich testID.

Dlaczego jest to ważne? Dlaczego podczas testowania interfejsu użytkownika musimy próbować symulować zachowanie użytkownika w jak największym stopniu? Dzieje się tak, ponieważ w końcu będzie to człowiek, który będzie wchodził w interakcję z interfejsem użytkownika, a nie komputer, i jeśli zobaczy, że na przycisku jest renderowane słowo „Hello”, a nie „Submit”, przypadek testowy powinien zakończyć się niepowodzeniem, ponieważ to jest coś, co może zniechęcić użytkownika końcowego.

4. Czyste funkcje są łatwiejsze do przetestowania niż funkcje nieczyste

Czyste funkcje to funkcje, które zawsze dają ten sam wynik dla odpowiedniego wejścia, tj. Jeśli czysta funkcja wypompowuje 2 dla 1 to zawsze tak by się działo, podczas gdy nieczyste funkcje mogą wypompowywać 2 przy pierwszym wywołaniu, a następnie wypompowywać 5 podczas drugiego połączenia.

Jest to przydatne, o czym należy pamiętać podczas pisania kodu. Zanieczyszczone funkcje mogą stać się łatwiejsze do przetestowania, jeśli moduł wprowadzający „nieczystość” w takich funkcjach jest mockowalny.

5.Używaj uchwytów jako danych wejściowych i asercji w testach

Załóżmy, że masz obiekt typu pracownik i masz na nim różne funkcje, takie jak funkcja do zapisywania wielkimi literami name, funkcja sprawdzająca, czy pracownik jest dorosły, czy nie, itp.

Teraz przypuśćmy, że bierzesz ten obiekt jako dane wejściowe we wszystkich przypadkach testowych.

To są Twoje fikcyjne dane lub Twoje „urządzenie”. W pierwszym przypadku testowym, który sprawdza, czy funkcja zapisująca nazwę wielką literą działa zgodnie z oczekiwaniami, czy nie, zapewniasz, że jej dane wyjściowe są równe { ...employee, name: employee.name.toUpperCase() }, a w drugim przypadku testowym zapewniasz czy funkcja wyświetla employee.age >= 18, czy nie, i tak dalej.

Być może zastanawiasz się, jaką korzyść daje nam używanie urządzeń w taki sposób? Odpowiedź jest taka, że ​​pisząc testy w ten sposób, ułatwiasz sobie szybkie naprawianie testów w przyszłości.

Np. A gdybyśmy chcieli dodać kolejną właściwość maritalStatus w obiekcie pracownika, ponieważ teraz wszyscy nasi pracownicy są zobowiązani do ujawnienia swojego stanu cywilnego. Jeśli w naszym pierwszym przypadku testowym ustaliliśmy, że wynik jest równy { name: "KARTIK", age: 25, sex: "Male", children: 0 } zamiast { ...employee, name: employee.name.toUpperCase() }, nasz przypadek testowy się zepsuje. Zepsuje się również, jeśli zmienimy wartość name na coś innego. Innymi słowy, nasz przypadek testowy nie byłby w ogóle elastyczny i dlatego miałby większe szanse na przerwanie z powodu niepowiązanych zmian w bazie kodu.

6. Napisz testy jednostkowe dla komponentów i funkcji narzędziowych

To są części twojego kodu, które będą używane przez wiele modułów. W związku z tym należy je przetestować pod kątem wszystkich możliwych wejść / przypadków brzegowych, ponieważ nie wiesz, w jaki sposób inne moduły będą używać tych funkcji / komponentów. Dlatego nie powinny one mieć żadnego nieoczekiwanego zachowania.

7. Napisz testy integracji dla ekranów

Trudno jest napisać testy jednostkowe dla ekranów, ponieważ zwykle zależą one od dużej liczby komponentów i bibliotek innych firm, takich jak sklep Redux. Tak więc, aby napisać testy jednostkowe dla ekranów, najpierw będziesz musiał mockować wszystkie te zależności, co jest dużo pracy. Dlatego w tym przypadku lepiej jest pisać testy integracyjne.

7. Pisanie testów E2E do testowania kodu natywnego

Kod natywny nie działa w środowisku żart. Aby to przetestować, będziesz musiał użyć biblioteki takiej jak Detox.

8. Zawsze wykonuj testy migawek dla ekranów i komponentów

Jeśli dokonasz zmiany stylu w komponencie, który jest używany przez wiele innych ekranów / komponentów, testy migawek dla tych ekranów zakończą się niepowodzeniem, dopóki nie zaktualizujesz migawek. Pomoże Ci to zrozumieć, na które inne moduły wpłynęła wprowadzona zmiana. Jeśli pracujesz w zespole, to naprawdę pomaga recenzentowi podczas przeglądów PR zrozumieć, na jakie moduły wpłynęła konkretna zmiana dokonana w komponencie, ponieważ zmiany w migawkach tych modułów są odzwierciedlone w twoim PR.

Podsumowanie

Mam nadzieję, że ten artykuł okazał się pomocny i jeśli jesteś zdezorientowany tym, co właśnie przeczytałeś, nie martw się. Drugą częścią tej serii będzie samouczek dotyczący konfigurowania środowiska testowego w React Native z przykładami kodu ekranów testowych, komponentów i funkcji, zgodnie z wytycznymi, które wyznaczyliśmy w tej pierwszej części.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *