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 - Testování v C# .NET - Úvod do testování

Vítejte, všichni pokročilí programátoři, v online kurzu testování aplikací v C# .NET a Visual Studio.

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. Je určený pro všechny, kteří usilují o slušné zaměstnání, kde vás za tyto zkušenosti velmi dobře ohodnotí. Nebo je určen pro ty z vás, kteří mají nějakou svou aplikaci a rádi by ji dále pohodlně rozšiřovali tak, aby se nemuseli bát, že změny kódu rozbijí původní funkčnost.

Budeme předpokládat, že znáte:

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

Proč testovat

Testování se určitě řadí mezi dobré praktiky vývoje softwaru (best practices). Další takovou praktikou je např. programovat objektově, používat vícevrstvou architekturu a podobně. Některé praktiky bychom měli dodržovat opravdu ortodoxně, např. pro psaní neobjektového kódu 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í.

Kdy testovat

Hned na úvod se zmíníme, že testování je velmi důležité a v určité části projektu dokonce nepostradatelné. Na druhou stranu, v prvních fázích projektu (a to zejména u start-upů), kdy se hraje na čas, funkčnosti aplikace se často mění, a je třeba aplikaci co nejdříve spustit, není vůbec dobrý nápad testy psát.

Musely by se č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 budgetem (rozpočtem). Konec konců, i jeho plat vychází z toho jak je aplikace konkurenceschopná. 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ž mají několik stabilních funkčností.

Rozšiřování softwaru

Jakékoli rozšiřování softwaru, pokud jej děláme kvalitně, 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, ale i když se budeme hodně snažit, trh se mění nekontrolovaně a úspěšnou aplikaci bude třeba upravovat ze všech stran. Pokud stávající funkce nebudeme upravovat, začne nám vznikat redundantní kód (např. napíšeme podobnou metodu znovu, místo abychom jen parametrizovali nějakou, co již aplikace má, přidáváme zbytečně další databázové tabulky místo toho, abychom jen upravili datový model a podobně).

Asi víme, že 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, když bychom museli změny provádět na několika místech, bloky kódu by se opakovaly a podobně. Došli jsme tedy k tomu, že svou aplikaci budeme stále měnit a přepisovat, takto vývoj softwaru prostě vypadá. 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.

Proč to nemůže testovat člověk?

Zamysleme se nad naivní představou.

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í (use casů) jsou ve zdejším systému stovky. Jestli vás napadá, že člověk by je testoval hodiny a že proto to necháme udělat stroj, který to udělá pravděpodobně za pár minut, stále nemáte úplně pravdu. 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

Představme si, že takto testujeme aplikaci, jsme někde v polovině testovacího scénáře a nalezneme chybu. Nejde napsat komentář k článku např. kvůli změně nějakého validátoru. Chybu opravíme, úspěšně pokračujeme až do konce scénáře. Otestovanou aplikaci nasadíme na produkční server.

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, kterou jsme již otestovali předtím. Takto bychom mohli přijít i o několik desítek tisíc Kč, než by nám chybu někdo nahlásil. 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í se celý scénář provést od začátku!

A že se těch chyb obvykle najde hned několik, celé testování se protáhne až na několik dní klikání. Programátor toto pravděpodobně nevydrží a neprovede testy pečlivě (osobně jsem frustraci z provádění těch samých úkonů stále dokola nikdy nesnesl :) ), čímž dojde k zanesení chyby na produkci.

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.

Robot - Testování v C# .NET

Typy testů

Zaměřme se nyní na to, co na aplikaci testujeme. Typů testů je hned několik. Obvykle nepokrývají úplně všechny možné scénáře (všechen kód). Hovoříme o procentuálním pokrytí testy (code coverage), většinou kritických částí aplikace. Čím větší aplikace je, tím více typů testů potřebuje a tím více funkčnosti 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ř. aby se do nich dalo registrovat.

Popišme si ty nejzákladnější typy testů:

  • Jednotkové testy (Unit testy) - Obvykle testují univerzální knihovny, nepíšeme je pro kód specifický pro danou aplikaci. Jednotkové testy 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 pomocí unit-testů testovat, zda metoda obsahující databázový dotaz, která je použita v jednom kontroleru (CodeBehindu, nějaké řídící vrstvě) vrací co má. Naopak dává velmi dobrý smysl testovat např. validátor telefonních čísel, který používáme na 20 místech nebo dokonce v několika aplikacích. Takový jednotkový test vyzkouší např. 20 různých správných a nesprávných telefonních čísel, jestli validátor opravdu pozná, která jsou validní a která ne. Unit testy jsou tzv. whitebox testy, to znamená, že je píšeme s tím, že víme, jak testovaný kód uvnitř funguje (vidíme dovnitř).
  • Akceptační testy - Tento typ testů je naopak úplně odstíněn od toho, jak je aplikace uvnitř naprogramovaná, jsou to tedy blackbox testy (nevidíme dovnitř). Každý test obvykle testuje určitou funkčnost, např. test pro psaní článků by testoval jednotlivé use cases s tím spojené (předat článek ke schválení, schválit článek, zamítnou článek, publikovat článek jako administrátor...). Tyto testy obvykle využívají framework Selenium, který umožňuje automaticky klikat ve webovém prohlížeči a simulovat internetového uživatele, který naši aplikaci používá. Těmito testy se tedy v podstatě zkouší specifická logika aplikace (databázové dotazy a podobně), testuje se výsledek, který aplikace vygeneruje, ne přímo její vnitřní kód.
  • Integrační testy - V dnešní době dosahují aplikace již poměrně vysoké komplexnosti a velmi často bývají rozdělené do několika služeb, které spolu komunikují a jsou vyvíjené zvlášť. Právě integrační testy dohlíží na to, aby do sebe vše správně zapadalo.
  • Systémové testy - I když aplikace funguje dobře, na produkčním prostředí podléhá dalším vlivům, se kterými musíme rovněž počítat. Např. že by měla zvládat obsluhovat tisíc uživatelů v jeden okamžik. To bychom provedli zátěžovým testem, který spadá mezi systémové testy.
  • A mnohé další...

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, který má následující fáze:

  • Analýza požadavků.
  • High-level návrh.
  • Detailní specifikace.
  • Implementace.

Software se již dávno nevyvíjí postupným provedením těchto 4 fází, ale iteračně, tedy prováděním těchto fází v krátkých časových intervalech pro další a další části aplikace. V-model každé z těchto fází přiřazuje testovací fáze (typ testů, o kterých jsme mluvili výše):

V-model pro testování softwaru - Testování v C# .NET

Vidíme, že název v-modelu je odvozen z podoby s písmenem V.

Po implementaci ověříme:

  • unit testy detailní specifikaci,
  • integračními testy high-level návrh,
  • akceptačními testy zda fungují všechny use casy.

V-model se někdy dělá ještě o několik pater vyšší, pokud je aplikace opravdu rozsáhlá a vyžaduje více typů testů, např. ještě testy systémové).

V příští lekci, Testování v C# .NET - Úvod do unit testů a příprava projektu, se naučíme programovat unit testy, což jsou ty nejjednodušší testy, které ověřují funkčnost vnitřních knihoven (jednotek) a obvykle s nimi začínáme při pokrývání aplikace testy.


 

Všechny články v sekci
Testování v C# .NET
Přeskočit článek
(nedoporučujeme)
Testování v C# .NET - Úvod do unit testů a příprava projektu
Článek pro vás napsal David Hartinger
Avatar
Uživatelské hodnocení:
125 hlasů
David je zakladatelem ITnetwork a programování se profesionálně věnuje 15 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David se informační technologie naučil na Unicorn University - prestižní soukromé vysoké škole IT a ekonomie.
Aktivity