Tesztvezérelt trükkösláda



Az eredeti cikk szerzője Pat Eyler. Ezt a feldolgozást a Rubylation Network készítette és fordította le több nyelvre.

Jelenlegi rovatunkban a tesztvezérelt fejlesztés eszközeit vesszük górcső alá. Ha nem vagy jártas a tesztvezérelt fejlesztésben, és szeretnél róla többet megtudni, itt találsz néhány jó cikket:

Azért kedvelem a tesztvezérelt programozást, mert biztosabb vagyok abban hogy amit megírtam, működik. Ezzel a módszerrel gyorsan össze tudok ütni egy működÅ‘képes elsÅ‘ verziót, amit késÅ‘bb könnyen át lehet designolni. A Ruby nyelvhez kiváló tesztvezérelt fejlesztést segítÅ‘ eszközök léteznek – többek között a Test::Unit, rake, rcov, unit_diff és az autotest programokat tartom nélkülözhetetlennek.

Az elsÅ‘ kettÅ‘ a legtöbb Ruby hacker számára valószínűleg ismerÅ‘sen cseng. Ha még nem volt alkalmad dolgozni velük, a “csákányos könyv” (Pick Axe book) remek dokumentációt kínál a Test::Unit-hoz, amelyrÅ‘l a www.ruby-doc.org címen is találhatsz infókat. A rake-rÅ‘l ebben az IBM Developerworks cikkemben olvashatsz, valamint Martin Fowler cikkében.

Ha még nem használod a Test::Unit-ot és a rake-t, szánj egy kis időt ezen kiváló eszközök tanulmányozására. A Test::Unit a Ruby része, míg a rake letölthető a RubyForge oldalról.

A többi csomagról is ejtenék néhány szót: Az rcov egy kódlefedettség-vizsgáló eszköz. Egy testsuite-ra lefuttatva kigenerálja a kód tesztek általi lefedettségét. Az rcov az eigenclass.org címrÅ‘l tölthetÅ‘ le. LehetÅ‘ség van HTML kimenet – lásd a példát itt – valamint ASCII kimenet generálására. Az utóbbi lehetÅ‘ség illusztrálására lásd az alábbi (rövidített) példát. Az rcov relatíve gyorsan működik – ugyanazon program lefuttatása rcov analízissel csak kétszeresére, legfeljebb háromszorosára növeli a futtatás idejét, és ezért hasznos eredményeket kapunk cserébe.


class MockDB                                                          |      2
                                                                      |      0
  def exec(query, &block)                                             |     11

    case query.split(' ')[3]                                          |      5
    when 'zero'                                                       |      5

      num = 0                                                         |      1
    when 'one'                                                        |      4

      num = 1                                                         |      1
    else                                                              |      0

      num = 2                                                         |      3
    end                                                               |      0

                                                                      |      0
    yield [num]                                                       |      5
                                                                      |      0

  end                                                                 |      0
                                                                      |      0
end      
                                                                      |      0

Az rcov futtatása egy testsuite-ra így történik:

$ rcov test/test_hostname

Egyéb érdekes parancssor-kapcsolók többek között:

  • -t: csak szöveges kimenet
  • -T: felturbózott szöveges kimenet
  • -p: profiling kimenet generálása
  • -x: egyes fájlnevek kihagyása – vesszÅ‘vel elválasztott reguláris kifejezések megadásával
  • –no-html: HTML állományokat generálásának megtiltása

Ha a csak szöveges kimenet mellet döntesz, ajánlott átirányítani az eredményt egy állományba. A másik lehetÅ‘ség a tee használata – az rcov kimenete nagyon hosszú tud lenni.

Alapvetőleg a tesztlefedettség-ellenőrző eszközök ara mutatnak rá, hogy mely programrészekre kéne több tesztet írni, gyakorlatban más területen is hasznosak tudnak lenni: nemrégiben volt egy esetem amikor az rcov hozzásegített a kód refactoringjához. Néhány órája egy hosztnév ellenőrző programon dolgoztam tesztvezérelt módszerrel, és írtam jó néhány tesztet. Úgy gondoltam ideje egy kicsit felhagyni a kódolással és ellenőrizni a lefedettséget. Az volt a tippem, hogy 100%-os lefedettséget értem el a tesztjeimmel, de azért meg szerettem volna erről győződni. Elindítottam az rcov-ot, és csodálkozva vettem tudomásul a piros csíkot a zöld mező végén: némely dolgok nem voltak tesztelve!

Elkezdtem bogarászni a kódot és a teszteket. Láttam hogy hol történik a hibás eset tesztelése, de az rcov nem és nem akart ráakadni. Kiderült, hogy egy később beiktatott teszt duplán ellenőrizte a problémát, ezért a hiba már hamarabb el lett kapva. A felesleges résztől való megválás után az rcovnak köszönhetően a programom 1 felesleges metódussal rövidült.

Az rcov jelenlegi verziójában van egy kisebb hiba amire megéri odafigyelni: nevezetesen a program nem veszi figyelembe a folytatódó sort “and” és “or” kifejezések után. Szerencsére ez csak egy gyors javítást igénylÅ‘ probléma, és bele fog kerülni az rcov következÅ‘ verziójába.

A többi eszközről is ejtenék néhány szót. Az auotest és az unit_test programok a ZenTest csomagban kerülnek forgalomba, és a folyamatos tesztelés mindennapos használatának megkönnyítését teszik lehetővé. A ZenTest csomagot rubygem-ként telepíthetjük fel.

Az autotest feltételezi hogy kódunk a ./lib, míg tesztjeink a ./test könyvtárban laknak. Lefuttatva végrehajtja a teszteket majd kijelzi az eredményt. Az autotest igazi előnye abban rejlik, hogy a tesztekhez hozzárendeli a megfelelő állományokat, osztályokat és metódusokat. Minden alkalommal ha egy új állomány kerül bele ebbe a listába, a tesztek újrafuttatásra kerülnek. Ha bármely teszt hibát jelez, az autotest egy szűkebb körű vizsgálatba kezd, csak a problémás teszteket végrehajtva. Ez lehetővé teszi a hibát jelző kód szinte azonnali felfedezését és annak kijavítását.

Néhány órámba került míg megszoktam az autotest használatát. Először kis dolgokkal kezdtem, ami azért volt jó, mert az autotestnek nem volt ideje átmennie az összes változáson és lefuttatni az összes tesztet, ámbár erre is van mód: a CTRL-C billentyű-kombináció azonnal újraindítja a tesztelést, kétszer lenyomva pedig megszakítja azt.

Az autotest egyik tulajdonsága hogy nem kedveli ha a tesztek nem futnak le. A tesztvezérelt fejlesztési ciklus elején nem létezÅ‘ implementációs állományokra is szoktam hivatkozni. ‘Normális’ fejlesztés esetén hajlamos vagyok elírni dolgokat vagy szintaktikus hibákat ejteni. Az imént felsoroltak bármelyike autotest használata esetén a következÅ‘ figyelmeztetést eredményezi:

# Test::Unit died, you did a really bad thing, retrying in 10

Ez a hibaüzenet nem használ ugyan az egónknak, de segít a helyes úton haladni.

Még egy utolsó szépséghiba: az autotest nem szereti az Emacs által generált autosave állományokat, és akárhányszor egy ilyen állományba botlik, összedől. A következő verzióban várható a probléma orvoslása.

A következő egyszerű de nagyszerű program a unit_diff: egy hibát jelző teszt esetén a remélt és a tényleges eredményeket összehasonlítja diff segítségével, ezáltal segítve a rengeteg kimeneti jelentésből kiszűrni a fontos dolgokat. Az unit_diff alkotója, Eric Hodel a ParseTree csomag fejlesztés közben használta, ahol egy-egy hibát jelentő teszt több képernyős, nehezen értelmezhető hibaüzenetet eredményezett. Az unit_diff segítségével sikerült ezt a rémálmot két-három soros releváns hibaüzenetté redukálni. Nagyon hasznosnak találtam XML kimenettel való munka esetén is.

Az unit_diff futtatása szintén egyszerű:

$ ruby test/test_hostname |unit_diff

A megtalált hibák feldolgozásra, majd a lényeges részek kiíratásra kerülnek.

The Rubylation Network

28 thoughts on “Tesztvezérelt trükkösláda

  1. I don’t know if I can totally agree on this one, after getting the fleshlight forbidden that I seen on fleshlighteurope.eu I don’t think any other masturbator can come close to a fleshlight – and that is after using other good masturbators like the Tenga Egg. But I still must say none of these can compare to a fleshlight – No question about it,, it beats the hell out of many other fake pussies!

  2. Oh mу goodness! Amazing аrticle dude!
    Thank уou so much, However I am having ρroblems
    with your RЅS. I ԁon’t understand the reason why I am unable to subscribe to it. Is there anyone else getting similar RSS issues? Anyone that knows the solution can you kindly respond? Thanx!!

    Feel free to surf to my homepage … pussy site

Leave a Reply

Your email address will not be published. Required fields are marked *