• Nem Talált Eredményt

Tesztvezérelt fejlesztés

In document Programozási technológiák – Jegyzet (Pldal 107-110)

A szerződés alapú tervezés alapelvei

A szerződés

1. Tesztvezérelt fejlesztés

Tesztvezérelt fejlesztés (test-driven development, TDD) alatt egy olyan szoftverfejlesztési megközelítést értünk, amely a tesztelés és a kódfejlesztés folyamatát együttesen, egymástól szét nem választható módon, párhuzamosan végzi. A kód kifejlesztése inkrementális módon történik, és mindig magával vonja az adott inkremens tesztjeinek a fejlesztését is. Mindaddig nem léphetünk a következő inkremens fejlesztésére, amíg a korábbi kódok át nem mennek a teszteken.

Kódújraszervezés

A tesztvezérelt fejlesztés eredetileg az extrém programozásnak (extreme programming, XP) nevezett agilis szoftverfejlesztési módszertan részeként jelent meg, de sikerrel alkalmazhatjuk nemcsak agilis, de hagyományos (terv központú) szoftverek kifejlesztése során is.

A tesztvezérelt fejlesztés három törvénye:

1. Tilos bármilyen éles kódot írni mindaddig, amíg nincs hozzá olyan egységtesztünk, amely elbukik.

2. Tilos egyszerre annál több egységtesztet írni, mint ami ahhoz szükséges, hogy a kód elbukjon a teszt végrehajtásán. A fordítási hiba is bukásnak számít!

3. Nem szabad annál több éles kódot fejleszteni, mint amennyire ahhoz van szükség, hogy egy elbukó egységteszt átmenjen.

Ez a három törvény azt jelenti számunkra, hogy először mindig egységtesztet kell készítenünk ahhoz a funkcionalitáshoz, amelyet le szeretnénk programozni. Azonban a 2. szabály miatt nem írhatunk túl sok ilyen tesztet: mihelyst az egységteszt kódja nem fordul le, vagy nem teljesül valamely állítása, az egységteszt fejlesztését be kell bejezni, és az éles kód írásával kell foglalkoznunk. A 3. szabály miatt azonban ilyen kódból csak annyit (azt a minimális mértékűt) szabad fejlesztenünk, amely a tesztet lefordíthatóvá és sikeresen lefuttathatóvá teszi.

Katák a szoftverfejlesztésben

A katák fogalma a japán harcművészetekből (cselgáncs, kendó, karate, aikidó) szivárgott be a szoftverfejlesztés területére. Eredetileg egy kata alatt egy olyan harcművészeti formagyakorlatot értünk, amely egyénileg vagy párban végrehajtható, részletesen megkoreografált mozgásmintát takar.

A bowling kata

A bowling katát Robert C. Martin (unclebob) írta le először. A gyakorlat célja egy olyan alkalmazás kifejlesztése, amely egy játékos vagy csapat bowling játékban elért pontjait számolja.

„A bowlingot csoportban és egyénileg is lehet játszani. Lényege, hogy tíz mezőt (frame) kell teljesíteni, az első kilenc mezőben két lehetőségünk van a gurításra. Ha a bábukat (pin) egy gurításból letaroljuk – ezt nevezzük strike-nak –, akkor a következő két gurítás eredményét a gép automatikusan hozzáadja a tarolás eredményéhez. Abban az esetben, ha másodikra döntjük le a bábukat – ez a spare –, csak a következő gurítás eredménye adódik hozzá pluszban a pontszámokhoz. A játék legutolsó, tizedik frame-jében strike esetén azonnal legurítjuk a 2 jutalomdobást, spare esetén pedig szintén (persze csak egyet). A maximális 300-as eredményt 12 egymást követő strike adja. Az eredmény nyilvántartása, számolása: Ha nem sikerül két dobásból sem levinni az összes (10) bábut, akkor a ledobott bábuk száma adja a mező értékét (un. "nyitott" frame). Spare-nek hívjuk (jele /), ha két dobásból visszük le a 10 bábut. E mezőhöz az ezt követő gurítás eredménye adódik hozzá. Strike-nak nevezzük jele (X), ha az első gurításra ledöntjük mind a 10 bábut. Ilyenkor elmarad a második gurítás. E mezőhöz a következő két gurítás eredménye is hozzáadódik. Ha egy játékos a tizedik mezőt is hibátlanul teljesíti, akkor ezt követően kap még egy ún. »bónuszdobást«, mely spare esetén egy, strike esetén pedig plusz két dobást jelent.

Lényegében minden frame-ben 30 pontot lehet elérni, így a 10 mező adja a maximum 300 pontot, amit tehát úgy lehet elérni, hogy a lehetséges 10 kezdő + 2 bónuszdobás mindegyike strike.” [ http://hu.wikipedia.org/wiki/Bowling#Szab.C3.A1lyai ].

Az alábbi ábrán egy bowlingjáték eredménye látható: egy-egy nagy négyzet egy-egy keretet (frame-et) jelképez, a felső sorban az egyes keretekben elért gurítások, míg az alsó részben a kumulatív pontszám látható. Az első keretben az első gurítás során egy, a második során négy bábu borult fel, ezért összesen 5 pontot szerzett a játékos. A második frame-ben első gurítása négy, a második öt bábut döntött fel, ezért a keret eredménye 9 pont, így a második keret végére 14 ponttal áll a játékos. A felső sorbeli tömör négyzet strike-ot, az átló mentén kettévágott négyzet pedig spare-t jelöl.

5.1. ábra - Egy bowling játék eredménye

Kódújraszervezés

A legfontosabb tehát a tesztvezérelt fejlesztésse kapcsolatban, hogy megértsük, hogy csupán néhány nagyon egyszerű lépést ismétlünk újra és újra. Ezek az egyszerű kis lépések azonban remek kódolási tapasztalathoz juttathatnak minket. A tesztvezérelt fejlesztés tehát ciklikus tevékenység, mindig ugyanazokat a tevékenységeket hajtjuk végre alkalmazása során. Szokás ezt red–green–refactor cilkusnak is nevezni, mert az egységtesztek grafikus futtatói között bevált színséma segítségével határozhatjuk meg a teendőket:

1. Először is írni kell egy olyan tesztet, amely elbukik (red, hiszen a grafikus futtatók ezt a piros színnel jelölik).

2. Ezt követően alakítani kell a tesztelendő rendszeren mindaddig, amíg az átnem megy majd a teszten (green, hiszen ezt zölddel jelölik).

3. A harmadik lépsben az ismétlődések megszüntetése, a kód újraszervezése (refactoring).

5.2. ábra - A tesztvezérelt fejlesztés ritmusa [KACZANOWSKI2013]

Fontos, hogy megértsük a szemléletmódot: ha valamilyen megvalósítandó funkcionalitásról gondolkodunk, akkor azt tesztek formájában írjuk le előbb! Mivel ez a funkcionalitás még nem készült el, ezért a teszt nyilvánvalóan bukásra van ítélve (sőt, elképzelhető, hogy le sem fordul!). Az alapötlet itt az, hogy rögtön kezdjünk el a kliens fejével és szemszögéből gondolkodni a rövidesen megírásra kerülő kódunkkal kapcsolatban, és képesek leszünk a valóban fontos dolgokra összpontosítani.

Mihelyst ezzel megvagyunk, jöhet a green lépés: megírjuk a funkcionalitást úgy, hogy a tesztelendő kód átmenjen a teszteken. Fontos, hogy csak kis lépésekben haladjunk! Ne akarjunk túlságosan előrehaladni.

Lehetőség szerint mindig csak azt a minimális mennyiségű kódot írjuk meg, ami ahhoz kell, hogy a teszten átmenjen. Nem baj, ha már biztosan tudjuk, hogy az a későbbiekben nem lesz elég, de vegyük figyelembe, hogy lesz egy csomó más tesztünk is, amelyek mind valamilyen funkcionalitás meglétét vizsgálják. Ha túlságosan előre gondolkozunk, fennáll a veszélye, hogy a későbbi döntési lehetőségeink közül veszünk el, a szabadsági fokunkat szűkítjük egy esetlegesen túl korán meghozott döntéssel.

5.3. ábra - A tesztvezérelt fejlesztés ritmusa részletezettebben [KACZANOWSKI2013]

Kódújraszervezés

A harmadik lépés a kód újraszervezése. Miután a tesztjeink sikeresen lefutnak, keresnünk kell a bad smelleket, azon pontokat a kódunkban, amelyek potenciális veszélyforrást jelenthetnek (például az ismétlődő kódrészek sértik a DRY alapelvet, a bonyolult feltételes logikák esetleg nincsenek összhangban a KISS alapelvvel, stb. A tesztjeink az újraszervezés során is jó szolgálatot tesznek: a feladatunk annyi, hogy az újraszervezés során mindvégig zölden tartsuk a futtatási eredményeket (ez látszik a részletesebb ábrán is), hiszen ez jelzi, hogy a kódunk kívülről (a kliens szemszögéből) ugyanúgy viselkedik, mint mielőtt nekikezdtünk az átszervezésnek. Ha bármikor pirosra fordul a jelző, akkor valamit hibáztunk, szóval vonjuk vissza az előző lépést.

Fontos

Nem csak a tesztelendő kódra gondoljunk! Ugyanilyen fontos a tesztkód tisztány és érthetően tartása is, vagyis az újraszervezési lépéseket a tesztosztályainkon éppúgy végezzük el, mint a tesztelt osztályainkon!

Tipp

A tananyaghoz kapcsolódó videók között a Bowling Kata bemutatásán keresztül nyújtunk betekintést a tesztvezérelt fejlesztés mikéntjébe.

In document Programozási technológiák – Jegyzet (Pldal 107-110)