Vinkit testivetoisen kehityksen kanssa tasapainotteluun

Meillä Sysartilla on pitkät perinteet testivetoisen kehityksen (TDD, test-driven development) soveltamisesta asiakasprojekteissa. TDD:ssä kantava idea on kirjoittaa vaatimuksia vastaavat testit ensiksi, sitten testit läpäisevä koodi ja lopulta refaktoroida koodi hyväksi tuotantokoodiksi.

Maailma on muuttunut paljon siitä kun TDD:stä ruvettiin puhumaan lähes 20 vuotta sitten. Modernissa webbikehityksessä parhaat tavat testata ovat yleensä varsin erilaiset, mutta esimerkiksi integraatioprojekteihin TDD sopii edelleen hyvin. Vuosien varrella on myös opittu paljon siitä, mitä asioita testivetoisessa kehityksessä tulee käytännössä varoa tai huomioida.

TDD:n pohjalta on kehitetty myös erilaisia tekniikoita tuoda asiakas mukaan osaksi määrittely- ja testausprosessia. Näistä esimerkkinä BDD (Behavior-driven development) ja ATDD (Acceptance test-driven development). Tässä jutussa keskitytään kuitenkin itse TDD:hen, jossa testit tehdään puhtaasti kehittäjän näkökulmasta.

Testikirjaston paisuminen ennustaa ongelmia jatkokehitykselle

Toteutetun projektin jälkeen näyttää monesti hyvältä: meillä on toimiva tuotantokoodi ja sille kattava testisetti. Pienet muutokset ja korjaukset onnistuvat todennäköisesti helposti.

Ongelmia helposti tulee, kun testit kirjoittanut kehittäjä lähtee projektista. Ymmärtävätkö uudet ylläpitäjät mitä testit tarkalleen testaavat? Hajoavatko testit, kun toteutetaan uusia featureita? Voikin olla että testien omaksumiseen ja ylläpitoon menee paljon enemmän aikaa kuin itse koodin.

Vinkit TDD:n tehokäyttöön

  1. Testaa järjestelmän käyttäytymistä

    TDD:n tärkeimpänä ohjenuorana on testata järjestelmän käyttäytymistä eikä sisäisen toteutuksen yksityiskohtia. Jos tässä onnistutaan, testit hajoavat vain vaatimusten muuttuessa. Tässä kantavana ajatuksena on, että jos ohjelmisto toimii ulospäin oikealla tavalla, toimii myös sisäinen toteutus. Sisäisessä toteutuksessa voi toki olla ongelmia, mutta ne ovat luonteeltaan sellaisia, ettei niitä olisi saatu yksikkötesteillä kiinni alkuunkaan (esimerkiksi suorituskykyongelmat, muistivuodot).
  2. Mikä yksikkö?

    Yksikkötestauksessa yksikkönä ajatellaan helposti ohjelmointikielen luokkaa, mutta juuri tämä johtaa edellä mainittuihin ongelmiin. Ajattelemalla toteutettavaa moduulia tai vaatimusta yksikkönä (mikropalveluiden tapauksessa ehkä koko palvelua), päästään luonnollisesti siihen, että testataan laajempaa kokonaisuutta.
  3. Poista testejä

    Kehittäessä voi olla tarpeen testata nimenomaan toteutuksen yksityiskohtia, jotta saa kaiken kohdalleen. Tällaisia testejä saa toki kirjoittaa, mutta tämän jälkeen tulisi miettiä palveleeko testi sovelluksen ylläpitäjää vai hankaloittaako jatkokehitystä. Mikäli päätyy jälkimmäiseen, tulisi testi poistaa rohkeasti.
  4. Pidä yksinkertaisena

    Testejä kirjoittaessa on houkutus käyttää hienoja tekniikoita, joilla itse sovelluksen toimintaa voidaan matkia mahdollisimman pitkälle (mocking). Nämä ovat kuitenkin omiaan lisäämään testien kompleksisuutta. Vanha ja buginen testikirjasto on ylläpitäjän painajainen. Mieti siis mikä on yksinkertaisin tapa testata toteutettava vaatimus.
Yksinkertainen on yleensä myös nopea ajaa. Usein projektien kasvaessa testien ajossakin kestää kauemman, joka vähentää tuottavuutta ja heikentää kehittäjäkokemusta. Pidä siis testit nopeina!

Edellinen
Edellinen

Päivitimme palkkamallimme bonuksen osalta – testaa päivitetty palkkalaskurimme!

Seuraava
Seuraava

Tärkeintä (ja vaikeinta) on aloittaminen