Sanitarna inspekcija
Dakle, restoran je spreman. Imamo kuvare koji delegiraju posao (launch), glavnog šefa koji upravlja životnim vekom kuhinje (CoroutineScope) i švedski sto koji je uvek pun (Flow).
Na papiru, sve izgleda kao remek-delo. Ali evo surove realnosti: asinhroni kod je užasno težak za dokazivanje.
U pravoj kuhinji, ako recept kaže “krčkati 4 sata”, inspektor neće sedeti tamo 240 minuta sa štopericom.
Poludeo bi. U svetu programiranja imamo isti problem.
Ne možemo da priuštimo da nam CI/CD pipeline stoji u mestu 5 sekundi samo zato što je neki delay(5000) zalutao u kod.
Još gori su oni flaky testovi što prođu kod vas na mašini, a padnu na serveru jer je mreža štucnula na milisekundu.
Da bismo prošli inspekciju, a da ne izgubimo razum, moramo da naučimo kako da iskrivimo vreme.
Tajni sastojak: runTest
Staromodno testiranje korutina je uključivalo runBlocking i ručno pozivanje Thread.sleep().
Iskreno? Nemojte to raditi. Sporo je i nepouzdano. Umesto toga, koristimo biblioteku kotlinx-coroutines-test.
Glavna zvezda ovde je runTest. Zamislite ga kao simulaciju kuhinje gde sat kuca samo onako kako vi kažete.
Ako vaš kod udari u delay(10_000), runTest zapravo ne čeka. On jednostavno teleportuje virtuelni sat 10 sekundi unapred, trenutno.
1. Simulacija krčkanja (suspend funkcije)
Recimo da preuzimamo podatke o korisniku. Potrebna je sekunda da se simulira mrežni poziv.
Kod:
| |
Test:
Koristimo runTest da preskočimo dosadan deo.
| |
2. Praćenje table sa statusom (StateFlow)
Testiranje ViewModel-a je mesto gde se većina ljudi saplete. Želite da vidite kako se UI stanje menja: Idle -> Loading -> Success.
Jedan iskren savet: Ako hardkodujete Dispatchers.IO unutar svojih klasa, bićete u problemu. Uvek ubrizgavajte (inject) dispečere.
To je jedini način da ih u testovima zamenite nečim što možete da kontrolišete.
| |
U testu koristimo advanceUntilIdle(). To je u suštini fast-forward dugme koje izvršava sve što čeka u redu.
| |
3. Provera švedskog stola (Flow)
Kako testirati strim? Ako naš Flow izbaci tri jela, moramo biti sigurni da stižu po redu i da nijedno nije nestalo.
Najlakši trik? Pretvorite Flow u List. runTest je dovoljno pametan da sačeka da se strim završi (virtuelno) pre nego što uradite asertaciju.
| |
Finale serijala: Kuhinja je otvorena
Testiranje nije birokratija. To je način da ne dobijete poziv u 3 ujutru jer se aplikacija srušila. Koristeći runTest, prelazimo sa “valjda ovo radi” na “imam dokaz da radi.”
U ovom serijalu smo prešli ozbiljan put:
- Osnove: Prestali smo da blokiramo tredove.
- Menadžment: Koristili smo Scope-ove da sprečimo curenje memorije.
- Strimovi: Ovladali smo Flow-om za kompleksne podatke.
- Otpornost: Preživeli smo gužvu uz backpressure.
- Verifikacija: Naučili smo da krivimo vreme radi testova.
Kuhinja je sada vaša. Napravite nešto brzo i stabilno.
Srećno kodiranje!