TDD Tarina käyttöönotosta

Samankaltaiset tiedostot
TDD ja ATDD. Niklas Collin. Naulakatu 3, Tampere

Ohjelmistojen mallintaminen. Luento 11, 7.12.

Testilähtöinen ohjelmistokehitys. Testilähtöinen ohjelmistokehitys. TDD Testilähtöinen ohjelmistokehitys. Testi! Testi

Test-Driven Development

JReleaser Yksikkötestaus ja JUnit. Mikko Mäkelä

Ohjelmointi 2 / 2010 Välikoe / 26.3

Test-Driven Development

Yksikkötestaus. import org.junit.test; public class LaskinTest public void testlaskimenluonti() { Laskin laskin = new Laskin(); } }

SEPA REFAKTOROINTI Antti Ahvenlampi, 57408L Erik Hakala, 57509T

Testilähtöinen ohjelmistokehitys. Testilähtöinen ohjelmistokehitys. TDD Testilähtöinen ohjelmistokehitys. Testi! Testi. Test-Driven Development, TDD

Mikä yhteyssuhde on?

Metodien tekeminen Javalla

Helia Ohjelmointitaito Tuomas Kaipainen Mermit Business Applications Oy Mermit Business Applications

SEPA diary. Dokumentti: SEPA_diary_PK_HS.doc Päiväys: Projekti: AgileElephant Versio: V0.3

TDD Käytännössä Todellinen työkalu vai lehmipoikien laukkaa? Harri Kulmala Solita Oy

Olio-ohjelmointi Javalla

4. Luokan testaus ja käyttö olion kautta 4.1

Sisällys. 14. Poikkeukset. Johdanto. Johdanto

14. Poikkeukset 14.1

Automaattinen yksikkötestaus

Ohjelmoinnin perusteet, syksy 2006

1 Tehtävän kuvaus ja analysointi

Kompositio. Mikä komposition on? Kompositio vs. yhteyssuhde Kompositio Javalla Konstruktorit set-ja get-metodit tostring-metodi Pääohjelma

Sisällys. 14. Poikkeukset. Johdanto. Johdanto

9. Periytyminen Javassa 9.1

Ohjelmointi 2 / 2008 Välikoe / Pöytätestaa seuraava ohjelma.

14. Poikkeukset 14.1

Testaussuunnitelma PULSU. Syksy 2008 Ohjelmistotuotantoprojekti. HELSINGIN YLIOPISTO Tietojenkäsittelytieteen laitos

1.3 Lohkorakenne muodostetaan käyttämällä a) puolipistettä b) aaltosulkeita c) BEGIN ja END lausekkeita d) sisennystä

Testivetoinen ohjelmistokehitys

Rinnakkaisohjelmointi kurssi. Opintopiiri työskentelyn raportti

812341A Olio-ohjelmointi Peruskäsitteet jatkoa

Sisällys. Metodien kuormittaminen. Luokkametodit ja -attribuutit. Rakentajat. Metodien ja muun luokan sisällön järjestäminen. 6.2

Java ja grafiikka. Ville Sundberg

5. HelloWorld-ohjelma 5.1

Pedacode Pikaopas. Java-kehitysympäristön pystyttäminen

Convergence of messaging

Luokat ja oliot. Ville Sundberg

Ohjelmointi 1 / 2009 syksy Tentti / 18.12

Tehtävä 1. Tehtävä 2. Arvosteluperusteet Koherentti selitys Koherentti esimerkki

Rajapinta (interface)

15. Ohjelmoinnin tekniikkaa 15.1

Ohjelmistotekniikan menetelmät, koe

Sisällys. Yleistä attribuuteista. Näkyvyys luokan sisällä. Tiedonkätkentä. Aksessorit. 4.2

Sisällys. 6. Metodit. Oliot viestivät metodeja kutsuen. Oliot viestivät metodeja kutsuen

7. Näytölle tulostaminen 7.1

1. Olio-ohjelmointi 1.1

Ohjelmistojen mallintaminen, syksy 2011, laskuharjoitus 2

COTOOL dokumentaatio SEPA: Refaktorointi

Ohjelmointitaito (ict1td002, 12 op) Kevät Java-ohjelmoinnin alkeita. Tietokoneohjelma. Raine Kauppinen

Pakkauksen kokoaminen

Pakkauksen kokoaminen

Sisällys. Yleistä attribuuteista. Näkyvyys luokan sisällä ja ulkopuolelta. Attribuuttien arvojen käsittely aksessoreilla. 4.2

Ohjelmoinnin jatkokurssi, kurssikoe

Harjoitus Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti:

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op Taulukot & Periytyminen

5. HelloWorld-ohjelma 5.1

Javan perusteita. Janne Käki

Yksikkötestaus. Kattava testaus. Moduulitestaus. Ohjelman testaus. yksikkotestaus/ Seija Lahtinen

4. Olio-ohjelmoinista lyhyesti 4.1

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op Rajapinnat ja sisäluokat

Osio 4: Tietovirrat. Properties- eli ominaisuustiedostot Logger: lokitietojen käsittely

Sisältö. Johdanto. Tiedostojen lukeminen. Tiedostojen kirjoittaminen. 6.2

Delegaatit ja tapahtumakäsittelijät

7. Oliot ja viitteet 7.1

Poikkeustenkäsittely

T Tietojenkäsittelyopin ohjelmatyö. Testiraportti, vaihe T1. Tietokonegrafiikka-algoritmien visualisointi. Testiraportti, vaihe T1

Java kahdessa tunnissa. Jyry Suvilehto

Tässä tehtävässä käsittelet metodeja, listoja sekä alkulukuja (englanniksi prime ).

Olio-ohjelmointi Virhetilanteiden käsittely

Liite 1: KualiKSB skenaariot ja PoC tulokset. 1. Palvelun kehittäjän näkökulma. KualiKSB. Sivu 1. Tilanne Vaatimus Ongelma jos vaatimus ei toteudu

Ohjelmistotekniikan menetelmät, toteutuksesta ja testauksesta

Olio-ohjelmointi: Luokkien toteuttaminen. Jukka Juslin

15. Ohjelmoinnin tekniikkaa 15.1

11. Javan valintarakenteet 11.1

Sisältö Johdanto. Tiedostojen lukeminen. Tiedostojen kirjoittaminen. 26.2

2. Olio-ohjelmoinista lyhyesti 2.1

Testaussuunnitelma. Ohjelmistotuotantoprojekti Nero. Helsinki Ohjelmistotuotantoprojekti HELSINGIN YLIOPISTO Tietojenkäsittelytieteen laitos

KOHDELUOKAN MÄÄRITTELY

BlueJ ohjelman pitäisi löytyä Development valikon alta mikroluokkien koneista. Muissa koneissa BlueJ voi löytyä esim. omana ikonina työpöydältä

public static void main (String [] args)

Java-API, rajapinnat, poikkeukset, UML,...

Listarakenne (ArrayList-luokka)

ITKP102 Ohjelmointi 1 (6 op)

Sisältö. Johdanto. Tiedostojen lukeminen. Tiedostojen kirjoittaminen. 6.2

Testausdokumentti. Kivireki. Helsinki Ohjelmistotuotantoprojekti HELSINGIN YLIOPISTO Tietojenkäsittelytieteen laitos

9. Periytyminen Javassa 9.1

Java-kielen perusteet

Ohjelmistotuotanto. Luento

Kehitysohje. ETL-työkalu. ExtraTerrestriaLs / Aureolis Oy

Tarjolla tänää: Ohjelmiston toteutuksesta. Kuinka tulla hyväksi ohjelmoijaksi? CRC-kortit. Testilähtöinen kehittäminen JOT2007. Uudelleenrakentaminen

Ohjelmointi 2, välikoe

Lohkot. if (ehto1) { if (ehto2) { lause 1;... lause n; } } else { lause 1;... lause m; } 15.3

Olion elinikä. Olion luominen. Olion tuhoutuminen. Olion tuhoutuminen. Kissa rontti = null; rontti = new Kissa();

SEPA diary. Dokumentti: SEPA_diary_PK_HS.doc Päiväys: Projekti: AgileElephant

// Tulostetaan double-tyyppiseen muuttujaan "hinta" tallennettu // kertalipun hinta ja vaihdetaan riviä. System.out.printf("%.1f euros.

Versio Päiväys Tekijä Kuvaus Tikkanen varsinainen versio

13/20: Kierrätys kannattaa koodaamisessakin

Oliot viestivät metodeja kutsuen

Java-kielen perusteet

Transkriptio:

TDD Tarina käyttöönotosta Näkemys onnistuneeseen käyttöönottoon Novaloc Oy - Hermiankatu 6-8 H 33720 Tampere info@novaloc.fi - +358 (0)50 544 5421

Taustaa Novaloc oy Novaloc Oy on vuoden 2007 alussa perustettu ohjelmistoalan yritys Liiketoiminta-alue IT-palveluliiketoiminnassa Asiakaslähtöisten projektien tekeminen Konsultointi Nykyisellään työllistää kymmenkunta henkilöä Pääasiallisesti käytetyt teknologiat Java, Spring Framework ja Apache Tomcat

Taustaa - Esiintyjä Niklas Collin Vanhempi järjestelmäsuunnittelija Novalocin perustajajäsen ScrumMaster, koodari, hallituksen jäsen riippuu tilanteesta TTY:n kasvatti vieläkin Tutkintouudistus varmistanee valmistumisen kuitenkin

Esityksessä käytettyä testaustermistöä Yksikkötestaus Yksittäisen luokan testaaminen Ulkoiset riippuvuudet tulisi minimoida Integraatiotestaus Useamman luokan yhteistoiminnan testaus Ulkoiset riippuvuudet sallitaan Tietokantatestit jne. ovat integraatiotestejä Järjestelmätestaus Koko paketin testaus kerralla WWW-sovelluksissa käsittää selaimen läpi käskyttämisen

Testausmuodoista Käytännössä yksikkötestausta voi tehdä kahdella tapaa: Mockist ja Classicist Molemmissa tavoissa on etunsa, TDD:tä lienee kuitenkin helpompi lähteä opettelemaan käyttämällä mockist -tapaa Perusteluna se, että mockist-tapa antaa koodarille mahdollisuuden miettiä myös toteutuskoodin sisäistä toimintaa testiä kirjoittaessa pienempi hyppäys tavoissa Myöhemmin suosisin ennemmin classicist -tapaa, kunhan peruskäytännöt on opittu Perusteluna testien pienempi korjauksien tarve jos jotain muutetaan, koska mock-testit puuttuvat toteutuskoodin sisäiseen logiikkaan

Test-Driven Development Mitä on TDD? Miksi Novaloc päätti siirtyä käyttämään sitä? Test-Driven Developmentilla (TDD, testiohjattu kehitys) on kahdenlainen tarkoitus: Toimia matalan tason suunnittelun lähtökohtana Varmistaa kattava testaus yksikkö- ja integraatiotestaustasolla Pääasiallisena korkeamman tason motivaationa siis laadun varmistaminen Kattavan testipatteriston avulla minimoidaan regressio ja täten muutosten tekeminen on helpompaa

Test-Driven Development Test Code Refactor Toteutus etenee lyhyissä sykleissä Syklin pituus muutamasta kymmenestä sekunnista viiteen minuuttiin Refaktoroi Toteuta Ensin kirjoitetaan testi, joka testaa yksinkertaista osuutta toiminnasta Tätä testiä vasten tehdään haluttu toiminnallisuus Testaa Lopuksi refaktoroidaan jos sille on tarvetta

Aieperustainen ohjelmointi Oleellinen osa testiohjattua kehitystä on aieperustainen ohjelmointi (Programming by Intention) Tarkoituksena on lähestyä ohjelmakoodin kehitystä black-box -ajattelulla Rajapintoja tehdessä ei mietitä toiminnallisuutta, vaan sitä miten kyseistä rajapintaa haluttaisiin käyttää Pyritään jakamaan ohjelmakoodi useisiin metodeihin, joiden nimet ovat mahdollisimman kuvaavia Ohjelmakoodista tulee luettavampaa Esimerkki avaa ideaa

Aieperustainen ohjelmointi - esimerkki public class CurrencyConverter { public static void main(string[] args) { BigDecimal sum = new BigDecimal(args[0]); String from = args[1]; String to = args[2]; Properties currencies = new Properties(); try { currencies.load(classloader.getsystemresourceasstream("currencies.properties")); } catch (Exception e) { e.printstacktrace(); System.exit(1); } Object fromcurrencyobj = currencies.get(from); Object tocurrencyobj = currencies.get(to); if (fromcurrencyobj == null) { System.err.println("Invalid currency type '" + from + "'"); System.exit(1); } else if (tocurrencyobj == null) { System.err.println("Invalid currency type '" + to + "'"); System.exit(1); } BigDecimal fromcurrencyrate = new BigDecimal(fromCurrencyObj.toString()); BigDecimal tocurrencyrate = new BigDecimal(toCurrencyObj.toString()); BigDecimal result = sum.multiply(fromcurrencyrate.divide(tocurrencyrate)); } } System.out.println(sum + " " + from + " = " + result + " " + to);

Aieperustainen ohjelmointi - esimerkki public class ImprovedCurrencyConverter { public static void main(string[] args) { BigDecimal sum = new BigDecimal(args[0]); String from = args[1]; String to = args[2]; Properties currencies = loadcurrencyfile (); BigDecimal fromcurrencyrate = getcurrencyrate (from, currencies); BigDecimal tocurrencyrate = getcurrencyrate (to, currencies); BigDecimal result = calculateresult (sum, fromcurrencyrate, tocurrencyrate); } System. out.println(sum + " " + from + " = " + result + " " + to); }... Jaottelu metodeihin on perustason ohjelmointiosaamista Aieperustaisessa ohjelmoinnissa jaottelua ei kuitenkaan tehdä jälkikäteen, vaan yllä merkityt metodikutsut tehdään ennen varsinaisen toteutuskoodin kirjoittamista Tarkoituksena on esittää ohjelmoijan aie tulevaisuuden toiminnallisuudesta

TDD + PbI =? Miten aieperustainen ohjelmointi sitten liittyy TDD:hen? Ohjelmien teko TDD:nä on käytännössä aieperustaista ohjelmointia testien suunnasta katsottuna Kirjoitat aieperustaisesti testin, joka kutsuu ohjelmakoodia, jota ei ole vielä olemassakaan Yhdessä TDD ja aieperustainen ohjelmointi muodostavat vahvan työskentelykäytännön, joka varmistaa niin rajapintametodien järkevän rakenteen kuin myös selkeän ja luettavan koodin rajapinnan takana

TDD:n eri lajit TDD terminä on nykyisellään monikäsitteinen Alunperin TDD on lähtöisin Extreme Programming -metodologiasta, nykyisin TDD on käytössä myös XP:n harjoittajien ulkopuolella Nykyisellään TDD:n voi jakaa neljään erilaiseen versioon: 1) Testiohjattu kehitys 2) Testisuuntautunut kehitys 3) Testiohjattu suunnittelu (alkuperäinen XP-tapa) 4) Testiohjattu kehitys ja suunnittelu Novaloc päätyi vaihtoehtoon 4.

Kritiikki TDD on saanut osakseen paljon hehkutusta ja suoranaista hypetystä, mutta myös kritisoijia riittää Tunnetuimpia vastustajia lienee James Cope Coplien Cope vastustaa erityisesti alkuperäistä XP:n tapaa Myös VTT:llä ovat erityisesti Sinisalo ja Abrahamsson tehneet tutkimuksia, jotka ovat tuoneet huolestuttavia tuloksia koskien TDD:n toimivuutta Tutkimukset eivät kuitenkaan ole olleet riittävän kattavia, jotta niistä voisi vetää lopullisia johtopäätöksiä TDD on suhteellisen vähän tutkittu aihe, viestit kentältä kuitenkin ilmaisevat sen toimivan

Miten Novaloc toimi aluksi? Ensin yksi henkilö opetteli perusteellisesti sen, että mistä on oikein kyse Tämän jälkeen tehtiin yksi hyvin pieni (n. 1000 riviä) asiakasprojekti yksin tämän henkilön toimesta Ei-kriittinen projekti, epäonnistuminen ei olisi haitannut merkittävästi Projektista opittiin ja oppeja hyödynnettiin kun TDD otettiin suuremmassa mittakaavassa käyttöön?!

Suurempaan mittakaavaan Seuraavaksi tiimi kasvatettiin neljään ja työn alle otettiin isompi projekti, jonka tarkoituksena oli kehittää monikäyttöinen alusta tuleville projekteille Aikaisempi yksinäinen henkilö astui ScrumMasterin rooliin ja alkoi poistamaan esteitä tiimin tieltä Tälläinen este oli mm. TDD:n opettaminen tiimille Tiimin työskentelyä seurattiin ja kannustettiin Mukaan otettiin myös CI-palvelin, joksi valittiin Hudson Buildauksesta huolehti Maven

Tulokset Alustan saavuttaessa pisteen, jossa sen päälle alettiin tekemään ensimmäistä asiakasprojektia, oli koodirivejä vajaa 30 000 Testikattavuudet 80-90% riippuen kattavuustyypistä ja moduulista Aivan kaikkea ei testattu, model-objektien getterit ja setterit generoitiin jne. Sprinttien päätteeksi syntynyt koodi käytännössä bugitonta Yleisesti ottaen laatu pysyi selvästi korkeampana kuin aikaisemmin

Huomioita Novalocin siis voidaan sanoa onnistuneen TDD:n käyttöönotossa, mitä tehtiin oikein? ScrumMasterin rooli osoittautui kriittiseksi: ilman aktiivista kannustajaa, esteiden poistajaa ja kehitystyökalujen parantamista olisi TDD voinut osoittautua liian työlääksi hyppäykseksi kehittäjille Kehitystiimi tunsi toisensa erinomaisesti ja oli tehnyt paljon töitä keskenään Helpotti asioiden opettamista Kouluttajan jatkuva läsnäolo edesautti asioiden sisäistämistä

Huomioita Tiimi tajusi heti kättelyssä, että kirjaimellinen XP:n mukainen TDD:n seuraaminen ei voi toimia Päädyttiin mukailevampaan ratkaisuun, jossa TDD:n rooli on koodipohjan kannalta kehittävä, ei suunnitteleva CI-palvelin ja -käytännöt olivat käytännön pakko Erityisesti analyysityökalut auttoivat paljastamaan kurjat petturit Testien suoritusnopeuteen kiinnitettiin erityistä huomiota Mikäli testien ajaminen on liian hidasta, niin kehittäjät eivät enää aja niitä jatkuvasti ja TDD hajoaa käsiin Tiimin pitää saada keskittyä yksin projektiin, jossa käyttöönotto tehdään!

Huomioita Käyttöliittymäkerroksen kehittämisessä testiohjatusti ei ole mieltä Automaattisilla testeillä ei kyetä testamaan kaikkea (esim. selainkohtaiset sivurakenteen hajoamiset) Kun toteutusratkaisu ei ole täysin selvä pitäisi käyttää ns. Spikeja asian selvittämiseen Spiken toteuttaminen on kuitenkin vaikeaa ympäristössä, jossa opeteltavan asian vaativan ympäristön pystyttäminen veisi kohtuuttomasti aikaa Tälläisissä tilanteissa toteutuskoodi syntyi opettelun myötä ja testit kirjoitettiin jälkikäteen Ei kuitenkaan ongelma kunhan muistetaan refaktoroida

Huomioita Ilmapiirin pitää olla refaktorointiin kannustava Kenen tahansa koodeja saa ja pitää parantaa aina kun siihen näkee syyn (Common Code Ownership) Kuitenkin pitää osata varoa aropupumaista asiasta toiseen pomppimista ja keskittyä oleelliseen Ei painosteta jatkuvasti uusia ominaisuuksia tiimiltä, vaan luotetaan tiimin kykyyn toimittaa halutut ominaisuudet Sprintin päättyessä Jos ei refaktoroida myös testejä, niin TDD epäonnistuu Tällöin seurauksena on korkeat testikattavuudet, mutta muutosten hallinta muuttuu todella vaikeaksi, koska testien itsensä korjaaminen on liian työlästä

Yhteenveto huomioista Testit ovat yhtä tärkeitä ja vaativat yhtä paljon huomiota kuin varsinainen toteutuskoodi Ilman refaktorointia TDD epäonnistuu ja tuloksena on vaikeasti ylläpidettävä sekamelska Käyttöönoton yhteydessä on tärkeää, että TDD:tä kokeileva tiimi tuntee toisensa hyvin ja on erittäin ammattitaitoinen Myöhemmin nämä oppineet koodarit voivat levittää oppejaan muissa tiimeissä Tiimillä pitää olla isällinen valvoja, joka auttaa minimoimaan uuden käytännön tuomat vaikeudet TDD-koodarin pitää osata hyvien testien kirjoittaminen

Kysymyksiä? Kiitos kuuntelusta, toivottavasti esitys aiheutti ajatuksia, jotka johtavat parempiin käytäntöihin :) Vastaan kysymyksiin parhaani mukaan

Lisämateriaalia Lisäluettavaa esityksen jälkeen: http://www.testdriven.com/ Practical TDD and Acceptance TDD for Java Developers, Koskela 2007, ISBN 1-932394-85-0 Test driven Development: By Example, Beck 2004, ISBN 0321146530, 9780321146533 Using Continuous Integration? Better do the "Check In Dance", http://codebetter.com/blogs/jeremy.miller/archive/2005/07/25/129797.aspx Red-Green-Refactor, http://jamesshore.com/blog/red-green-refactor.html Mocks Aren't Stubs, http://martinfowler.com/articles/mocksarentstubs.html