story runner & rspec käytännössä

0 views
Skip to first unread message

pirkka

unread,
Feb 13, 2008, 3:43:02 AM2/13/08
to Ruby on Rails: Finnish
Terve,

eilen oli hauska dojo Tampereella rspecin parissa. Dojossa ei tehty
Railsia mutta käytetyt BDD-tekniikat liittyvät tietysti Railsiin.

Tuntuu että storyjen käyttötavoissa löytyy enemmän vaihtelua kuin
specien puolella. Dan North käyttää storyjä usean modelin keskinäisen
toiminnan testaamiseen eli ei varsinaisesti tee Rails-hommaa
ollenkaan. Pat Maddoxin blogissa tarinoissa speksataan esimerkiksi
mitä näkymiä sovelluksia sovelluksen pitäisi renderöidä missäkin
vaiheessa tarinaa välittämättä siitä mitä näissä vieweissä itseasiassa
näkyy. Jarkon brigade-esityksessä webrat puolestaan testasi näkymien
sisältöä ja linkkejä välittämättä siitä mitä "konepellin alla"
tapahtuu eli muistuttaa lähinnä perinteistä (selaimella tapahtuvaa)
hyväksymisteustausta.

Itselläni on aika heikko tausta model speccien puolella, ja nyt kun
olen kirjoittanut muutaman päivän tarinoita olen mietisekellyt että
missä vaiheesssa storyjen puolelta hypätään kirjoittamaan model, view
ja controller -speksejä. Sovellusta voi nimittäin kehittää
kirjoittamatta näitä alemman tason speccejä ollenkaan, mutta
tietenkään se ei kuulosta kovin hyvältä idealta:

1. failing story step
2. write code
3. passing story step
4. refactor
5. non-pending stories pass
6. goto 1.

Eilisen dojon perusteella voisi ajatella työvuota jossa:

1. merkataan yksi storyn askel pois pending-tilasta (käytännössä vain
kirjoitetaan puuttuva step, jos käytössä plain text storyt - nice!)
2. kirjoitetaan m/v/c speccejä ja laitetaan ne menemään läpi kunnes...
3. storyn askel menee läpi
4. kaikki menee läpi
5. refactor
6. takasin kohtaan 1. jos jotain on pending
7. ?
8. profit

Luulisin että itselleni seuraava steppi on opetella kirjoittamaan
järkeviä m, v & c spekkejä. Eipä se mitään ydinfysiikkaa ole, mutta
kyllähän tuossa pääsi eteenpäin pelkillä storyilläkin. :D :D :D View-
ja model spekkejä on tullut jo vähän kirjoiteltuakin, ja veikkaisin
että kontrollerien spekeistä tulee aika laihoja käytännössä.

Storyjen käyttö on uusinta uutta, eli olis hauska kuulla ihmisten
kokemuksia niiden käytöstä tässä ketjussa. Muutenkin olis hauska saada
tähän foorumiin enemmän keskustelua, kun suomenkielistä rails-porukkaa
kuitenkin tuntuu riittävän jonkin verran.

Ps. ainakin toi nykyisen duunin projektipäällikkö tykkäili noista
tarinoista koska luonnollinen kieli tuntuu helpottavan sovelluksen
toiminnan "visualisointia" suunnitteluvaiheessa verrattuna muihin
suunnittelumenetelmiin... sain jo palautettakin sovelluksen
toimintalogiikasta niiden avulla.

Edvard Majakari

unread,
Feb 13, 2008, 3:21:16 PM2/13/08
to finnis...@googlegroups.com
Heip,

Minustakin dojo oli mainio. Lisää jäi kaipaamaan, varsinkin kun
aloimme juuri päässeet kunnolla vauhtiin, kun aika jo loppui.

> eilen oli hauska dojo Tampereella rspecin parissa. Dojossa ei tehty
> Railsia mutta käytetyt BDD-tekniikat liittyvät tietysti Railsiin.

Sinänsä eiliset tekniikat eivät muistaakseni liittyneet mitenkään
Railsiin erityisesti, olkoonkin, että sekä StoryRunner ja RSpec ovat
molemmat hyvin suosittuja noissa ympyröissä. Käsitin ehkä väärin,
mutta siis mitenkään Rails-spesifistä eilinen koodi ei ollut.

Tarinoiden (stories) ja speksien/yksikkötestien erosta: on totta, että
pelkillä tarinoilla voisi periaatteessa pärjätä. Testaamisesta tulisi
tosin vaikeampaa ja hitaampaa, koska tarinoissa joutuu usein
kirjoittamaan enemmän kontekstia, jotta halutun tilanteen voi testata.
Hitaus taas tulee erityisesti siitä, että koska mitään olioita ei
mockata/stubata[1], niin viestit menevät raskaiden alijärjestelmien
lävitse (Rails), tehdään levy-IO:ta, lähetetään sanomia verkon yli
yms.

Mutta on väärin, _just plain wrong_ puhua testaamisesta tai
testikattavuudesta. Se ei ole lainkaan BDD:n tai TDD:n idea, vaan se,
että testien(=speksien!) kirjoittaminen auttaa ajattelemaan sitä,
miten toteutus tulisi tehdä. Ja juuri siinä integrointitestit tai
tarinat auttavat yleensä varsin vähän, koska ne ovat usein
seuraavanlaisia:

...
report = Report.build_from_form_params(params)
report.subfrobnications.should == 42
...

Report.build_from_form_params ei kerro lainkaan, miten
yksinkertaisista avain-arvopareista luodaan mutkikas raportti, jossa
voi olla vaikka mitä analyysejä. Eikä sen kuulukaan näkyä tarinoissa:
siellä kiinnostaa lopputulos, ei miten se saadaan aikaan. Mutta TDD:n
ja BDD:n suurin anti on nimenomaan eri olioiden välisessä viestinnässä
eli käyttäytymisessä; sitä on BDD:n _behaviour_. Lopputulos ei ole
niin kiinnostava, koska se ei opeta meille useinkaan mitään.
Englanniksi keskeinen termi on "interface discovery[2]". BDD:ssä
mock-oliot ovat keskeisessä roolissa, koska niillä kirjoitetaan
odotukset sille, miten speksattava olio viestii ympäristönsä kanssa.
Speksattavaa oliota itseään ei kuitenkaan mockata (tätä sääntöä saa
IMO rikkoa, mutta sitten vasta kun osaa ja ymmärtää säännöt) vaan ne
oliot, joiden kanssa olio viestii. Toisin sanoen silloin kun
kuvittelemme vain kirjoittavamme mukavia mock-odotuksia ja stubeja,
suunnitelemme itse asiassa speksattavan olion kanssa viestivien
olioiden rajapinnan. Ja nyt ao. rajapinta tulee toteutettua sen
mukaan, millaisia rooleja oliolta edellytetään (outside in) sen
sijaan, että meillä olisi ensiksi sopivan tuntuinen rajapinta ja
sitten miettisimme miten sitä käyttämällä jokin joukko palveluita
voidaan toteuttaa (inside out).

Viitteistä: [2] kannattanee lukea ajatuksella läpi ainakin kaksi
kertaa siten, että lukukertojen välillä on väliä. Itselleni
keskeisin ajatus (eli se mitä otsikko sanoo) valkeni kunnolla vasta
toisella kerralla. YMMV.

[1] Mocks Aren't Stubs: http://martinfowler.com/articles/mocksArentStubs.html
[2] Mock Roles, not Objects: http://www.jmock.org/oopsla2004.pdf

PS. TDD/BDD auttaa toki testauksessa sikäli, että sattuneesta syystä
olioiden testattavuus paranee huomattavasti, ja toisaalta myös
kaikille ominaisuuksille tulee kirjoitettua vähintään yksi testi,
jolloin saadaan hyvä alustava testipeite (testausta BDD ei kuitenkaan
korvaa, eikä sen ole tarkoituskaan).

PPS. inside out ei ole aina huono vaihtoehto. Esim.
ohjelmistokirjastoissa voisi kuvitella, että rajapinnasta saadaan
puhtaampi ja intuitiivisempi tekemällä siitä mahdollisimman
ortogonaalinen ja siisti -- tavoite, johon on vaikea päästä jos ko.
olioilta vaadittuja rooleja käytetään vain tietyssä asiayhteydessä
yhdessä sovelluksessa. Mutta hyvien kirjastojen tekeminen onkin wanhan
sanonnan mukaan 3x vaikeampaa kuin sovellusohjelmien.

--
"One day, when he was naughty, Mr Bunnsy looked over the hedge into
Farmer Fred's field and it was full of fresh green lettuces. Mr
Bunnsy, however, was not full of lettuces. This did not seem fair."
-- Terry Pratchett, Mr. Bunnsy Has An Adventure

Jarkko Laine

unread,
Feb 13, 2008, 3:44:18 PM2/13/08
to finnis...@googlegroups.com
On 13.2.2008, at 22.21, Edvard Majakari wrote:
> Mutta on väärin, _just plain wrong_ puhua testaamisesta tai
> testikattavuudesta. Se ei ole lainkaan BDD:n tai TDD:n idea, vaan se,
> että testien(=speksien!) kirjoittaminen auttaa ajattelemaan sitä,
> miten toteutus tulisi tehdä.

Ja erityisesti BDD on prosessi, outside in, jossa ulomman kerroksen
speksaaminen mock-olioiden avulla auttaa alemman kerroksen luokkien
rajapinnan kehittämisessä.

Railsin kanssa tämä on suhteellisen suoraviivaista:

1) Valitse tärkein ominaisuus, joka järjestelmässä on toteutettava.
2) Kirjoita tälle ominaisuudelle user story.
3) Toteuta storyn ensimmäinen askel => FAIL
4) Kirjoita askeleen vaatima view spec => FAIL
5) Toteuta näkymään askeleen vaatima toiminnallisuus => view spec
menee läpi, storyn steppi (ehkä) edelleen FAIL
5b) Refaktoroi näkymää tarpeen mukaan. Tämä saattaa vaatia
toiminnallisuuden siirtämistä helpereihin (ja niiden speksaamista).
6) Kirjoita askeleen vaatimalle controller-toiminnolle speksi.
Rajapinta toiminnolle saadaan siitä, mitä näkymän speksissä on
jouduttu mockaamaan.
7) Toteuta toiminnallisuus controlleriin niin, että askeleen vaatimat
controller-speksit menevät läpi.
7b) Refaktoroi
8) Kirjoita askeleessa käytettäville ActiveRecord-luokille speksit,
joiden avulla ne toteuttavat kohdissa 4 ja 6 mockatut rajapinnat.
9) Toteuta edellisen kohdan speksit toteuttava toiminnallisuus.
9b) Refaktoroi tarpeen mukaan.
10) palaa kohtaan kolme ja seuraavaan askeleeseen.

Lisähuomioita:
* kohdat 4-5b, 6-7b ja 8-9b ovat periaatteessa perinteisiä TDD-
iteraatioita.
* joissain askeleissa kohdasta 5 (tai 7) voidaan hypätä suoraan
takaisin kohtaan 3, koska askeleen toteuttaminen vaatii vain muutoksia
näkymään (+ kontrolleriin).
* Olen huomannut, että yo. prosessi auttaa pitämään kontrollerit
laihoina ja siirtämään toiminnallisuutta enemmän Model-tasolle (mikä
on hyvä asia), koska se helpottaa merkittävästi kontrollerien
speksaamista. Eli jos kontrollereja speksatessa tuntuu, että joutuu
tekemään spekseihin oudontuntuisia kiertoteitä ja mockeja, se on usein
merkki siitä, että kontrollerissa on bisneslogiikkaa, joka kuuluu
Model-tasolle.

--
Jarkko Laine
http://jlaine.net
http://dotherightthing.com
http://www.railsecommerce.com
http://odesign.fi


Pirkka Hartikainen

unread,
Feb 13, 2008, 4:35:35 PM2/13/08
to finnis...@googlegroups.com
Jeah, tiistain dojo ei siis liittynyt suoranaisesti Railsiin, mutta
koska tää on Rails -foorumi koin tarpeelliseksi perustella miksi
asiasta täällä messuilen. En keksinyt parempaakaan foorumia, ja
lisäksi ainakin itse kaipaisin tänne (tai johonkin muulle
suomenkieliselle ruby/rails -foorumille) lisää aktiivisutta.

Toi Jarkon "prosessikuvaus" vaikuttaa juuri siltä mitä olen tässä
ollut hakemassa Railsin kanssa devaamiseen. En tiedä sitten tekeekö
muut täällä järjestyksessä V->C->M tai kenties toisin päin, mutta
omaan tarinapohjaiseen lähestymistapaan toi tuntuu järkevältä.

Antti Tarvainen

unread,
Feb 14, 2008, 3:31:50 AM2/14/08
to finnis...@googlegroups.com
Moi.

Kiitos kaikille dojo-kävijöille! Se, että tällaiseen sessioon tulee
junamatkan päästä ihmisiä, antaa potkua samanlaisten tempausten
tekemiseen jatkossakin.

BDD-prosessikysymyksessä olen samaa mieltä Edin ja Jarkon kanssa. Tätä
kohtaa Edin kirjoituksessa en kuitenkaan ihan ymmärtänyt:

> [Tarinoissa] kiinnostaa lopputulos, ei miten se saadaan aikaan.


> Mutta TDD:n ja BDD:n suurin anti on nimenomaan eri olioiden
> välisessä viestinnässä eli käyttäytymisessä; sitä on BDD:n
> _behaviour_. Lopputulos ei ole niin kiinnostava, koska se ei opeta
> meille useinkaan mitään.

Kyse on kai siitä, mitä BDD tarkoittaa. Ed taitaa ajatella määritelmää
"BDD is TDD done right." joka on tietenkin oikein, koska sitä
kaikkialla toistetaan. Itse olen kuitenkin mm. Jarkon puheiden
seurauksena alkanut ajatella, että BDD takoittaa lisäksi sitä koko
prosessia, jolla korkean tason vaatimuksista saadaan integrointi- ja
yksikkötestien kautta toimivaa koodia.

Mun mielestä asiat kasvavat tärkeysjärjestyksessä kun mennään
lähemmäksi asiakasta. Tarinat ovat siksi kaikista tärkeimpiä, ja koko
muu prosessi tuottaa tavallaan vain teknisiä päätöksiä.

Vaikka model on kaikista sisimpänä, sen speksit ovat mun mielestä
tärkeimmät yksikköspeksit. Model on nimittäin asiakasta lähellä
toisella tavalla: sovellusalueen ymmärtäminen tulee yleensä
asiakkaalta ja hyvä model pyrkii kuvaamaan sovellusaluetta
mahdollisimman tarkasti.


Disclaimer: Toisin kuin Jarkko ja Ed, mä pystyn käyttämään
päivittäisessä työssäni BDD:tä aika harvoin.


Antti T.

Edvard Majakari

unread,
Feb 14, 2008, 4:33:03 AM2/14/08
to finnis...@googlegroups.com
Mui,

> Kiitos kaikille dojo-kävijöille! Se, että tällaiseen sessioon tulee
> junamatkan päästä ihmisiä, antaa potkua samanlaisten tempausten
> tekemiseen jatkossakin.

Kyllä :)

> > Mutta TDD:n ja BDD:n suurin anti on nimenomaan eri olioiden
> > välisessä viestinnässä eli käyttäytymisessä; sitä on BDD:n
> > _behaviour_. Lopputulos ei ole niin kiinnostava, koska se ei opeta
> > meille useinkaan mitään.

> Kyse on kai siitä, mitä BDD tarkoittaa. Ed taitaa ajatella määritelmää
> "BDD is TDD done right." joka on tietenkin oikein, koska sitä
> kaikkialla toistetaan. Itse olen kuitenkin mm. Jarkon puheiden

Siksi tuo "...suurin anti". Superlatiivin käyttö on ehkä liioittelua,
koska muuten BDD:n näkökulma jää liian suppeaksi.
Antin viittaama korkean tason prosessiajattelu jää kuitenkin usein
BDD:ssä huomiotta, joten huomautus oli paikallaan.

> Mun mielestä asiat kasvavat tärkeysjärjestyksessä kun mennään
> lähemmäksi asiakasta. Tarinat ovat siksi kaikista tärkeimpiä, ja koko
> muu prosessi tuottaa tavallaan vain teknisiä päätöksiä.

No siinä mielessä kyllä. Eli kyse on siitä, ajatellaanko BDD:tä prosessi- vai
suunnittelumenetelmänä (oikeasti se kai on kumpaakin).

> Disclaimer: Toisin kuin Jarkko ja Ed, mä pystyn käyttämään
> päivittäisessä työssäni BDD:tä aika harvoin.

No joo, mutta olet tehnyt sitä yhteenlaskien enemmän kuin minä :)
Janyssehommaloppuuumultakingngngngnn.

Reply all
Reply to author
Forward
0 new messages