6.6.2013

Ketteryys haltuun: Yleisimmät ketterät käytännöt

Ketteryys haltuun -artikkelisarjassa julkaistut muut osat:
Osa 1: Ketterän kehityksen yleiset periaatteet
Osa 3: Scrum pähkinänkuoressa
Osa 4: Ketteryys haltuun: Miten ostan ketteriä IT-projekteja?

Ketteryys haltuun -artikkelisarjassa kerrotaan ketterän kehittämisen periaatteista ja käytännön menetelmistä. Ketterä kehittäminen on kerännyt paljon huomiota, mutta ilmiö ei ole lainkaan yksiselitteinen eikä ketterän kehittämisen soveltaminen käytännössä ole aina yksinkertaista. Tämän artikkelisarjan tavoitteena on avata peruskäsitteitä ja auttaa ymmärtämään mitä ketteryys ohjelmistokehityksessä tarkoittaa.

Sarjan toisessa osassa tarkastellaan yleisimpiä ketteriin menetelmiin liittyviä kehityskäytäntöjä.

Yleisimmät ketterät käytännöt

Ketteriin menetelmiin liittyy paljon erilaisia toimintatapoja ja -käytäntöjä. Tässä artikkelissa on esitelty tiiviisti yleisimmät käytännöt, jotka tulevat vastaan ketterien projektien kanssa toimiessa.

Päiväpalaveri

Päiväpalaverilla (daily meeting) tarkoitetaan päivittäin pidettävää lyhyttä tilannepalaveria, jossa tiimin kaikki jäsenet ovat koolla. Tällainen lyhyt tilannepalaveri löytyy useimmista ketteristä menetelmistä: Scrum-menetelmässä tämä tunnetaan nimellä daily scrum. XP:ssä puhutaan stand -up meetingistä, seisontapalaverista.

Päiväpalaverissa kukin vastaa tyypillisesti kolmeen kysymykseen:

  • Mitä teit edellisenä päivänä?
  • Mitä aiot tehdä tänään?
  • Mitkä seikat haittaavat työskentelyäsi?

Palaverin tarkoituksena on varmistaa, että kukin tiimin jäsen tietää jatkuvasti, mitä toiset tekevät. Etenkin Scrum-mallissa kolmas kysymys on erityisen merkityksellinen. Scrum-mestarin tärkein työtehtävä on poistaa työskentelyä haittaavia esteitä, jotta tiimi voi tehdä työtään mahdollisimman tehokkaasti.

Yleensä päiväpalaverin on tarkoitus kestää vain 5-15 minuuttia. Tavoitteeseen pääsy pyritään varmistamaan muun muassa pitämällä palaveri seisten. Mikäli päiväpalaverin aikana tulee ilmi suurempia asioita, jotka vaativat laajempaa keskustelua tai selvitystyötä, sitä varten järjestetään oma palaverinsa päiväpalaverin jälkeen.

Päiväpalaverin tarkoituksena on omalta osaltaan parantaa projektin läpinäkyvyyttä: tilaisuus on avoin kaikille, jotka ovat kiinnostuneita projektin tilasta. Vain tiimiin kuuluvat henkilöt saavat puhua palaverissa, mutta kuuntelemaan saa tulla kuka tahansa. Tämä vähentää huomattavasti erilaisten raporttien ja tilannekatsausten tarvetta. Päiväpalaverin tarkoitus ei ole olla “kyttäyssessio”, missä johto seuraa kunkin tekemisiä, vaan nimenomaan tiimin itsensä työnohjaukseen liittyvä tilannekatsaus, jossa myös saatetaan työtä haittaavat esteet yleiseen tietoisuuteen.

Jatkuva integraatio

Jatkuvalla integraatiolla (continuous integration) tarkoitetaan prosessia, jossa koko ohjelmisto koostetaan ja integroidaan jatkuvasti. Perinteisissä kehitysmalleissa integraatio sijoittuu projektin loppupuolella tehtäväksi kertarypistykseksi. Usein rypistyksestä myös tulee hyvin pitkä ja vaikea, varsinkin jos heti projektin alkumetreiltä asti ei ole osattu huomioida integroinnin haasteita.

Jatkuva integraatio ohjaa kehitystä siihen suuntaan, että ohjelmisto on milloin tahansa ainakin periatteessa julkaistavissa hyvin nopeasti. Mikäli ohjelmiston arkkitehtuuri on suuri ja eri tiimit toteuttavat eri komponentteja, jatkuvalla integraatiolla varmistutaan siitä, että komponenttien yhteenliittämisessä ei tule suuria yllätyksiä siinä vaiheessa, kun projektia pitäisi alkaa päättämään.

Projektin koosta riippuen integroinnin jatkuvuus voi olla reaaliaikaista (esim. integrointi käynnistyy automaattisesti jokaisen check-inin yhteydessä) tai ajastettua (esim. integrointi tapahtuu joka yö). Mikäli ohjelmiston koostaminen kestää huomattavan pitkän ajan (tunteja), kannattaa yleensä siirtyä ajastettuihin koosteisiin.

Tyypillisesti jatkuvassa integroinnissa tehdään kaikki toimenpiteet, mitkä kuuluvat tuotteen julkaisuun muutenkin. Yksinkertaisimmillaan tämä voi tarkoittaa vain tuoreimman ohjelmistoversion noutamista versionhallinnasta, kääntämistä ja lopputuotteen siirtämistä asennushakemistoon. Toisessa ääripäässä on järjestelmät, jotka suorittavat samalla kaikki automatisoidut testit (yksikkötestit, hyväksyntätestit ja muut mahdolliset testit), kääntää ohjelmakoodin, alustaa www-palvelimen, asentaa web-servicet paikoilleen, koostaa käyttöohjeet ja API -kuvaukset ja lopuksi vielä kirjoittaa koko asennuspaketin DVD -levylle.

Jälkitarkastelu

Jälkitarkastelu esiintyy Scrum-menetelmässä nimellä retrospective meeting ja Crystal-menetelmistössä nimellä reflection workshop. Idea molemmissa on kuitenkin sama: pysähdytään hetkeksi miettimään, ovatko valitsemamme käytännöt ja toimintatavat parhaita mahdollisia vai onko jossain parannettaa.

Erityisen hyvä hetki tällaiselle on jokaisen toimituksen jälkeen. Perinteisissä ohjelmistokehitysmalleissa puhutaan usein post mortemista, projektin päättymisen jälkeen pidettävästä tapaamisesta, jossa analysoidaan projektin kulkua ja kootaan yhteen projektin aikana opittuja asioita. Tämä on hyvä käytäntö ja ensiaskel oikeaan suuntaan, mutta usein nämä jäävät pitämättä, koska post mortem ei hyödytä enää sitä projektia, jonka päättyessä se järjestetään.

Hyödyllisempää on järjestää “mini post mortem” jokaisen iteraation päätteeksi. Näin projektin aikana saadut kokemukset voidaan valjastaa hyödyttämään jo menossa olevaa projektia. Jälkitarkastelujen pitämisestä tulee myöskin huomattavasti kevyempää, kun niitä pidetään usein. Tällöin ei tarvitse pitää yhtä massiivisen pitkäkestoista työpajaa, missä saadaan koottua kaikki pitkän projektin kokemukset talteen.

Refaktorointi

Refaktoroinnilla (refactoring) tarkoitetaan työtä, jota tehdään ohjelmakoodin pitämiseksi ymmärrettävänä ja ylläpidettävänä, vaikka työn tuloksena varsinainen toiminnallisuus ei muutukaan.

Koska ketterässä kehityksessä lähdetään siitä, että vaatimukset voivat muuttua koska tahansa, koodin on oltava erityisen ylläpidettävää. Tyypillisesti käytössä on myös jaettu koodin omistajuus, jolloin kuka tahansa voi tehdä muutoksia mihin ohjelmiston osaan tahansa. Tällöin on ensiarvoisen tärkeää, että koodi on selkeää ja ymmärrettävää, ja että ymmärrettävyyttä ylläpidetään jatkuvasti.

Jotta refaktorointi olisi turvallista, kannattaa “turvaverkkona” käyttää yksikkötestejä. Kattavan testipatteriston turvin voidaan varmistua siitä, että koodin toiminnallisuus ei todella muutu.

Testivetoinen kehitys

Testivetoisella kehityksellä (test-driven development, TDD) tarkoitetaan nimensä mukaisesti sitä, että ohjelmistoa kehitetään testien vetämänä. Perinteisissä malleissa testaus on jätetty projektin loppupäähän, toteutuksen jälkeen. Ongelmaksi tässä muodostuu se, että mikäli virheitä löytyy suuri määrä, ei välttämättä ole enää juurikaan aikaa korjata niitä.

Ohjelmistoa pitäisi kehittää siten, että virheiden määrä on jatkuvasti minimissä. Valitettavan usein käytetty periaate on “tehdään tämä ensin valmiiksi, korjataan sitten virheet”. Tämä johtaa kuitenkin useisiin merkittäviin ongelmiin:

  • Projektin loppupuolelle muodostuu epämiellyttävää testaa-korjaa -vaihe
  • Projektin aikana kumuloituvat virheet hidastavat ohjelmiston kehittämistä
  • Ohjelmistossa olevat virheet voivat johtaa siihen, että joissakin toiminnoissa virheitä pyritään kiertämään, ja kun lopulta varsinainen virhe korjataan, sen kiertämiseksi tehty purkkakorjaus menee rikki.

Etukäteen kirjoitettuja testejä voidaan joissain tapauksissa käyttää korvaamaan varsinainen vaatimusmäärittely – testit kertovat yksiselitteisesti sen, mitä ohjelmiston pitää missäkin tilanteessa tehdä.

Yleensä testeinä käytetään yksikkötestejä.

Yksikkötestit

Yksikkötestauksella (unit testing) – tai kehittäjätestauksella (developer testing) – tarkoitetaan hyvin matalan tason testausta, jossa varmistutaan metoditasolla siitä, että koodi toimii ohjelmoijan tarkoittamalla tavalla.

Parhaimmillaan yksikkötestit toimivat erittäin tarkkana määrittelynä siitä, miten ohjelman pitäisi toimia.

Yksikkötestit voi kirjoittaa valmiiksi joku toinen tiimin jäsen, esimerkiki pääkehittäjä, mutta usein ohjelmoija itse kirjoittaa testit omaa koodiaan varten. Kun testitapaukset on kirjoitettu valmiiksi, ohjelmoijan tehtävänä on kirjoittaa koodi, joka läpäisee testit. Testivetoisessa kehityksessä noudatetaan juuri tätä ideaa.

Jotta yksittäisen metodin oikea toiminta voidaan varmistaa, vaaditaan monta testiä yhtä metodia varten: yleensä erilaisia parametrikombinaatioita on useita. Erityisesti testeissä kannattaa huomioida raja-arvot ja vialliset syötteet.

Usein yksikkötestit suoritetaan automaattisesti osana jatkuvaa integraatiota, jolloin voidaan varmistua siitä, ettei johonkin ohjelmiston osaan tehty muutos aiheuttanut jotain ongelmaa toisella puolella ohjelmistoa.

Yhteisomistus

Ohjelmointitiimissä työskennellessä on erittäin tärkeää, että koodin omistajuus on selvillä. Tähän on kehitelty useita erilaisia malleja. Tiukimmasta päästä ovat luokkakohtainen omistajuus, missä vain yksi henkilö saa tehdä muutoksia kuhunkin luokkaan. Yhteisomistus tarkoittaa vastaavasti sitä, että kaikki koodi on tiimin yhteisessä omistuksessa. Tällöin kuka tahansa tiimin jäsen saa tehdä muutoksia mihin luokkaan tahansa.

Yhteisomistajuus takaa, että johonkin komponenttiin tarvittava muutos ei ole yksittäisestä ihmisestä kiinni eikä siten hidasta työn edistymistä. Toisaalta malli vaatii hyvää tiimihenkeä ja sitoutumista sekä vastuun ottamista koko tuotteesta. Missä tahansa komponentissa oleva virhe on kaikkien vastuulla.

Olipa koodin omistajuus ratkaistu miten tahansa, tämän täytyy olla kaikille tiimiläisille päivänselvää, jottei tarvitse käyttää aikaa sen miettimiseen “saanko minä tehdä tähän muutoksia”.

Tasainen tahti

Tasainen tahti (sustainable pace) käytäntönä tarkoittaa sitä, että työtahdin on pysyttävä sellaisena, että sitä voisi jatkaa periaatteessa loputtomiin. Käytännössä tämä tarkoittaa sitä, että ylitöitä ei lähtökohtaisesti suositella tehtäväksi. Ihminen jaksaa tehdä pitempää päivää tuottavasti muutaman päivän tai viikon, mutta sen jälkeen alkaa väsymys heikentää suoritusta. Ohjelmointi on ajatustyötä, eikä aivoja kannata ylirasittaa pitkään. Työn edistymisen kannalta ratkaisevia ovat aivotunnit, eivät läsnäolotunnit!

Tasainen tahti varmistaa, että pidemmällä aikavälillä tiimi toimii optimaalisesti – lähes täydellä teholla jatkuvasti.

Pariohjelmointi

Pariohjelmointi on käytäntö, missä kaksi ohjelmoijaa työskentelee yhdessä yhdellä koneella. Toinen toimii pääohjelmoijana ja toinen seuraa vierestä. Pari voi vaihtaa rooleja joustavasti sen mukaan minkä parhaaksi katsovat. Ensikuulemalta tämä kuulostaa erittäin tehottomalta tavalta toimia, mutta käytännössä tällä menetelmällä on saavutettavissa useita hyötyjä. Aina kun sillä hetkellä vuorossa oleva näppäimistön käyttäjä jää pohtimaan jotain ongelmaa, saattaa parilla olla jo vastaus valmiina. Vierestä tarkkaileva pari myös usein nopeammin havaitsee, jos toinen tekee huomaamattaan jonkun virheen.

Pariohjelmoinnin kannattavuudesta on tehty jonkin verran tutkimuksia. Keskimääräinen vaikutus pariohjelmoinnilla kehitysnopeuteen on vain n. 1,5-kertainen (kaksi ihmistä yksin saisi siis enemmän koodia aikaan), mutta tuloksena syntyvän koodi laatu on moninkertaisesti parempi. Tämän vuoksi koodin ylläpidettävyys ja muokattavuus ovat huomattavasti parempia ja tämän kautta säästöt tulevat merkittäviksi.

Pariohjelmoinnilla saavutetaan myös sosiaalisia vaikutuksia:

  • keskittyminen työntekoon on parempaa, kun joku toinen on mukana seuraamassa
  • ohjelmoija ei käy yhtä helposti “vain nopeasti lukaisemassa henkilökohtaista sähköpostiaan”, mikä yleensä aiheuttaa selvän katkoksen työn sujumiseen
  • ulkopuoliset häiriötekijät vähenevät – jos kaksi ihmistä näyttää keskittyvän tiiviisti työn tekemiseen, heitä ei tulla häiritsemään yhtä helposti kuin henkilöä, joka ohjelmoi yksin

Pariohjelmointi on lisäksi yksi tehokkaimpia osaamisen kehittämisen keinoja. Ikäänkuin työn tekemisen sivutuotteena ohjelmoijat tulevat näyttäneeksi toisilleen oman tapansa ratkaista ongelmia, käteviä näppäinoikoteitä usein käytettyihin toimintoihin sekä jakavat kokemuksiaan työtä tehostavista työkaluista.

Hyvin usein kuultuja kommentteja yhdessä ohjelmoivilta pareilta ovat “Ai, tuon saa tehtyä noin helposti!” tai “En tiennytkään, että noinkin voi tehdä”. Parin kumpikin ohjelmoija siis kehittyy yksilönä. Vielä kun tiimin sisällä pareja vaihdetaan säännöllisesti, tietämys jakaantuu koko tiimille hyvin nopeasti.

Käyttäjätarinat

Ketterässä kehityksessä ei ole tapana tehdä täydellistä vaatimusmäärittelyä etukäteen, vaan vaatimukset tarkentuvat projektin kuluessa. Jollain tavalla projektissa on kuitenkin päästävä alkuun ja ketterä tapa siihen on käyttäjätarinat (user stories).

Käyttäjätarina on yksi selkeä toiminnallinen vaatimus, mitä järjestelmän on tuettava. Varsinainen teksti pyritään pitämään mahdollisimman lyhyenä, mutta tekstistä pitää käydä ilmi KUKA pystyy tekemään MITÄ ja MIKSI. Liian usein puhutaan vain ”käyttäjistä”, vaikka järjestelmällä voi oikeasti olla useita erilaisia käyttäjäryhmiä.

Käyttäjätarinoita luodaan tarinankirjoitussessioissa, johon osallistuu tulevia käyttäjiä, asiakkaan edustajia ja mahdollisesti myös järjestelmän kehittäjiä. Tavoitteena on kirjoittaa mahdollisimman suuri määrä tarinoita, ottamatta kantaa siihen, mitä niistä oikeasti toteutetaan. Tarinat voivat olla alkuun ylimalkaisia, niitä voidaan myöhemmin tarkentaa tai jakaa alitarinoihin.

Hyvillä käyttäjätarinoilla on tiettyjä yhteisiä piirteitä:

  • Riippumattomuus. Mikäli tarinat ovat vahvasti riippuvaisia toisistaan, priorisointi ja toteutukseen vaaditun työajan arviointi voi osoittautua mahdottomaksi.
  • Neuvoteltavuus. Tarinat eivät ole sopimuksia, vaan niissä pitää olla joustamisen varaa.
  • Arvokkuus. Tarinan pitää tuoda lisäarvoa käyttäjälle, ei kehittäjälle.
  • Arvioitavuus. Koska suunnitelu tehdään tarinoiden pohjalta, on niiden oltava arvioitavissa.
  • Pienuus. Suuret tarinat ovat liian monimutkaisia, ja riskialttiita tehtäväksi. Usein pitkät kertomukset voidaan jakaa pienempiin osatarinoihin.
  • Testattavuus. Tarinoiden pitää olla testattavissa.

Käyttäjätarinoiden EI OLE tarkoitus olla täydellinen määrittely, vaan enemmänkin muistuttaa asioista, joista pitää keskustella.

Käyttäjätarinatkaan eivät ole ainut oikea ratkaisu kaikkiin tilanteisiin. Hyvin suurissa projekteissa tarinoita voi kertyä niin suuri määrä, että niiden käsittely käy mahdottomaksi. Ongelmaa voi helpottaa luomalla ”korkean tason” tarinoita, kertomuksia, alusta lähtien ja myös ryhmitellä tarinoita teemoittain.

Tarinat eivät myöskään välttämättä ole oikea valinta, mikäli vaatimusten jäljitettävyys on tärkeää. Hyvässä, luottamukseen perustuvassa asiakassuhteessa tähän ei kuitenkaan ole yleensä tarvetta.

Käyttäjätarinat keskittyvät parantamaan suullista, tiimin sisäistä, eikä formaalia viestintää. Mikäli vaatimuksia on tarpeen kommunikoida useille eri tahoille – esimerkiksi monitoimittajaprojekteissa – tarinoita on tarpeen laajentaa formaalimmilla dokumenteilla.


Artikkeli pohjautuu Sinisen Meteoriitin menetelmäarkkitehti Sami Poimalan tuottamiin koulutusmateriaaleihin ja artikkeleihin. Artikkelin on julkaistuun muotoon viimeistellyt ja täydentänyt Sinisen Meteoriitin konsultti Perttu Tolvanen.

Perttu Tolvanen on sisällönhallinnan konsultti. Pertulla on kokemusta laajoista portaaliprojekteista joissa on sovellettu ketterän kehittämisen menetelmiä. Perttu Tolvanen työskentelee Sinisessä Meteoriitissa ja auttaa asiakkaita hankkeistuksessa, vaatimusmäärittelyissä ja teknologiavalinnoissa.

Sami Poimala on kokenut menetelmäarkkitehti ja ohjelmistokehittäjä. Sami on työskennellyt vuosia ketterän kehittämisen parissa Sinisessä Meteoriitissa ja myös kouluttanut paljon esimerkiksi Sinisen Meteoriitin henkilökuntaa ketterän kehittämisen saloihin.

Sininen Meteoriitti on SharePoint-toteutuksiin erikoistunut ohjelmistoyritys, jonka projekteissa on hyödynnetty ketteriä menetelmiä jo vuosia. Artikkelisarja ketteristä menetelmistä jatkuu seuraavaksi aiheella “Scrum pähkinänkuoressa”.