Android Unit Testy

Android Unit Testy

Naucz się pisać testy na Androidzie raz, a dobrze.

…………………………………………………………………………………………………………….

Pytanie nie brzmi, czy powinno się testować kodzik.

Prawdziwe pytanie to – czy możesz sobie pozwolić na brak testów?

Co ogarnięcie unit testów da Tobie?

  • lepszą pozycję na rynku pracy (zobacz w ilu ogłoszeniach wspominają o jUnit lub Mockito)
  • zrozumienie biznesu stojącego za aplikacją
  • mniej wyrwanych włosów z głowy podczas debugowania
  • lepszą produktywność: nie zrobisz tyle błędów typu “to miało być w ifie, a nie w elsie”
  • szybszy development: zamiast za każdym razem odpalać apkę na emulatorze, odpalasz jedynie test

Są zasadniczo dwie opcje finansowania tego programu:

1. Wykorzystujesz budżet szkoleniowy w firmy w której pracujesz na ten kurs (profit)
2. Inwestujesz samodzielnie w ten kurs i dzięki temu zdobywasz lepszą pracę w firmie która budżet szkoleniowy posiada (również profit)

* a jeśli zajmujesz się freelancingiem, to już pewnie dobrze wiesz, że inwestycja w edukacje się dobrze zwraca  

Co pisanie testów da Twojemu projektowi i firmie?

(tym uzasadnisz udział w programie w ramach firmowego budżetu szkoleniowego, serio!)

  • wydajniejszą pracę nad nowymi funkcjonalnościami
  • bezpieczniejszy refaktor (nawet w legacy)
  • większą pewność w deploymencie (nawet w piątki!!!!)
  • wzrost kultury jakości w zespole i w firmie
  • lepszą architekturę aplikacji i design kodziku – pisanie testów promuje clean architecture
  • lepszą produktywność: czytelne testy pozwalają efektywniej współpracować nad kodem w zespole

 Jeśli Twój manager lub szalony product owner upadł na głowę i twierdzi, że „my nie mamy czasu na testy”, to możesz mu przedstawić poniższe fakty…

„PM mówi, że nie mamy czasu na testy”

  • zmień project managera albo firmę 
  • koszt napisania testów pod każdego taska: +10% czasu na development
  • koszt naprawy głupiego błędu, bo nie było wcześniej czasu na testy: +99999% czasu na naprawy
  • unit testy  -> szybszy rozwój produktu
  • unit testy -> bezpieczniejsze i szybsze wdrożenia

Scenariusz  A: nie masz testów w projekcie:

  • bierzesz taska z backlogu 
  • piszesz implementację (3h)
  • pushujesz do mastera
  • deploy do Play Store (zajmuje 3 dni)
  • część userów ma CRASH bo JSON jest źle parsowany
  • robisz rollback do poprzedniej wersji (kolejne 3 dni)
  • szukasz błędu i naprawiasz buga (1-2 dni)
  • wypuszczasz nową wersję (3 dni)

Całość: ~8 dni roboczych na wdrożenie poprawek

Scenariusz  B: piszesz testy, którym możesz zaufać:

  • bierzesz taska z backlogu 
  • piszesz implementację (3h)
  • tworzysz testy (1h)
  • znajdujesz błąd w formatowaniu JSONa 
  • poprawiasz implementację (20min)
  • pushujesz do mastera
  • deploy do Play Store
  • userzy są szczęśliwi

Napisanie kodu trwa zajmie Ci troszkę więcej czasu, ale znacząco minimalizujesz ryzyko wystąpienia głupiego błędu na produkcji

Zgadza się. Task zajmie troszkę więcej czasu.
Za to oszczędzisz sporo nerwów jakby coś miało pójść źle (a zgodnie z prawem Murphy’ego, na pewno pójdzie).

Co się bardziej opłaca? Matematykę zostawiam Tobie.

To był jedyny test w projekcie 

Po co testować, skoro domyślasz się, że powinno działać?

Pozwól, że opowiem Ci pewną historię. Dołączyłem kiedyś do projektu w jednej z krakowskich agencji. Nie było w projekcie w nim ani grama testów. Aplikacja działała już od jakiegoś czasu na produkcji.

Spytasz się mnie, czy zespół palił się do refaktorowania apki i wdrażania nowych funkcjonalności? Otóż nie. Nikt nie miał odwagi żeby coś zmienić, bo z każdą istotniejszą zmianą trzeba było przebudowywać aplikację, wgrywać na telefon i ręcznie klikać przeróżne scenariusze.  

Nowe ficzerki były estymowane na ogromne ilości story pointów, a niektóre poważne bugi dostawały labelkę „won’t do”. Cóż, Jira wszystko przyjmie. Psychika deweloperów niekoniecznie. Przecież tak się nie da pracować. 

Jako że byłem „nowy” w zespole i nie cały ten marazm mnie jeszcze nie dotyczył, postanowiłem coś z tym zrobić. Na początek napisałem kilka testów do najprostszych przypadków i dodałem podstawowy flow CI/CD. Tyle wystarczyło, by zespół przekonał się do pracy w ten sposób, a testów powstawało coraz więcej.

Członkowie zespołu nie bali się już refaktoru. Ficzerki dało się estymować bardziej realistycznie.   A wiesz co jest w tym najlepsze? W żadnym momencie nie zastanawialiśmy się nad tym czy w naszych estymatach uwzględniać czas potrzebny na napisanie testów, lub czy product owner „da przyzwolenie” na takie prace.

Unit testy stały się integralnym elementem dowożenia tasków i całego procesu dostarczania oprogramowania. Tak trzeba żyć.

Co mamy w programie?

Lekcja po lekcji, moduł po module zagłębiasz się w kolejne tajniki testów. 

Każdy koncept zrozumiesz i dzięki temu go wdrożysz.

Konfiguracja środowiska

Omówimy pokrótce wszelkie narzędzia z których będziemy korzystać.

Poznasz tutaj wzorce given-when-then i dowiesz się czy warto używać adnotacji typu @BeforeClass. Poznasz również sposoby na odpalanie testów jUnit4 i jUnit5 w obrębie jednego projektu.

Asercje bez tajemnic

Zobaczysz czym tak naprawdę są asercje, odkryjesz potencjał drzemiący w bibliotekach standardowych jUnit5, zapoznasz się z zewnętrznymi libkami do asercji i wreszcie zbudujesz własne, reużywalne metody do asercji.

Test Doubles: stuby i fake

Poznasz konkretne sposoby na tworzenie stubów z Mockito, MockK, Mockito-Kotlin, a także bez użycia frameworków. Nauczysz się jak wydajnie wykorzystywać te narzędzia, żeby mieć porządek w testach. 

Test Doubles: mocki i weryfikacje

Jak sprawdzić side effecty? Jak używać matcherów? Jak do tego wszystkiego ma się Mockito? Na te i inne pytania znajdziesz odpowiedzi w tym module. 

Testowanie use case’ów

Mając już niezbędne podstawy ze struktury testów, asercji i mockowania, stworzysz pełen test dla rzeczywistego use case’u. Omówię tutaj kilka podejść do testowania takich komponentów.

Kotlin Coroutines w testach

Coroutines stają się standardem w Androidzie. W tym module poznasz metody testowania kodu opartego o Kotlin Coroutines , także z wykorzystaniem zewnętrznych bibliotek.

RxJava

RxJava była złotym standardem zanim korutyny na dobre przejęły serca i dusze Android devów. W tych lekcjach poznasz sprawdzone sposoby na ujarzmienie kodu reaktywnego. 

ViewModele!

Poznasz filozofię stojącą za testowaniem androidowych ViewModeli. Zobaczysz jak zaplanować testy z tym komponentem i co tak naprawdę powinno się przetestować. Nauczysz się również budować testy klas wykorzystujących LiveData i StateFlow

Model-View-Cokolwiek

Testowanie przez weryfikację metod? Albo asercje na stanie widoku? W tym module poznasz konkretne i sprawdzone sposoby na testowanie kodu zbudowanego ze wzorcami Model-View-Presenter, Model-View-Intent, a także Model-View-Cokolwiek (zobaczysz, że filozofia testowania nie różni się aż tak bardzo między różnymi implementacjami MVC)

Dirty Architecture

Prześledzimy słabo zaprojektowaną apkę, oczywiście taką bez żadnych sensownych testów. Pokażę jak w takich sytuacjach podejść do tworzenia testów i co możemy zrobić, żeby podnieść jakość w projekcie.

Moduł bonusowy – różne smaczki

W module bonusowym poznasz kilka smaczków i hacków na niestandardowe rzeczy. Pokaże tutaj jak zamockować loggery, jak radzić sobie z datami i czasem w kodzie, a także jak ogarnąć testy dla klas wykorzystujących Context.

Jarosław Michalik

NIP 6252464759
REGON 369959840