Finalist

Finalist Developers Blog

Ruby/Scrum volgens Finalist – de ontwikkelaar

2 March 2009 17:51 · Iain Hecker · Methodieken, Ruby, Scrum, Testen

Deze maand plaatsen we op de Finalist developer blog een serie over Ruby en scrum die vanuit vier verschillende rollen wordt beleefd. Vandaag geeft Iain zijn visie op Ruby/ Scrum volgens de ontwikkelaar:

Ik hou van Scrum. Zo, dat is er uit. Ik ben een van die programmeurs die liever niet eindeloos vergadert en interviewt over hoe iets moet gaan werken. Ik krijg liever een korte instructie, ik bouw wat en laat dat zien. Mijn eerste ingeving is zelden gelijk naar wens, dus ik krijg feedback over wat ik gebouwd heb en verwerk dat weer. Zo komen we samen dichter bij het eindproduct. Ik houd er niet van om de gehele dag alleen maar te praten. Ik wil zo snel mogelijk mijn handen vuil maken en aan het werk. Effectief biedt scrum je evenveel overleg als de wat traditionelere projectaanpakken, maar meer verspreid, waardoor het wat beter uit te houden is.

In dit artikel wil ik een mogelijkheid aandragen om de momenten van overleg effectiever te maken. En als technische jongen kom ik met een stuk techniek om daarin te helpen. We zijn al bekend met technieken zoals Ruby on Rails die ons helpen met het snel inzichtelijk maken van wat er gebouwd wordt en het opvangen van veranderende wensen die de Scrum aanpak met zich meebrengt. Ik ga het daarom hebben over een ander onderdeel van het project: de communicatie tussen de klant en de ontwikkelaars. Iets wat van nature niet altijd even soepel gaat.

Communicatieproblemen

Van nature is er een communicatieprobleem tussen de klant en de ontwikkelaar. De klant is een expert in haar domein en weet waar ze over praat. Ze heeft een bepaald idee hoe een applicatie haar kan helpen met een probleem in de business waar ze in zit en kan daar goed de ins en outs van uitleggen.

De ontwikkelaar is expert in het domein van het maken van applicaties. In het geval van webapplicaties, waar ik het in het vervolg uitsluitend over ga hebben, weet de ontwikkelaar wat een webserver kan, wat een browser kan en wat zijn tools kunnen. De ontwikkelaar weet alleen niks van wat de klant doet. Door de kennis die een ontwikkelaar bezit over webapplicaties zal hij ook andere dingen verwachten van het op te leveren product dan de klant. En eerlijk is eerlijk, ontwikkelaars zijn nerds. Alhoewel dat niet per definitie betekent dat ze sociaal gestoord zijn, betekent dat wel dat ze problemen op andere manieren uitleggen en begrijpen dan mensen zonder programmeerervaring. Het is een hele kunst om ontwikkelaar en klant met de spreekwoordelijke neus dezelfde kant op te krijgen.

Features

Hoe dicht je het gat tussen de klant en de ontwikkelaar? Er zijn daar in de loop der jaren vele manieren voor verzonnen. Veelal in de vorm van schema’s en diagrammen. Scrum gaat uit van Features en User Stories. Laten we eerst eens beginnen met features. Een voorbeeld van een feature kan zijn het hebben van accounts op de webapplicatie. Maar wat moeten we er mee? Waarom moeten we inloggen? Er is daarom voor features een vast formaat bedacht. Een feature moet in dit formaat drie regels bevatten: een doel, een gebruiker, en uiteindelijk ook wat de actie werkelijk is. Deze drie elementen zijn het minimaal vereiste om vast te leggen wat een bepaalde functionaliteit moet doen.

Om zo’n feature makkelijk te beschrijven is het handig om een vast stramien te hanteren.

    Met als doel de gegevens prive te houden
    zal ik, als een werknemer van mijn bedrijf
    een account moeten maken en daarmee moeten inloggen.

Zoals je ziet is elke regel een van dit voorbeeld een van de onderdelen van zo’n feature. De eerste regel is het doel, de tweede regel wie geraakt wordt door dat doel en de derde regel de uiteindelijke beschrijving. Ik heb in dit voorbeeld “met als doel” en “ik, als” vetgedrukt. Deze onderdelen zijn verplicht in een feature-beschrijving. Het onderdeel “met als doel” is namelijk cruciaal voor zowel de klant als de ontwikkelaar. Het onderdeel “ik, als” is er om ervoor te zorgen dat je in de rol komt van degene die het moet doen. Als je je inleeft in de gebruiker, zal hetgeen je maakt beter aansluiten op zijn/haar wensen.

Helaas is zo’n beschrijving nog te vaag. We weten nu wat het doel is van de functionaliteit die we willen bouwen, maar we weten nog niet hoe die er uit moet zien. Daarvoor zijn er User Stories.

User Stories

Een user story is een verhaal van de gebruiker en wat hij of zij doet. Het aardige van user stories is dat het de klant helpt te praten naar de taal van de ontwikkelaar en het helpt de ontwikkelaar om beter te begrijpen wat de klant bedoelt. Een user story wordt ook wel “scenario” genoemd.

Een user story heeft 3 onderdelen, vergelijkbaar met een use case. Het begint met een set voorwaarden, gevolgd door een set acties en het eindigt met een set verwachtingen. Laten we kijken naar een voorbeeld. Stel de klant wil in kunnen loggen op de webapplicatie, dan zou een van de user stories die daar bij horen kunnen zijn:

  Gegeven het feit dat ik een account heb met de inlognaam "iain" en wachtwoord "geheim"
  Als ik de inlogpagina bezoek
  En ik bij het veld "inlognaam" de waarde "iain" invul
  En ik bij het veld "wachtwoord" de waarde "geheim" invul
  En ik druk op de knop "inloggen"
  Dan zie ik "welkom iain!"

Laten we deze user story gaan ontleden. De eerste regel bevat de voorwaarden. De volgende vier regels zijn de actie en de laatste regel is de verwachting. Om aan te geven welk deel het is, beginnen we de voorwaarden met het woord “Gegeven“, de acties met het woord “Als” en de verwachtingen met het woord “Dan“. Opeenvolgende voorwaarden, acties en verwachtingen beginnen met het woord “En“. Er kunnen dus meerdere voorwaarden, acties en verwachtingen zijn.

Voor de bovengenoemde feature zijn natuurlijk meer user stories te bedenken, zoals het uitloggen, het aanmaken van een account, het resetten van een wachtwoord, etc. Dit laat ik als oefening voor de lezer over.

Het valt je misschien op dat de user story in de eerste persoon enkelvoud is geschreven. Dat deden we ook al bij de feature die hierboven beschreven staat. Weer een hulpmiddel om er voor te zorgen dat we ons inleven in de gebruiker.

Het mooie van User Stories is dat we nu meetbaar hebben gemaakt wat er verwacht wordt van de op te leveren feature. Tijdens de sprintplanning worden deze stories opgezet door klant en ontwikkelaar samen. Het is de opdracht voor de klant om op deze manier de wens duidelijk te maken aan de ontwikkelaar en de opdracht voor de ontwikkelaar om aan te geven of het duidelijk is en het vervolgens te gaan bouwen. Deze User Stories zijn als het ware een mini-contract voor een bepaalde feature.

Ook zie je aan het voorbeeld dat maken van een account eerst gemaakt moet worden, voordat er ingelogd kan worden. We brengen nu heel mooi in kaart in welke volgorde er gebouwd moet worden. Verder is dit ook gelijk een testscript. Je kan stap voor stap doorlopen en kijken of een bepaalde actie werkt. Als je alle user stories op een rij zet, kan je zo de gehele applicatie bekijken.

Komkommertijd

Nu zal je vast denken: “Zijn ontwikkelaars echt zo dom dat we ze in zulke elementair bewoordingen de functionaliteit moeten uitleggen?” Wellicht in het voorbeeld van inloggen niet, omdat dat een redelijk bekende functionaliteit is. “En het gebruik van de vaste woorden en zinsopbouw, moet dat allemaal?” Ze zijn er om ervoor te zorgen dat alle onderdelen afgedekt zijn en dat duidelijk is wat er nodig is voordat een functionaliteit geschreven kan woorden.

Maar er is nog een andere reden. Deze reden heet “Cucumber“. Cucumber is een testtool om te kijken of de stappen die in een user story zijn opgenomen gemaakt zijn en naar verwachting werken. Cucumber gaat uit van de steekwoorden “Gegeven“, “Als“, “Dan” en “En” en roept daarmee bepaalde scripts aan. De ontwikkelaar kan deze stappen in programmacode vervolgens definiëren. Daarom lag er al die nadruk op welke woorden er gebruikt werden.

In Cucumber wordt er per feature een bestand (bijvoorbeeld “accounts.feature“) gemaakt voor de feature en de user stories die daar bij horen. Zo’n bestand ziet er dus als volgt uit:

  Functionaliteit: De applicatie moet beveiligd worden met accounts
    Met als doel de gegevens prive te houden
    zal ik, als een werknemer van mijn bedrijf
    een account moeten maken en daarmee moeten inloggen.
 
    Scenario: Inloggen
      Gegeven het feit dat ik een account heb met de inlognaam "iain" en wachtwoord "geheim"
      Als ik de inlogpagina bezoek
      En ik bij het veld "inlognaam" de waarde "iain" invul
      En ik bij het veld "wachtwoord" de waarde "geheim" invul
      En ik druk op de knop "inloggen"
      Dan zie ik "welkom iain!"
 
    Scenario: Uitloggen
      Gegeven ...
 
    Scenario: Een account maken
      Gegeven ...
 
    Scenario: Een vergeten wachtwoord resetten
      Gegeven ...

Bijvoorbeeld de eerste stap: “Gegeven het feit dat ik een account heb”, betekent dat om deze stap te laten slagen er een gebruiker in de database moet worden gezet. Dat ziet er dan zo uit:

  Gegeven /^het feit dat ik een account heb met de inlognaam "(.+)" en het wachtwoord "(.+)"$/ do |inlognaam, wachtwoord|
    User.create! :login =>; inlognaam, :password =>; wachtwoord
  end

Dit is feitelijk een stuk Ruby code. De eerste regel is hier de stapdefinitie. Het begint ook met Gegeven, zodat Cucumber weet dat dit een voorwaarde is (of deze nou begint met Gegeven of En maakt niet uit). Dan volgt er een “regular expression“, een stuk tekst waar de inlognaam en wachtwoord eruit worden gefilterd en aan de gelijknamige variabelen worden toegewezen. De tweede regel doet wat met die waarden, namelijk het maken van een gebruiker met de opgegeven inlognaam en wachtwoord. De derde regel markeert het einde van deze stapdefinitie.

Een actie geeft opdrachten op de pagina. Je kan velden invullen, op knoppen drukken, op links klikken, pagina’s openen en nog veel meer. De volgende stapdefinitie is te gebruiken voor meedere stappen en de code spreekt voor zichzelf.

  Als /^ik bij het veld "(.+)" de waarde "(.+)" invul$/ do |veld, waarde|
    fill_in veld, :with =>; waarde
  end

Een verwachting is een stuk testcode. Het volgende voorbeeld van een stapdefinitie kijkt of de tekst voorkomt op een pagina:

  Dan /^zie ik "(.+)"$/ do |tekst|
    response.body.should include(tekst)
  end

Als je vervolgens aan Cucumber de opdracht geeft om te starten, wordt er een mini-browser (genaamd webrat) gestart en worden de user stories doorlopen. Vervolgens krijg je een overzicht van de de user stories waarin elke regel gekleurd is. Roodgekleurde tekst betekent dat deze stap niet werkt, groen betekent dat de stap werkt en geel betekent dat deze stap nog niet af is (dus nog niet gedefinieerd is). De stappen die niet gedraaid zijn (omdat een stap daarvoor niet goed is gegaan) zijn blauw. Je kan dus precies zien hoever je bent met programmeren. Ook komt het weleens voor dat een nieuwe functionaliteit iets doet waardoor een oude niet meer werkt. Dat kan je merken met Cucumber.

Cucumber voorbeeld rapportage

Opmerking: Dit is een screenshot van een gegenereerd html-rapport. Cucumber geeft voor ontwikkelaars standaard output op de command-line met verwijzingen naar de code en tips hoe de story te laten slagen. Je wordt als ontwikkelaar uitstekend op weg geholpen om je applicatie te maken

Cucumber kan ook meer. Het kan ook samenwerken met Selenium (een javascript test framework), zodat dezelfde stappen ook in een echte browser, zoals Firefox, uitgevoerd kunnen worden. Dit is wat langzamer, maar je kan dan echt zien hoe cucumber door de applicatie heen loopt. Ook kan selenium screenshots maken van elke pagina zodat je goed kan zien welke pagina’s er zijn en of ze goed ontworpen zijn.

Conclusie

Cucumber is een fantastische tool die het inzichtelijk maakt aan zowel de klant als de ontwikkelaar hoe de status is van een functionaliteit. Als klant hoef je je geen zorgen te maken over de stapdefinities, maar je kan in gewoon Nederlands zien wat er wel en niet werkt. Cucumber kan automatisch starten bij elke wijziging die de programmeur maakt om de voortgang direct inzichtelijk te maken. Voor de programmeur is dit een globale test of wat ze geschreven hebben geen errors produceert. Natuurlijk ontslaat dit de programmeur niet van zijn verantwoordelijkheid om een uitgebreide test-suite te schrijven, want cucumber vangt alleen fouten op een hoog niveau op.

Ik heb nog wel iets te bekennen en dat is dat we bij Finalist Cucumber nog niet officieel gebruiken. We hebben er uiteraard al wel mee gespeeld en zijn op dit moment aan het kijken hoe we dit het beste kunnen integreren in onze werkwijze. Degene die Cucumber gebruikt hebben zijn er erg van gecharmeerd en we hopen het zo snel mogelijk in het wild in te kunnen zetten.

Meer weten?

Ik heb maar een klein onderdeel beschreven van Cucumber en het proces wat hier mee gepaard gaat. Ik raad je aan om als je meer wilt weten eens de volgende links door te bladeren.

Share and Enjoy:
  • email
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Blogosphere News
  • Fleck
  • NuJIJ
  • Slashdot
  • StumbleUpon
  • LinkedIn
  • Twitter

7 reacties »

  1. Ik zie dat Worpress mijn code verpest. Overal waar => staat moet natuurlijk => staan.

    Iain Hecker - March 2, 2009 19:38

  2. Wordpress verpest zelfs je corrigerende comment ;)

    Arie - March 2, 2009 20:00

  3. Goed helder artikel man!

    Diederick Lawson - March 3, 2009 9:49

  4. Leuk verhaal!

    Alleen een vraag: waarom heb je dit niet opgesplitst in twee verschillende artikelen? Want in feite probeer je twee onderwerpen – die min of meer ook voor twee verschillende doelgroepen bedoeld zijn – in één posting te vatten. Het Scrum gedeelte is interessant voor developers, maar ook vooral voor klanten – om meer begrip te krijgen over hoe Scrum werkt. Het tweede gedeelte, over Cucumber is echter voornamelijk interessant voor developers (en Testers) en is eigenlijk een onderwerp op zich denk ik…

    Martin - March 3, 2009 10:59

  5. @martin Ik denk dat het cucumber ook interessant is voor klanten. Niet zozeer hoe het werkt, maar wel dat zij (als zij dat willen) inzage kunnen hebben in de status van het project. De talk die ik in de links noemde heet “Testing as communication”. Niet iedere klant is er wellicht in geinteresseerd.

    Over cucumber wil ik graag nog een keer een post schrijven overigens.

    Iain Hecker - March 3, 2009 12:32

  6. Ik ben het met martin eens dat het halverwege ineens een verhaalt over Cucumber wordt in plaats van ‘scrum volgens de ontwikkelaar’. De conclusie van het artikel gaat zelfs over cucumber en niet over scrum zoals de titel deed verwachten.

    Neemt niet weg dat cucumber natuurlijk een erg gaaf stuk gereedschap is!

    Peter - March 5, 2009 15:09

  7. [...] is weer komkommertijd. Ruim een jaar geleden schreef ik een blogpost over de testtool “Cucumber“. Cucumber is een testtool om in BDD-stijl te ontwikkelen. [...]

    BDD Javascript Ontwikkelen met Cucumber | Finalist Developers Blog - May 4, 2010 9:04

Reageer

RSS feed for comments on this post · TrackBack URI