Sačuvajte vreme i glavu — testirajte softver

Cilj ove serije o testiranju softvera je da vam da inspiraciju za vaše buduće projekte. Trebalo bi da vam takođe pruži mnoštvo mogućnosti koje će vam pomoći da unapredite rad svog softvera — ne samo na kratke, već i na duže staze.

Tobias Baube - 1. Mart, 2016.

Kao prvo, ne bih želeo da raspravljam o tome kakvu vrstu postupka za unapređenje softvera bi neko trebalo da izabere ili preferira. Bilo da je to TDD (unapređivanje testiranjem) u kombinaciji sa Scrum ili Waterfall metodama – nije mi važno.

Cilj ove serije o testiranju softvera je da vam da inspiraciju za vaše buduće projekte. Trebalo bi da vam takođe pruži mnoštvo mogućnosti koje će vam pomoći da unapredite rad svog softvera — ne samo na kratke, već i na duže staze.

Cilj je jednostavan: Unaprediti svest o neophodnosti testiranja i različite prednosti koje ono nudi.

Želeo bih da istaknem da postoje četiri načina (pristupa) testiranja softvera. U nekim narednim objavama na blogu, a koje će tek biti prikazane, pozabaviću se njima detaljnije:

– Testiranje jedinica verifikuje funkcionalnost jedne zasebne funkcije ili metode (najmanja jedinica među navedenim načinima testiranja);

– Testiranje integracije obezbeđuje ispravnu funkcionalnost softvera kroz brojne funkcije ili pak različite nivoe softvera ili sistema (ovi testovi takođe uključuju i testove za primenu programskog interfejsa (API) i testove za komponente);

– Testiranje korisničkog interfejsa (UI) sprovodi se direktno na korisničkom interfejsu, a ovde polazimo od pretpostavke da je softverska logika ispravna i samo želimo da obezbedimo adekvatnu vizuelizaciju (redosled);

– Ručno testiranje (ovo bih nazvao „pristup menadžera projekta” ;-) ) podrazumeva da onaj ko testira softver ručno prođe kroz aplikaciju i lično je testira. Za razliku od ostala tri, ovo testiranje se ne izvodi automatski!

testing_pyramid-550x428
Piramida testiranja – prikaz različitih mogućnosti testiranja postojećih softvera

Za razliku od prva tri načina testiranja, kod ručnog testiranja je zaista neophodno ljudsko biće koje će ih sprovesti. Stoga se ovo testiranje ne izvodi automatski, pa samim tim predstavlja neku vrstu uskog grla na strani ljudskih resursa.

Automatska testiranja mogu se sprovoditi nezavisno od vremena i automatski slati izveštaje licima zaduženim za unapređenje softvera, menadžerima projekta ili vašem poštaru — kome god vi želite.

Međutim, često se pogrešno smatra da automatska testiranja oduzimaju dosta vremena razvoju u samom korenu, pa samim tim direktno utiču kako na trajanje izrade projekta, tako i na brzinu samog progresa. I, premda, ona mogu pomoći softverskim inženjerima da uoče greške i poboljšaju softver, mogu poslužiti i za baratanje u nekim graničnim slučajevima. Dobar softverski inženjer ovo obavezno odradi.

!! Upozorenje: ulazite u zonu sarkazma !!

Navodni privremeni zaključak:

Već data objašnjenja (pojednostavljena):

Razmatranje:

Zaključak:

Pretpostavimo sada da su korisnički testovi uglavnom gotovi i zaista pokrivaju najčešće neuspešne i uspešne slučajeve upotrebe koji su prethodno jasno naglašeni i definisani. Nije važno da li koristite brze postavke ili radije birate pristup vodopada od vrha ka dnu, pre ili kasnije objavićete novu verziju. Iz ma kog razloga.

Kako biste obezbedili pouzdano softversko rešenje od vas bi se očekivalo da ponovo testirate sve načine upotrebe (regresivno testiranje).

Ali!

Samim testiranjem novih funkcija ili sitnih problema (bagova) koji su već popravljeni mogli biste čak i da produžite vreme završetka projekta.

Uspešnost vašeg projekta biće još i veća, a da pritom štedite vreme i novac. Jer: ukoliko biste sve ponovo testirali, bilo bi to kao da isti posao radite dva puta. Pa, nemojte to raditi – ali vas još uvek muči efikasnost.

Disciplina traćenje

Elem, pozabavite se sada razmatranjem zahteva! Adaptacije softvera će uticati na postojeće komponente budući da ne želite da programirate nekoliko (prilično sličnih) komponenti više puta ili da vršite korelacije sa određenim komponentama.

Ali, na koji način argumentovati validnost tih uticaja? U suštini, ispunjenje ovih zahteva bitan je faktor uspešnosti jednog projekta. Bez obzira o kom projektu je reč. Sve dok efikasnost u pogledu trošenja vremena i novca nije ispod nule, vredno je truda zbog jedne jednostavne činjenice:

Sve dok su zahtevi ispunjeni i vi ne poslujete u minusu, projekat je, ipak, ostvario neki vid uspeha i samim tim bio vredan truda.

Zaključak:

Već data objašnjenja (pojednostavljena):

Razmatranje:

Zaključak:

Za slučaj da ste još uvek skeptični po pitanju automatskog testiranja, zamolio bih vas da bacite bogled na zaključak i deo „automatski testovi” u njemu zamenite sa “testovi”. Istog momenta ćete razumeti potrebu testiranja nečega pre same distribucije ili objavljivanja.

Zašto ne automatizovati te procese kad ono štedi vaše vreme i troškove, a u krajnjoj liniji i živce jer se posao ne ponavlja?

Na kraju krajeva, suočite se sa činjenicom: uspeh – bez obzira kakav – je višedimenzionalno stanje, jer možete biti uspešni na više nivoa. Ali, ako padnete na nekom od najvažnijih, poput kvaliteta i poverenja, uspeh će se pretvoriti u neuspeh i to na duže staze.

Sada izračunajte verovatnoću neuspeha projekta samo zato što ste želeli da budete još efikasniji po pitanju uštede vremena i smanjenja troškova.

Štaviše, projekti izrade softvera ne uvode se radi praćenja aktuelnih trendova. Oni su, zapravo u funkcionalnoj upotrebi već godinama, i dok se zahtevi okoline mogu menjati, njihova rešenja zahtevaju stabilnost i povremene potrebe radi usklađivanja sa novim propisima, potrebama ili jednostavno očekivanjima korisnika.

Stoga bi uspešnost jednog projekta trebalo meriti i prema njegovoj sposobnosti da taj uspeh održi.

Projekat se ne može smatrati održivim ukoliko troškovi zamene premašuju normalna očekivanja jer trud uložen u ponovno testiranje prevazilazi troškove same komponente. Nemogućnost održavanja softvera usled dodatnih troškova je na samo korak od programskog zastarevanja. Napori uloženi u ponovno testiranje se mogu držati pod kontrolom samo ako visok nivo automatskog testiranja garantuje regresiju.

Testiranje softvera — Testiranje jedinica

Testiranje jedinica sjajan je način da se osigura ponašanje određene funkcije onako kako je predviđeno i obezbedi očekivani rezultat. Ova ideja testira samo određenu funkciju ili metodu, pa samim tim obezbeđuje pouzdanost samo jednog kamena u temelju, i to onu koju korisnik neće iznova testirati.

Uvod

Svi su do sada već prepoznali potrebu za testiranjem jedinica i vi ste ih svakako svesni, ali mi bismo ipak želeli da ih još jednom pomenemo kako bismo zadržali celovitost u radu. U piramidi softverskog testiranja, najviše slučajeva testiranja piše se upravo za testiranje jedinica.

Naravno, moraju se uzeti u obzir i određena ograničenja, a naročito granični slučajevi o kojima se posebno vodi računa. Ukoliko softverski inženjer nije u mogućnosti da prepozna takve granične slučajeve, testiranje jedinica se samo po sebi može smatrati nefunkcionalnim.

Bilo bi još i bolje kada softverski inženjer ne bi uopšte morao sam da prepoznaje sve te granične slučajeve, već da se prethodno utvrde specifikacije, zahtevi ili kriterijumi onoga šta je prihvatljivo.

Primer lozinke

Sledeći primer će na jednostavan način ilustrovati pristup i koristi koje imate od pisanja testova za testiranje jedinica. Polja za ocenjivanje validnosti lozinke su, naravno, uvek aktuelna tema za diskusiju, mada ja, opet, mislim da je najjednostavnije da tako ilustrujemo ceo pristup.

Najomiljenija — povratna informacija od nadležnih za validnost lozinke: „Lozinka nije dovoljno sigurna”. Nije dovoljno sigurna po specifikaciji. A specifikacije se mogu razlikovati.

Kao primer, u našem polju za lozinku dozvolićemo samo brojeve i slova (velika i mala). Uklučujući minimalnu (5) i maksimalnu (10) dužinu.

Sada bi trebalo uvesti polje za korisničku lozinku koje se odnosi na određenu funkciju i proveru validnosti njegovog unosa. Mogli bismo da nastavimo dalje da kucamo sve kombinacije lozinki koje nam padnu na pamet.

Međutim, ovim nije obuhvaćeno mnoštvo graničnih slučajeva, a i dodatno bi nas nerviralo da sve ove nizove ručno kucamo u datom polju.

Ali, rešenje je prilično očigledno: jednostavno uvedite dve vrste listi (lozinke koje su validne i one koje nisu), pustite da testiranje jedinica odradi svoj deo i ocenite kao validnu povratnu vrednost naše funkcije za ocenjivanje validnosti.

Svakako, nije uvek tako lako predvideti sve moguće vidove tekstualnog unosa. Srećom, u najvećem broju slučajeva ograničenja datih unosa dobro su precizirana.

Na ovaj način je mnogo lakše testirati sve moguće kombinacije koje korisnici unose. Sami tim je mnogo pouzdanije i iziskuje manje vremena. Čak ukoliko to želite, možete da nakon ovoga samo proširite funkciju za ocenjivanje validnosti određenim povratnim vrednostima, kao što je ona za ukazivanje šta kod lozinke nije dobro: dužina, tip karaktera itd.

A, najbolje od svega je to što vam treba samo nekoliko linija koda da biste lakše ocenili napisani kod, a istom brzinom biste održavali svoje funkcije za slučaj da je neophodno uvesti neke izmene.

Zarad ilustrovanja cele ove priče, dodao sam jedan „starinski” Objective-C kod za gorenavedeni tip testiranja.

E, i molim vas: Pošto ne želimo da ubacujemo neophodne liste svojstava samog testa u našu produktivnu primenu, podesite da cilj liste bude samo cilj testa.

Screen Shot 2016-03-01 at 16.07.37

Tekst je preuzet sa Namics bloga, a originalni sadržaj možete pronaći ovde i ovde