ugrás a tartalomhoz

TDD?

eddig bírtam szó nélkül · 2012. Júl. 3. (K), 20.34
Picit belenéztem a phpunit használatába.
Arra lennék kíváncsi, jó-e az elképzelésem róla?
A TDD (egészen nagy vonalakban, vázlatosan) valahogy úgy működik, hogy
1. megtervezem, hogy nagyjából milyen osztályokra bontom az alkalmazást
2. kitalálom az egyes osztályok interface-ét
3. ezen interface-ekhez megírom a teszteket
4. elkészítem az osztály kódját
5. futtatom a tesztet és addig javítom a kódot, míg nem lesz hibátlan valamennyi
?

Ebből nekem hiányzik a privát/protected metódusok működésének tesztelése. Unit teszt esetén ez szükséges egyáltalán? (érzésem szerint nem, hiszen ha az adott interface/API publikus alkatrészei helyesen működnek, az csak úgy lehet, ha a nem publikus részek is megfelelően üzemelnek)

Bónusz kérdés (költői! ;-) ) : létezik élő ember, aki képes egy komolyabb rendszerre átfogó tesztet írni úgy, hogy közben a határidőket is be tudja tartani? :-)
----------------------------------
Félreértések elkerülése végett: a saját elképzeléseimet foglaltam össze (ebben a pillanatban botlottam egy angol nyelvű cikkbe, ahol közelítőleg ezt írták... szóval valószínűleg így működik, de nem onnan másoltam :-) )
 
1

Igen

Poetro · 2012. Júl. 3. (K), 20.54
Teljesen helyes az elgondolás. A privát metódusoknak jól kell, hogy működjenek, hogy a publikus metódusok helyes választ adjanak. Igazából a lényeg, hogy a teszteknél minél több eshetőségre felkészülj, hogy azok minden esetben a publikus interfész helyes választ ad-e. Külön érdemes felkészülni a speciális esetekre, mint mikor null illetve üres string érkezik, valamint amennyiben számokkal dolgozunk, akkor az működik-e azok speciális esetére is.

Kevés olvasnivaló magyarul:
10

Tankjú! (A diasor picit

eddig bírtam szó nélkül · 2012. Júl. 4. (Sze), 07.07
Tankjú! (A diasor picit kiakasztott, mikor az egyik oldalon megjelent valami Microsoftos kütyü... elsőre nagyon nem értettem, mit keres ott :D )
2

TDD By Example

blacksonic · 2012. Júl. 3. (K), 21.21
Nagyon jó alapolvasmány hozzá Kent Beck: Test Driven Development: By Example című könyve, ebben leírják a mikéntjét
3

Megelőztél, pont most akartam

duplabe · 2012. Júl. 3. (K), 21.26
Megelőztél, pont most akartam linkelni. Tényleg érdemes elolvasni, nagyon jó könyv.
4

A TDD (egészen nagy

tgr · 2012. Júl. 3. (K), 23.35
A TDD (egészen nagy vonalakban, vázlatosan) valahogy úgy működik, hogy
1. megtervezem, hogy nagyjából milyen osztályokra bontom az alkalmazást
2. kitalálom az egyes osztályok interface-ét
3. ezen interface-ekhez megírom a teszteket


Az a design-driven testing... Nekem az jött le, hogy a TDD lényege elvileg az, hogy tesztírással kezded, és a struktúra természetesen alakul ki, ahogy haladsz vele. (Veszed az első tesztet, megvalósítod (közben készül valami osztály), veszed a következő teszted, módosítod, hogy az is átmenjen, refaktorálsz, veszed a következő tesztet stb. A teszteket a specifikáció nagyjából meghatározza.) Hogy használják-e élőben ebben a formában, azt nem tudom.
6

Na ezt nem értem

eddig bírtam szó nélkül · 2012. Júl. 4. (Sze), 06.06
Csak a "józan paraszti eszemet" (illetve ami megmaradt belőle) használva:
Mire kezdesz tesztet írni, ha nincs egy terved arra nézve, hogy milyen darabokra akarod szétszedni az adott feladatot és ezek a darabok milyen interface-en kapcsolódnak egymáshoz?

Vagy csak szimpla félreértésről van szó?
Amikor interface-ről beszélek, akkor nem a PHP kulcsszóra gondolok, pusztán egy elméleti felületre.
Tehát kb. kitalálom, hogy milyen bejövő paraméterekre lehet szükség egy adott objektum működéséhez és mit várnék el tőle - kódot egy sort sem írok.
8

Félreértetted - szerintem

Pepita · 2012. Júl. 4. (Sze), 06.29
Ha megnézed tgr sorszámozását, gyakorlatilag u.ezt a sorrendet írta.
9

Az csak idézet

eddig bírtam szó nélkül · 2012. Júl. 4. (Sze), 06.54
A sorszámok a posztból vett idézetek. :-)
20

Ja-ja bocs

Pepita · 2012. Júl. 5. (Cs), 01.29
Annyira azon járt az agyam, amit írt, hogy ezen átsiklottam... :)
17

Az a design-driven testing...

inf · 2012. Júl. 4. (Sze), 21.47
Az a design-driven testing... Nekem az jött le, hogy a TDD lényege elvileg az, hogy tesztírással kezded, és a struktúra természetesen alakul ki, ahogy haladsz vele. (Veszed az első tesztet, megvalósítod (közben készül valami osztály), veszed a következő teszted, módosítod, hogy az is átmenjen, refaktorálsz, veszed a következő tesztet stb. A teszteket a specifikáció nagyjából meghatározza.) Hogy használják-e élőben ebben a formában, azt nem tudom.

Igen, szerintem is ez áll közelebb a TDD-hez. Egyébként használják ilyen formában, legalábbis nekem van olyan ismerősöm, aki igen. Én megpróbálkoztam vele, de szerintem túl kevés még a tapasztalatom hozzá, és nem tudom rendesen átgondolni egy projekt elején, hogy pontosan mit akarok, így viszont amint eszembe jut egy-egy új ötlet, dobhatom kukába a tesztjeim egy részét, mert az új ötlet teljesen más interface-t használ.
5

Red Green Refactor Red Green

Joó Ádám · 2012. Júl. 4. (Sze), 01.25
Red
Green
Refactor

Red
Green
Refactor

Red
Green
Refactor…

(Írsz egy tesztet a legegyszerűbb interfészre, ami megoldaná a problémád. Futtatod, és konstatálod, hogy nem működik.

Belekódolod a megoldást, hogy működjön.

Észreveszed, hogy a megoldásod redundáns, így hát általánosítod.)

Kent Beck-et olvasd el.
13

Red...

eddig bírtam szó nélkül · 2012. Júl. 4. (Sze), 08.18
Közben megtaláltam Bob bácsi könyvében az ezzel foglalkozó fejezetet és azt hiszem, amit te Red-ként említesz, az magyarra fordítva az első sikertelenül lefutó tesztet jelenti. "Ez lehet akár fordítási hiba is...". (szintaktikai v. egyéb okból - gondolom én, de ugye ő java-t használ)
No ez nem tiszta. Elkezdem írni a tesztet úgy, hogy (maradjunk PHP környezetben) a tesztelendő osztályból még egy üres forráskód fájl sem létezik, ergo az első require_once elhasal rajta -> javítom, hogy már létezzen, majd folytatom a tesztírást az osztály példányosításával, ami megint elakad, mert még csak egy üres .php fájl van a tesztelendő osztály helyén -> megírom az osztályt konstruktorig -> mikor ez a teszt már sikeres, akkor írom a publikus metódusok tesztjeit ugyanilyen ciklusban stb.
Ez valahogy így?
14

Pontosan.

Joó Ádám · 2012. Júl. 4. (Sze), 10.25
Pontosan.
18

Így, de pont, hogy nem ez az

inf · 2012. Júl. 4. (Sze), 21.50
Így, de pont, hogy nem ez az eleje a lényeg, ha úgyis tudod, hogy ez meg ez miatt fog elhasalni a teszt, akkor alapból belemásolhatod az interface-ből a metódusokat, és létrehozhatsz egy vázat az osztálynak. Szóval rugalmasabban is lehet kezelni ezeket az elveket... A kis lépések inkább a kódolásra vonatkoznak... Írsz egy kis tesztet, aztán írsz hozzá egy kis kódot, és így tovább...
7

A könyv

eddig bírtam szó nélkül · 2012. Júl. 4. (Sze), 06.18
A Kent Beck könyvére adott tippeket köszi mindenkinek!
(mivel már letettem arról, hogy a programozásból megéljek, már nem fér a keretbe - nem panasz, pusztán tényközlés, hogy nem ignorálom a javaslatot)
11

először a teszt írás és utána a kód

T.G · 2012. Júl. 4. (Sze), 07.35
Én néhányszor gyakorlás gyanánt próbáltam, hogy valóban először a teszt írás és utána a kód, és meg kell mondanom felemelő érzés. :)

Bár ehhez az is kell, hogy amikor olvassa az ember a Tiszta kódot, akkor "érezze a katarzis"-t, mint ahogy egy másik fórumtémában írtad, hogy ez elmaradt... :)

A probléma az, hogy ha nincs rutin, akkor ez sokkal lassabb, mintha kihagynánk, vagy csak utólag írnánk teszteket. Ami nálam probléma, hogy a TDD-nél sokkal előrébb kell gondolkodni. A tervezés során nem tudom megtippelni, hogy egy osztály átlépi-e a 100 sort vagy sem? Nem látom, hogy ebből majd fél óra múlva két osztály lesz stb.

De a lényeg a lényeg, a nagykönyv szerint a teszt írás az első, a kód írás a második. Ám nem nagyon kell szégyenkezned, ha nem ebben a sorrendben csinálod, a legtöbben egyáltalán nem használnak teszteket, akik igen, azoknak is a legtöbbje utólag ír tesztet, és Bob bácsi és néhány haverja meg elsőre írja a tesztet. :)

A lépéseidet azért mégis annyiban módosítanám, hogy az utolsó lépésben nem addig javítom, amíg valamennyi teszt jó nem lesz, hanem addig alakítom a kódot, amíg a lényeges pontok tesztelhetővé vállnak. (bár ez is csak lehet, hogy nálam igaz, és szintén a rutintalanság miatt, hogy az elkészült osztályszerkezet nehézkesen tesztelhető, és itt jön elő, hogy egy osztály csak egy dolgot csináljon)
12

Egy óriási probléma...

eddig bírtam szó nélkül · 2012. Júl. 4. (Sze), 08.08
Én csak középiskolában tanultam (iskolarendszerben) a programozást, ennek is már harminc éve... :-(
Programozással csak "coder"-ként foglalkoztam, a tervezést sohasem tanultam, pláne nem gyakoroltam.
Ebbe a témába azért esik nehezemre belerázódni, mert még a legegyszerűbb feladatok megtervezése is iszonyatosan sok munkába kerül és egyszerűen nincs hozzá türelmem.
Szomszéd Pistikét nem akarok játszani még így, hobbi szinten sem, viszont a hiányzó alapismeretek+türelmetlenség... hát nem jósolok nagy jövőt magamnak... :-)

Tegnap belebotlottam (ki tudja hanyadszor) a phpunitba és úgy döntöttem, kipróbálom. Most itt tartok. Próbálgatom.
21

Tervezés

Pepita · 2012. Júl. 5. (Cs), 01.45
Ez az első. Enélkül mihez kezdesz neki?
Igazad van: egy jó program- (és adatbázis-) terv sok munkába és türelembe kerül. Azt hiszem Janoszentől olvastam, hogy egy projektnek ez több mint a fele. Egyet is értek vele.

Ha van egy jó terved, akkor a programozás max. a fele annak, mint ha nincs terved. De inkább negyede.

Ha nincs terved, akkor csak kókányolás lesz belőle millió javítgatással - tehát akkor bizony olyan vagy, mint Szomszéd Pistike.

Ha nagyon nem megy a tervezés, akkor talán még nem a TDD a következő lépés számodra. Én - hősiesen bevallom - eddig megvoltam a phpunit nélkül, de érzem, hogy valamire nagy szükségem van, csak még nem tudom (biztosan), hogy mire.

Szerk.: ja, és egy kicsike honlapnál - nálam - az adatbázis- és a programterv gyakorlatilag egyszerre készül, nem is nagyon válik szét.
22

Ez az első. Enélkül mihez

inf · 2012. Júl. 5. (Cs), 02.16
Ez az első. Enélkül mihez kezdesz neki?
Igazad van: egy jó program- (és adatbázis-) terv sok munkába és türelembe kerül. Azt hiszem Janoszentől olvastam, hogy egy projektnek ez több mint a fele. Egyet is értek vele.

+1, a terv a legfontosabb része. Runtin nélkül elég nehéz elsőre úgy összerakni, akár még egy adatbázist, hogy az tényleg jó legyen. Nekem előfordul még, hogy hozzá kell csapni egy-egy táblát is akár, még csak tanulom :-)

PhpUnit nálam azért nem vált be, mert windows alatt fejlesztek, és képtelenség telepíteni rá. Pár napot próbálkoztam vele, aztán úgy döntöttem, hogy hatékonyabb, ha keresek mást. A simpleTest, amit találtam, kb 10 perc alatt fent volt... Nálam az egyik legfőbb mérce azzal kapcsolatban, hogy jó e egy program, vagy lib, hogy mennyire egyszerű telepíteni. Elhiszem, hogy ez a Sebastian Bergmann gyerek egy nagy linux meg pear fun, de nálam nagyon durván elbukott... :-)
23

Akkor nálam is elbukott

Pepita · 2012. Júl. 5. (Cs), 03.00
Én is megrögzött windows-os vagyok.
Szerintem adatbázis összerakásban senkinek nincs rutinja, hacsak nem pontosan ugyanazokat a feladatokat oldod meg többször.
Ha meg beficcen egy-egy plusz tábla, akkor sincs semmi baj, ha amúgy jó a db, akkor könnyen illeszthető. A feladatspecifikáció viszont pontatlan volt, ha kellett plusz tábla.
Szerintem adatbázis-tervezésnél elsősorban lekérdezési oldalról kell közelíteni (mármint ha már meg van, hogy mit akarok tárolni, csak még nem tudom hogyan), nekem legalábbis sokat segít annak eldöntésében, hogy mi kerüljön az egyes táblákba, hogy tudom a gyakori lekérdezéseket minél egyszerűbbé (és gyorsabbá) tenni.
Bizony, ha jó az adatbázistervem, velem előfordul, hogy a programterv "csak fejben van"... Ez persze nagy hiba.
24

Hát itt konkrétan az volt,

inf · 2012. Júl. 5. (Cs), 09.17
Hát itt konkrétan az volt, hogy jelszó cserés meg rendelés visszaigazolós email-ekhez csináltam egy remoteCommand táblát, amit csatoltam a User-hez. A specifikáció nem volt pontatlan, inkább a kidolgozottsága az adatbázisnak volt az. Egy részét nagyon jól átgondoltam, és meg is valósítottam, a többinél meg mindig akkor kellett módosítani, amikor odaértem, és észrevettem, hogy hoppá, ide még kelleni fog 1-2 dolog... Szóval én a TDD-t ott bukom el, hogy nem gondolom át elég mélyen minden elemét a projektnek mielőtt nekikezdek...
15

Nem egeszen

blacksonic · 2012. Júl. 4. (Sze), 10.43
Ami nálam probléma, hogy a TDD-nél sokkal előrébb kell gondolkodni. A tervezés során nem tudom megtippelni, hogy egy osztály átlépi-e a 100 sort vagy sem? Nem látom, hogy ebből majd fél óra múlva két osztály lesz stb.


Pont hogy elore nem kell ezzel foglalkoznod. Amikor ugy erzed hogy az osztalyod mar tul sok mindenert felelos, vagy duplikacio van benne egyszeruen refaktoralod. A meglevo tesztek meg biztsitjak, hogy refaktoralas kozben nem rontasz el semmit.
19

Ez oké, de mi van, ha úgy

inf · 2012. Júl. 4. (Sze), 21.58
Ez oké, de mi van, ha úgy döntesz, hogy magát az interface-t is több részre bontod szét? Akkor a teszteket is darabolnod kell...
25

A tesztek refaktorálása

Joó Ádám · 2012. Júl. 5. (Cs), 15.06
A tesztek refaktorálása ugyanolyan fontos része a TDD-nek. De egyszerre mindig csak az egyiket változtatod, így egymást ellenőrzik.
26

Megint tanultam valamit :-)

inf · 2012. Júl. 5. (Cs), 15.12
Megint tanultam valamit :-)
16

1. megtervezem, hogy

inf · 2012. Júl. 4. (Sze), 21.41
1. megtervezem, hogy nagyjából milyen osztályokra bontom az alkalmazást
2. kitalálom az egyes osztályok interface-ét
3. ezen interface-ekhez megírom a teszteket
4. elkészítem az osztály kódját
5. futtatom a tesztet és addig javítom a kódot, míg nem lesz hibátlan valamennyi


Ez nem így megy szerintem. Én úgy állnék neki TDD-vel, hogy nagyjából elgondolom, hogy mit várok el, aztán létrehozok az elvárásaimmal összehangban egy vagy több interface-t, ami nagyjából lefedi az alkalmazást. Utána kiválasztom a legegyszerűbb metódust valamelyik interface-en, és írok hozzá egy tesztet, utána pedig megpróbálom megvalósítani egy osztályban. Ilyenkor jön általában az, hogy kiderül, hogy az a metódus mégsem annyira egyszerű, mint elsőre tűnt, és elkezdesz új interface-eket, teszteket és osztályokat gyártani, hogy szétosszad a feladatait, és megteremtsd az előkövetelményeket neki. Aztán néhány ilyen ciklus után már tényleg elég aprók lesznek az osztályok ahhoz, hogy meg tudd valósítani őket, és akkor ahogy elkezd épülni a kód szép lassan egyre feljebb halad ezen a kiépült osztály hálón, míg végül megint felérsz az eredetileg kiválasztott "legegyszerűbb" metódusodhoz. Utána fogod a következőt, azzal viszont már könnyebb dolgod lesz, mert az első metódushoz tartozó segéd osztályokat és interface-eket újrahasznosíthatod hozzá. Így minél későbbi fázisában vagy a kódolásnak, annál könnyebben megy minden, mert a segédosztályok egyre nagyobb hányada lesz már elve készen. Ha egy meglevő keretrendszert használsz, és ismered is a lehetőségeit, akkor meg még könnyebb dolgod van, mert abban már a segéd osztályaid nagy többsége már kész van. (Ettől függetlenül érdemes azokhoz is teszteket írnod, ha a keretrendszer készítői nem tették volna meg.)