Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 1 - Úvod do testování softwaru v Kotlin

Vítejte, všichni pokročilí programátoři, u první lekce tutoriálu testování aplikací v Kotlin. Kurz je tvořený zejména na základě praktických zkušeností s projekty většího rozsahu. Naučíme se v něm postupně pokrývat kód různými typy testů a tím vytvářet spolehlivé a kvalitní aplikace. Nabyté znalosti se hodí k získání velmi dobré pracovní pozice i při tvorbě vlastních aplikací, které je možné poté pohodlně rozšiřovat bez obav, že změny kódu rozbijí původní funkčnost.

Minimální požadavky kurzu

Kurz předpokládá dobrou znalost jazyka Kotlin. Zejména pak:

Testování je vlastně takovým čtvrtým bodem osnovy výše. Všechny čtyři body by měl každý dobrý programátor znát, aby jeho práce za něco stála.

Kdy testovat

Testování se určitě řadí mezi dobré praktiky vývoje softwaru, tzv. best practices. Jako další uveďme objektové programování či použití vícevrstvé architektury. Některé praktiky bychom měli dodržovat opravdu ortodoxně. Pro psaní neobjektového kódu totiž existuje opravdu jediný důvod a tím je neznalost programátora. Zapouzdřování logiky aplikace do objektů a vrstev znamená pro zkušeného vývojáře minimální zdržení a minimalizuje náklady na rozšiřování a udržování nepřehledné a nerozvrstvené aplikace.

Na druhou stranu, některé praktiky vývoje softwaru bychom naopak neměli dodržovat až takto extrémně. Mezi ně patří právě testování. Hned na úvod zmíním, že testování je velmi důležité a v určité části projektu dokonce nepostradatelné. V prvních fázích projektu, a to zejména u start-upů, kdy se hraje na čas a funkčnosti aplikace se často mění, není vůbec dobrý nápad testy psát.

V tomto případě je třeba co nejdříve aplikaci spustit. Testy by se navíc musely často měnit, zbytečně by zdržovaly a mohly by poškodit rozjezd.

Některým z vás nyní možná bleskla hlavou teorie okolo TDD (Test-Driven Development), která se naopak opírá o neustálé testování úplně všeho. Jako teoretický koncept zní sice hezky, ale v praxi by měl dobrý programátor dokázat myslet i trochu jako manažer a nakládat rozumně s vývojovým rozpočtem.

Pokud máme naopak aplikaci, která má již několik stabilních funkcí a chceme ji dále rozšiřovat, bez testů se neobejdeme.

Testy tedy pokrýváme takové aplikace, které již dosáhly určité stability.

Rozšiřování softwaru

Jakékoli kvalitní rozšiřování softwaru vždy znamená změnu stávajících funkčností. Do jisté míry může kvalitní analýza a návrh připravit půdu pro budoucí úpravy. I když se však budeme hodně snažit, trh se mění nekontrolovaně a úspěšnou aplikaci bude třeba upravovat ze všech stran. Pokud bychom stávající funkce neupravovali, začal by nám vznikat redundantní kód.

Takto například napíšeme podobnou metodu znovu a nevyužijeme stávající s upravenými parametry. Nebo přidáme zbytečně další databázové tabulky místo toho, abychom jen upravili datový model a podobně.

Vyhýbat se úpravě stávajícího kódu aplikace se vůbec nevyplatí, trpěl by tím její návrh a do budoucna by bylo velmi těžké takový slepenec nějak upravovat nebo rozšiřovat. Poté bychom museli změny provádět na několika místech, bloky kódu by se opakovaly a došli bychom nejspíš k závěru, že takovou aplikaci nelze dále udržovat a rozšiřovat. Takto vývoj softwaru prostě nevypadá.

A kdo potom otestuje, že vše funguje? Člověk? Když jsme došli k tomu, že musíme testovat, zda se předchozí funkčnost novou úpravou nerozbila, povězme si proč nemůže testování provádět člověk.

Úskalí manuálního testování

Představme si následující scénář.

Očekávání

Programátor nebo tester si sedne k počítači a prokliká jednu službu za druhou, jestli fungují. Vezměme si třeba ITnetwork. Tester by se zkusil zaregistrovat, přihlásit se, změnit si zapomenuté heslo, upravit profil, dobít body kreditní kartou... Funkčností (tzv. use cases) jsou ve zdejším systému stovky. Člověk by je testoval hodiny a stroj to nejspíš udělá za pár minut.

Toto ale není hlavní důvod, proč nemůže testování provádět člověk. Sednout si a den klikat není v zásadě pořád takový problém, testy se píší dlouho, možná by se to ještě i vyplatilo. Ale...

Realita

Dejme tomu, že aplikaci takto testujeme, jsme někde v polovině testovacího scénáře a nalezneme chybu. Nejde napsat komentář k článku třeba kvůli změně nějakého validátoru. Chybu opravíme a úspěšně pokračujeme až do konce scénáře. Otestovanou aplikaci nasadíme na produkční server a další den nám přijde email, že nejdou kupovat články.

Po chvíli zkoumání zjistíme, že oprava, kterou jsme provedli, rozbila jinou funkčnost. Tu jsme totiž testovali předtím. Takto bychom mohli přijít i o několik desítek tisíc korun, než nám chybu někdo nahlásí. A to jsme vůbec nezmínili katastrofické scénáře, kdy by došlo k nějakému úniku dat, zaspamování uživatelů a podobně.

Pokud se během testování provede oprava, musíme celý scénář provést od začátku!

Chyb se obvykle najde hned několik a celé testování by se takto protáhlo až na několik dní klikání. Programátor toto pravděpodobně nevydrží a neprovede testy pečlivě, čímž dojde k zanesení chyby na produkci.

Robot - Testování v Kotlin

A právě proto musí testy provádět stroj, který celou aplikaci prokliká obvykle maximálně za desítky minut a může to dělat znovu a znovu a znovu. Proto píšeme automatické testy. Toto nám však bohužel většina návodů na internetu neřekne.

Typy testů

Typů automatických testů je hned několik, obvykle nepokrývají úplně všechny možné scénáře, ale hovoříme o procentuálním pokrytí testy (code coverage). Pokrýváme jimi zejména kritické části aplikace. Čím větší aplikace je, tím více typů testů potřebuje a tím více funkčností obvykle pokrýváme. První verze menších aplikací většinou naopak ještě nepotřebují žádné testy nebo jen ty úplně základní (např. ověřujeme, zda je možné se do aplikace registrovat).

Popišme si základní typy testů:

  • Jednotkové testy (unit testy) obvykle testují univerzální knihovny. Nepíšeme je pro kód specifický pro danou aplikaci. Testují třídy, přesněji jejich metody, jednu po druhé. Předávají jim různé vstupy a zkouší, zda jsou jejich výstupy korektní. Nemá úplně smysl takto testovat, zda metoda obsahující databázový dotaz a použitá v jednom kontroleru, vrací, co má. Naopak dává velmi dobrý smysl testovat např. validátor telefonních čísel, který používáme na více místech. Takový jednotkový test vyzkouší např. dvacet různých správných a nesprávných telefonních čísel a zjistí, jestli je validátor opravdu rozpozná.

Unit testy jsou tzv. whitebox testy, to znamená, že při jejich tvorbě víme, jak testovaný kód uvnitř funguje (vidíme dovnitř).

  • Akceptační testy jsou naopak úplně odstíněny od toho, jak je aplikace uvnitř naprogramovaná. Označujeme je tedy jako blackbox testy. Každý test obvykle testuje určitou funkčnost. Test pro psaní článků například testuje jednotlivé use cases s tím spojené - předání článku ke schválení, schvalování či zamítnutí článku, publikace v roli administrátora...

Tyto testy obvykle využívají framework Selenium, který umožňuje automaticky klikat ve webovém prohlížeči a simulovat internetového uživatele. V podstatě zkouší specifickou logiku aplikace (databázové dotazy a podobně). Testuje se výsledek, který aplikace vygeneruje, ne přímo její vnitřní kód.

  • Integrační testy dohlíží na to, aby do sebe vše správně zapadalo v aplikacích s již poměrně vysokou komplexností. Ty velmi často bývají rozdělené do několika služeb, které spolu komunikují a jsou vyvíjené zvlášť.
  • Systémové testy umožňují kontrolovat další vlivy, se kterými musíme rovněž počítat. Aplikace by měla například zvládnout obsloužit tisíc uživatelů v jeden okamžik. To by ověřil zátěžový test, který spadá mezi systémové testy.

V-model

Úvod do problematiky softwarového testování zakončeme představením tzv. V-modelu. Ten rozšiřuje známý vodopádový model vývoje softwaru, kam patří následující fáze:

  • analýza požadavků,
  • high-level návrh,
  • detailní specifikace
  • a implementace.

Celý software se již dávno nevyvíjí postupným provedením těchto čtyř fází, ale iteračně. Jednotlivé fáze se v krátkých časových intervalech postupně aplikují na další části aplikace. V-model každé z nich přiřazuje testovací fáze, tedy daný typ testů, o kterých jsme mluvili výše:

V-model pro testování softwaru - Testování v Kotlin

Vidíme, že název V-modelu je odvozen z podoby s písmenem V. Unit testy ověříme detailní specifikaci, integračními testy high-level návrh a akceptačními testy zjistíme, zda fungují všechny use cases. V-model může být o několik pater vyšší, pokud je aplikace opravdu rozsáhlá a vyžaduje více typů testů, např. zmíněné systémové testy.

V příští lekci, Testování v Kotlin - První unit test pomocí JUnit, se naučíme programovat unit testy, což jsou ty nejjednodušší testy, které ověřují funkčnost vnitřních knihoven. Obvykle právě s nimi začínáme při pokrývání aplikace testy.


 

Všechny články v sekci
Testování v Kotlin
Přeskočit článek
(nedoporučujeme)
Testování v Kotlin - První unit test pomocí JUnit
Článek pro vás napsal Patrik Olšan
Avatar
Uživatelské hodnocení:
2 hlasů
Autor se věnuje vývoji softwaru, zejména mobilních aplikací
Aktivity