"Elgsena paremtas" programavimas(angl. Behaviour Driven Development). III dalis.

Posted by Saulius Grigaitis 06/07/2007 at 22h29

Sveiki. Pagaliau baigėsi bakalauriniai, stojamieji ir visi kiti akademiniai reikalai, tad dažniau rašysiu straipsnius. Šį kartą tęsiu pažintį su RSpec ir kontrolerių testavimu. Kontrolerių testavimo techninė dalis yra analogiška jau aptartoms dalims, bei turi keletą naujų dalykų, tačiau koncepciniai dalykai daug įdomesni. Juos ir aptarsiu šiame straipsnyje.

Visų pirma - RSpec'as propaguoja ne klasikinį testavimą, o "mock'inimą". Klasikiniame testavime visi testai surišti tarpusavyje panaudojant kiek galima tikrų objetų, o netikri objektai("mocks", "stubs" ir kita) yra naudojami tik tada, kai nėra kitos galimybės, pvz. dar neturint priėjimo prie WEB serviso, nes jis dar nesukurtas, bet turint jo API, bei darant prielaidą, kad servisas tikrai veiks korektiškai naudojantis pateiktu API. Tuo tarpu "Mock'istai" naudoja netikrus objektus kur tik gali ir tai turi prasmę. Iš esmės tai yra visiškai skirtingos koncepcijos, turinčios savo privalumų ir trūkumų. Pagrindiniai skirtumai yra testų integracija ir programavimo stilius. Klasikiniai testuotojai rašo testus, kurie surišti tarpusavyje, o "mock'istų" testai dažniausiai visiškai nepriklauso vienas nuo kito, tad klasikinių testuotojų testai yra integraciniai, o "mock'istų" - ne. Pvz. klasikinis testuotojas rašydamas kontrolerio testą nusprendžia, kad jam reikia naujo modelio "Book" klasės metodo "pages", jam nelieka nieko kito, kaip imti ir parašyti "Book" klasės metodo "pages" testą ir tada patį metodą "pages", geriausiu atveju - paprašyti kolegos, kad jis tai padarytų:). Gal viskas tuo gerai baigtųsi, jei nepaaiškėtu, kad "pages" metodui reikia dar kito metodo, kuris dar neparašytas, o kolega jau ir taip užimtas:). Taigi Klasikinis testuotojas norėjo parašyti kontrolerio testą ir patį kontrolerį, bet jam teko įsivelti į modelių metodų rašymą. Dažnai šita grandinė išauga iki įspūdingo ilgio. Tuo tarpu "mock'istas" daro prielaidą, kad modelis turi reikiamą metodą ar jį turės ir pasitiki jo veikimo korektiškumu, nes to metodo autorius jį jau ištestavo. Naudojant RSpec, tai atrodytų taip:

...
@book = mock_model("book")
@book.should_receive(:pages).and_return(100)
...
toks testas praeis sėkmingai net jei "Book" klasė ir neturės metodo "pages", tačiau programuotojas gali susikoncentruoti ir galvoti kaip geriau parašyti testą ir patį kontrolerį, o ne šokinėti prie kitų programos dalių.

Iš vienos pusės "mock'istams" lengviau programuoti, tačiau jie praranda testų integraciją, o klasikinimas testuotojams programuoti žymiai sunkiau, tačiau jie turi didesnę kodo kontrolę, nes integruoti testai geriau indikuoja pažeistas vietas po kodo pakeitimų. Klasikiniams testuotojams yra kur kas sunkiau programuoti didesnėse komandose lygiagrečiai, tuo tarpu "mock'istams" tai nedaro įtakos. Tačiau praktikoje kartais "mock'istams" sunku imituoti sudėtingų objektų elgseną, tad priveliama klaidų į pačius testus. Abi technikos turi savų pliusų ir minusų, jei dar neapsisprendei kuri tau tinkamesnė, paskaityk:

Martin Fowler - Mocks Aren't Stubs

RSpec Documentation - Mocks

Iki!

no comments | no trackbacks

Comments

Trackbacks

Use the following link to trackback from your own site:
http://www.rubyonrails.lt/trackbacks?article_id=17

(leave url/email »)

reCaptcha

   Comment Markup Help Preview comment